Linear solver. More...
#include <linsol.hpp>
Solves the square linear system A*X = B or A'*X = B for X with a sparse direct solver plugin. A Linsol is created for a fixed sparsity pattern of A; the numerical values are given at every call. A matrix with another sparsity pattern is projected onto the fixed one (entries outside it are dropped). The solve is split in a symbolic factorization (sfact, pivot selection from the pattern), a numeric factorization (nfact) and the triangular solves (solve); solve(A, B) performs all three. A numerically singular matrix makes nfact (or solve) raise an error for most plugins; for a symbolic (MX) A, solve returns an expression node that is differentiable with respect to A and B.
Available plugins include "qr" and "ldl" (sparse direct QR and LDL, codegen support), "symbolicqr" (QR as a symbolic expression), "csparse", "csparsecholesky", "lapacklu", "lapackqr", "ma27", "mumps". neig and rank are only implemented by "ldl", det by "qr" and "csparse". The constructor raises an error for a non-square pattern only when the plugin checks it; otherwise the solve fails.
>>> A = DM([[3, 1], [1, 2]]); b = DM([4, 3])
>>> L = Linsol("L", "qr", A.sparsity())
>>> L.plugin_name(), L.sparsity()
('qr', Sparsity(2x2))
>>> L.solve(A, b), L.solve(DM([[1, 2], [0, 1]]), DM([1, 1]), True)
(DM([1, 1]), DM([1, -1]))
>>> L.solve(A, DM([[4, 1], [3, 0]]))
DM(
[[1, 0.4],
[1, -0.2]])
>>> L.det(A)
5.0
>>> try:
... L.solve(DM([[1, 1], [1, 1]]), b)
... except RuntimeError as e:
... print("'nfact' failed" in str(e))
True
>>> Am = MX.sym("A", A.sparsity()); bm = MX.sym("b", 2)
>>> f = Function("f", [Am, bm], [L.solve(Am, bm), L.det(Am)])
>>> f(A, b)
(DM([1, 1]), DM(5))
>> A = DM([3 1; 1 2]); b = DM([4; 3]);
>> L = Linsol('L', 'qr', A.sparsity());
>> L.plugin_name(), L.sparsity()
qr
2x2
>> L.solve(A, b), L.solve(DM([1 2; 0 1]), DM([1; 1]), true)
[1, 1]
[1, -1]
>> L.solve(A, DM([4 1; 3 0]))
[[1, 0.4],
[1, -0.2]]
>> L.det(A)
5
>> try, L.solve(DM([1 1; 1 1]), b); catch e, msg = e.message; end
>> contains(msg, '''nfact'' failed')
1
>> Am = MX.sym('A', A.sparsity()); bm = MX.sym('b', 2);
>> f = Function('f', {Am, bm}, {L.solve(Am, bm), L.det(Am)});
>> [xs, d] = f(A, b); disp(xs), disp(d)
[1, 1]
5
julia> A = ca.DM([3 1; 1 2]); b = ca.DM([4, 3]);
julia> L = ca.Linsol("L", "qr", ca.sparsity(A));
julia> ca.plugin_name(L), ca.sparsity(L)
("qr", 2x2)
julia> ca.solve(L, A, b)
DM([1, 1])
julia> ca.solve(L, ca.DM([1 2; 0 1]), ca.DM([1, 1]), true)
DM([1, -1])
julia> ca.solve(L, A, ca.DM([4 1; 3 0]))
DM(
[[1, 0.4],
[1, -0.2]])
julia> L.det(A)
5.0
julia> try
ca.solve(L, ca.DM([1 1; 1 1]), b, false)
catch e
println(occursin("'nfact' failed", sprint(showerror, e)))
end
true
julia> Am = ca.MX.sym("A", ca.sparsity(A)); bm = ca.MX.sym("b", 2);
julia> f = ca.Function("f", [Am, bm], [ca.solve(L, Am, bm), L.det(Am)]);
julia> f(A, b)
([1, 1], 5)
- csparse
- ma27
- lapacklu
- lapackqr
- mumps
- ldl
- qr
- tridiag
Note: some of the plugins in this list might not be available on your system. Also, there might be extra plugins available to you that are not listed here. You can obtain their documentation with Linsol.doc("myextraplugin")
Linsol with CSparseCholesky Interface
Extra doc: https://github.com/casadi/casadi/wiki/L_21u
Linsol with CSparse Interface
Extra doc: https://github.com/casadi/casadi/wiki/L_21t
Interface to the sparse direct linear solver MA27 Works for symmetric indefinite systems Partly adopted from qpOASES 3.2
Extra doc: https://github.com/casadi/casadi/wiki/L_229
This class solves the linear system A.x=b by making an LU factorization of A:
A = L.U, with L lower and U upper triangular
Extra doc: https://github.com/casadi/casadi/wiki/L_22h
| Id | Type | Description |
|---|---|---|
| allow_equilibration_failure | OT_BOOL | Non-fatal error when equilibration fails |
| equilibration | OT_BOOL | Equilibrate the matrix |
This class solves the linear system A.x=b by making an QR factorization of A:
A = Q.R, with Q orthogonal and R upper triangular
Extra doc: https://github.com/casadi/casadi/wiki/L_22g
| Id | Type | Description |
|---|---|---|
| max_nrhs | OT_INT | Maximum number of right-hand-sides that get processed in a single pass [default:10]. |
Interface to the sparse direct linear solver MUMPS Works for symmetric indefinite systems
Extra doc: https://github.com/casadi/casadi/wiki/L_22t
| Id | Type | Description |
|---|---|---|
| posdef | OT_BOOL | Positive definite |
| symmetric | OT_BOOL | Symmetric matrix |
Linear solver using sparse direct LDL factorization
Extra doc: https://github.com/casadi/casadi/wiki/L_233
| Id | Type | Description |
|---|---|---|
| incomplete | OT_BOOL | Incomplete factorization, without any fill-in |
| preordering | OT_BOOL | Approximate minimal degree (AMD) preordering |
Linear solver using sparse direct QR factorization
Extra doc: https://github.com/casadi/casadi/wiki/L_22z
| Id | Type | Description |
|---|---|---|
| cache | OT_DOUBLE | Amount of factorisations to remember (thread-local) [0] |
| eps | OT_DOUBLE | Minimum R entry before singularity is declared [1e-12] |
Linear solver for tridiagonal matrices
Extra doc: https://github.com/casadi/casadi/wiki/L_22v
Linear solver for sparse least-squares problems Inspired from https://github.com/scipy/scipy/blob/v0.14.0/scipy/sparse/linalg/isolve/lsqr.py#L96
Extra doc: https://github.com/casadi/casadi/wiki/L_230
Linsol based on QR factorization with sparsity pattern based reordering without partial pivoting
Extra doc: https://github.com/casadi/casadi/wiki/L_231
| Id | Type | Description |
|---|---|---|
| fopts | OT_DICT | Options to be passed to generated function objects |
Extra doc: https://github.com/casadi/casadi/wiki/L_1kh
Definition at line 142 of file linsol.hpp.

Public Types | |
| using | internal_base_type = SharedObjectInternal |
| using | base_type = SharedObject |
Public Member Functions | |
| Linsol () | |
| Default constructor (a null object) More... | |
| Linsol (const std::string &name, const std::string &solver, const Sparsity &sp, const Dict &opts=Dict()) | |
| Create a linear solver. More... | |
| LinsolInternal * | operator-> () |
| Access functions of the node. More... | |
| const LinsolInternal * | operator-> () const |
| std::string | plugin_name () const |
| Query plugin name. More... | |
| const Sparsity & | sparsity () const |
| Get the sparsity pattern of A fixed at construction. More... | |
| void | sfact (const DM &A) const |
| Symbolic factorization of the linear system, e.g. selecting pivots. More... | |
| void | nfact (const DM &A) const |
| Numeric factorization of the linear system. More... | |
| casadi_int | neig (const DM &A) const |
| Number of negative eigenvalues. More... | |
| casadi_int | rank (const DM &A) const |
| Matrix rank. More... | |
| double | det (const DM &A) const |
| Matrix determinant. More... | |
| MX | det (const MX &A) const |
| Matrix determinant as an MX graph node. More... | |
| Dict | stats (int mem=1) const |
| Get all statistics obtained at the end of the last evaluate call. More... | |
| std::string | class_name () const |
| Get class name. More... | |
| void | disp (std::ostream &stream, bool more=false) const |
| Print a description of the object. More... | |
| std::string | get_str (bool more=false) const |
| Get string representation. More... | |
| std::string | debug_repr () const |
| bool | is_null () const |
| Is a null pointer? More... | |
| casadi_int | __hash__ () const |
| Returns a number that is unique for a given Node. More... | |
| DM | solve (const DM &A, const DM &B, bool tr=false) const |
Solve the linear system A*X = B (or A'*X = B with tr true) More... | |
| MX | solve (const MX &A, const MX &B, bool tr=false) const |
Solve the linear system A*X = B (or A'*X = B with tr true) More... | |
Static Public Member Functions | |
| static std::string | type_name () |
| Get type name. More... | |
| static bool | has_plugin (const std::string &name) |
| Check if a plugin is available. More... | |
| static void | load_plugin (const std::string &name) |
| Explicitly load a plugin dynamically. More... | |
| static std::string | doc (const std::string &name) |
| Get solver specific documentation. More... | |
|
inherited |
Definition at line 103 of file shared_object.hpp.
|
inherited |
Definition at line 102 of file shared_object.hpp.
| casadi::Linsol::Linsol | ( | ) |
|
explicit |
| name | Name of the solver object |
| solver | Plugin name, e.g. "qr", "ldl", "csparse"; see has_linsol |
| sp | Sparsity pattern of A (square); the numerical values are given at every call |
| opts | Options; an unknown option raises an error |
>>> L = Linsol("L", "ldl", Sparsity.dense(2, 2))
>>> L
Linsol(Linear solver LinsolLdl)
>>> try:
... Linsol("L", "qr", Sparsity.dense(2, 2), {"no_such_option": 1})
... except RuntimeError as e:
... print("Unknown option" in str(e))
True
>> L = Linsol('L', 'ldl', Sparsity.dense(2, 2)); disp(L)
Linear solver LinsolLdl
>> opts = struct('no_such_option', 1);
>> try, Linsol('L', 'qr', Sparsity.dense(2, 2), opts); catch e, msg = e.message; end
>> contains(msg, 'Unknown option')
1
julia> L = ca.Linsol("L", "ldl", ca.Sparsity.dense(2, 2));
julia> ca.str(L)
"Linear solver LinsolLdl"
julia> try
ca.Linsol("L", "qr", ca.Sparsity.dense(2, 2), Dict("no_such_option" => 1))
catch e
println(occursin("Unknown option", sprint(showerror, e)))
end
true
Extra doc: https://github.com/casadi/casadi/wiki/L_2pe
|
inherited |
If the Object does not point to any node, "0" is returned.
Extra doc: https://github.com/casadi/casadi/wiki/L_av
Definition at line 123 of file generic_shared_impl.hpp.
|
inherited |
Extra doc: https://github.com/casadi/casadi/wiki/L_au
|
inherited |
Definition at line 112 of file generic_shared_impl.hpp.
| double casadi::Linsol::det | ( | const DM & | A | ) | const |
Not available for all solvers ("qr" and "csparse"); factorizes A first.
>>> A = DM([[3, 1], [1, 2]])
>>> Linsol("L", "qr", A.sparsity()).det(A)
5.0
>>> try:
... Linsol("L", "ldl", A.sparsity()).det(A)
... except RuntimeError as e:
... print("'det' not defined" in str(e))
True
>> A = DM([3 1; 1 2]); L = Linsol('L', 'qr', A.sparsity()); disp(L.det(A))
5
>> L = Linsol('L', 'ldl', A.sparsity());
>> try, L.det(A); catch e, disp(contains(e.message, '''det'' not defined')); end
1
julia> A = ca.DM([3 1; 1 2]);
julia> ca.Linsol("L", "qr", ca.sparsity(A)).det(A)
5.0
julia> try
ca.Linsol("L", "ldl", ca.sparsity(A)).det(A)
catch e
println(occursin("'det' not defined", sprint(showerror, e)))
end
true
Extra doc: https://github.com/casadi/casadi/wiki/L_2hw
|
inherited |
|
static |
Same as doc_linsol.
>>> "LDL" in Linsol.doc("ldl")
True
>> contains(Linsol.doc('ldl'), 'LDL')
1
julia> occursin("LDL", ca.Linsol.doc("ldl"))
true
Extra doc: https://github.com/casadi/casadi/wiki/L_2ph
|
inlineinherited |
Definition at line 91 of file shared_object.hpp.
|
static |
Same as has_linsol.
>>> Linsol.has_plugin("qr"), Linsol.has_plugin("no_such_plugin")
(True, False)
>> Linsol.has_plugin('qr'), Linsol.has_plugin('no_such_plugin')
1
0
julia> ca.Linsol.has_plugin("qr"), ca.Linsol.has_plugin("no_such_plugin")
(true, false)
Extra doc: https://github.com/casadi/casadi/wiki/L_2pf
|
inherited |
Definition at line 116 of file generic_shared_impl.hpp.
|
static |
Same as load_linsol; raises an error when the plugin cannot be found.
>>> try:
... Linsol.load_plugin("no_such_plugin")
... except RuntimeError as e:
... print("no_such_plugin" in str(e))
True
>> try, Linsol.load_plugin('no_such_plugin'); catch e, msg = e.message; end
>> contains(msg, 'no_such_plugin')
1
julia> try
ca.Linsol.load_plugin("no_such_plugin")
catch e
println(occursin("no_such_plugin", sprint(showerror, e)))
end
true
Extra doc: https://github.com/casadi/casadi/wiki/L_2pg
| casadi_int casadi::Linsol::neig | ( | const DM & | A | ) | const |
Not available for all solvers (only "ldl"); uses the factorization of the most recent nfact call, which must have been made with the same matrix.
>>> A = DM([[-2, 0], [0, 1]])
>>> L = Linsol("L", "ldl", A.sparsity())
>>> L.nfact(A)
>>> L.neig(A)
1
>>> try:
... Linsol("L", "qr", A.sparsity()).neig(A)
... except RuntimeError as e:
... print("'neig' not defined" in str(e))
True
>> A = DM([-2 0; 0 1]); L = Linsol('L', 'ldl', A.sparsity());
>> L.nfact(A); disp(L.neig(A))
1
>> L = Linsol('L', 'qr', A.sparsity());
>> try, L.neig(A); catch e, disp(contains(e.message, '''neig'' not defined')); end
1
julia> A = ca.DM([-2 0; 0 1]);
julia> L = ca.Linsol("L", "ldl", ca.sparsity(A));
julia> ca.nfact(L, A)
julia> ca.neig(L, A)
1
julia> try
ca.neig(ca.Linsol("L", "qr", ca.sparsity(A)), A)
catch e
println(occursin("'neig' not defined", sprint(showerror, e)))
end
true
Extra doc: https://github.com/casadi/casadi/wiki/L_1kk
| void casadi::Linsol::nfact | ( | const DM & | A | ) | const |
Factorizes the values of A (after sfact if not done yet), so that neig, rank and the low-level solve can use the factorization. Raises an error when the factorization fails with option "regularity_check" set; otherwise a failure is only reported by solve.
>>> A = DM([[3, 1], [1, 2]])
>>> L = Linsol("L", "ldl", A.sparsity())
>>> L.nfact(A)
>>> L.neig(A), L.rank(A)
(0, 2)
>>> L.nfact(DM([[-1, 0], [0, 1]]))
>>> L.neig(DM([[-1, 0], [0, 1]]))
1
>> A = DM([3 1; 1 2]); L = Linsol('L', 'ldl', A.sparsity());
>> L.nfact(A); fprintf('%d %d\n', L.neig(A), L.rank(A))
0 2
>> B = DM([-1 0; 0 1]); L.nfact(B); disp(L.neig(B))
1
julia> A = ca.DM([3 1; 1 2]);
julia> L = ca.Linsol("L", "ldl", ca.sparsity(A));
julia> ca.nfact(L, A)
julia> ca.neig(L, A), ca.rank(L, A)
(0, 2)
julia> ca.nfact(L, ca.DM([-1 0; 0 1]))
julia> ca.neig(L, ca.DM([-1 0; 0 1]))
1
Extra doc: https://github.com/casadi/casadi/wiki/L_2pj
| LinsolInternal* casadi::Linsol::operator-> | ( | ) |
| const LinsolInternal* casadi::Linsol::operator-> | ( | ) | const |
| std::string casadi::Linsol::plugin_name | ( | ) | const |
| casadi_int casadi::Linsol::rank | ( | const DM & | A | ) | const |
Not available for all solvers (only "ldl"); uses the factorization of the most recent nfact call, which must have been made with the same matrix.
A rank-deficient matrix also triggers a warning in nfact.
>>> A = DM([[2, 1], [1, 3]])
>>> L = Linsol("L", "ldl", A.sparsity())
>>> L.nfact(A)
>>> L.rank(A)
2
>> A = DM([2 1; 1 3]); L = Linsol('L', 'ldl', A.sparsity());
>> L.nfact(A); disp(L.rank(A))
2
julia> A = ca.DM([2 1; 1 3]);
julia> L = ca.Linsol("L", "ldl", ca.sparsity(A));
julia> ca.nfact(L, A)
julia> ca.rank(L, A)
2
Extra doc: https://github.com/casadi/casadi/wiki/L_1kl
| void casadi::Linsol::sfact | ( | const DM & | A | ) | const |
Only uses the sparsity pattern of A. Called automatically by nfact and solve when needed; raises an error when the plugin fails.
Extra doc: https://github.com/casadi/casadi/wiki/L_2pi
For DM arguments, factorizes A and solves for all columns of B at once; the result is dense. For MX arguments, returns an expression node that is differentiable. The row count of A and B must match.
| A | Square matrix with the sparsity pattern given at construction (projected onto it otherwise) |
| B | Right-hand side, one column per system to solve |
| tr | Solve with the transpose of A instead |
B
>>> L = Linsol("L", "qr", Sparsity.dense(2, 2))
>>> L.solve(DM([[3, 1], [1, 2]]), DM([4, 3]))
DM([1, 1])
>>> try:
... L.solve(DM([[3, 1], [1, 2]]), DM([1, 2, 3]))
... except RuntimeError as e:
... print("matching row count" in str(e))
True
>> L = Linsol('L', 'qr', Sparsity.dense(2, 2));
>> L.solve(DM([3 1; 1 2]), DM([4; 3]))
[1, 1]
>> try, L.solve(DM([3 1; 1 2]), DM([1; 2; 3])); catch e, msg = e.message; end
>> contains(msg, 'matching row count')
1
julia> L = ca.Linsol("L", "qr", ca.Sparsity.dense(2, 2));
julia> ca.solve(L, ca.DM([3 1; 1 2]), ca.DM([4, 3]))
DM([1, 1])
julia> try
ca.solve(L, ca.DM([3 1; 1 2]), ca.DM([1, 2, 3]))
catch e
println(occursin("matching row count", sprint(showerror, e)))
end
true
Extra doc: https://github.com/casadi/casadi/wiki/L_2pk
For DM arguments, factorizes A and solves for all columns of B at once; the result is dense. For MX arguments, returns an expression node that is differentiable. The row count of A and B must match.
| A | Square matrix with the sparsity pattern given at construction (projected onto it otherwise) |
| B | Right-hand side, one column per system to solve |
| tr | Solve with the transpose of A instead |
B
>>> L = Linsol("L", "qr", Sparsity.dense(2, 2))
>>> L.solve(DM([[3, 1], [1, 2]]), DM([4, 3]))
DM([1, 1])
>>> try:
... L.solve(DM([[3, 1], [1, 2]]), DM([1, 2, 3]))
... except RuntimeError as e:
... print("matching row count" in str(e))
True
>> L = Linsol('L', 'qr', Sparsity.dense(2, 2));
>> L.solve(DM([3 1; 1 2]), DM([4; 3]))
[1, 1]
>> try, L.solve(DM([3 1; 1 2]), DM([1; 2; 3])); catch e, msg = e.message; end
>> contains(msg, 'matching row count')
1
julia> L = ca.Linsol("L", "qr", ca.Sparsity.dense(2, 2));
julia> ca.solve(L, ca.DM([3 1; 1 2]), ca.DM([4, 3]))
DM([1, 1])
julia> try
ca.solve(L, ca.DM([3 1; 1 2]), ca.DM([1, 2, 3]))
catch e
println(occursin("matching row count", sprint(showerror, e)))
end
true
Extra doc: https://github.com/casadi/casadi/wiki/L_2pk
| const Sparsity& casadi::Linsol::sparsity | ( | ) | const |
| Dict casadi::Linsol::stats | ( | int | mem = 1 | ) | const |
Plugin-specific; empty for most plugins. Raises an error before the first solve. With the option "record_time" set, it holds call counts and timings (n_call_*, t_proc_*, t_wall_*) of sfact, nfact and solve.
>>> L = Linsol("L", "qr", Sparsity.dense(1, 1))
>>> try:
... L.stats()
... except RuntimeError as e:
... print("did not solve a problem yet" in str(e))
True
>>> L.solve(DM(2), DM(4)), L.stats()
(DM(2), {})
>>> L = Linsol("L", "qr", Sparsity.dense(1, 1), {"record_time": True})
>>> L.solve(DM(2), DM(4)); L.stats()["n_call_solve"]
DM(2)
1
>> L = Linsol('L', 'qr', Sparsity.dense(1, 1));
>> try, L.stats(); catch e, disp(contains(e.message, 'did not solve a problem yet')); end
1
>> L.solve(DM(2), DM(4)), isempty(fieldnames(L.stats()))
2
1
julia> L = ca.Linsol("L", "qr", ca.Sparsity.dense(1, 1));
julia> try
ca.stats(L)
catch e
println(occursin("did not solve a problem yet", sprint(showerror, e)))
end
true
julia> ca.solve(L, ca.DM(2), ca.DM(4)), ca.stats(L)
(2, Dict{String, Any}())
julia> L = ca.Linsol("L", "qr", ca.Sparsity.dense(1, 1), Dict("record_time" => true));
julia> ca.solve(L, ca.DM(2), ca.DM(4)); ca.stats(L)["n_call_solve"]
1
Extra doc: https://github.com/casadi/casadi/wiki/L_2pl
|
inlinestatic |
Extra doc: https://github.com/casadi/casadi/wiki/L_1ki
Definition at line 149 of file linsol.hpp.