solving linear systems
just like for dense matrices,
faer provides several sparse matrix decompositions for solving linear systems ,
where
is sparse and
and
are dense.
these typically come in two variants,
supernodal and simplicial.
the variant is selected automatically depending on the sparsity structure of the matrix.
and although the lower level api provides a way to tune the selection options, it is currently not fully documented.
is triangular
{SparseColMat, SparseRowMat}::sp_solve_lower_triangular_in_place
can be used, or similar methods for when the diagonal is unit and/or the matrix is upper triangular.
is real-symmetric/hermitian and positive definite
if is hermitian and positive definite, users can use the cholesky
decomposition.
use faer::prelude::*;
use faer::sparse::*;
use faer::Side;
let A = SparseColMat::<usize, f64>::try_new_from_triplets(
2,
2,
&[
Triplet::new(0, 0, 10.0),
Triplet::new(1, 0, 2.0),
Triplet::new(0, 1, 2.0),
Triplet::new(1, 1, 10.0),
],
).unwrap();
let b = col![15.0, -3.0];
let llt = A.sp_cholesky(Side::Lower).unwrap();
let x = llt.solve(&b);
is square
for a square matrix , we can use the
decomposition with partial pivoting.
use faer::prelude::*;
use faer::sparse::*;
let A = SparseColMat::<usize, f64>::try_new_from_triplets(
2,
2,
&[
Triplet::new(0, 0, 10.0),
Triplet::new(1, 0, 2.0),
Triplet::new(0, 1, 4.0),
Triplet::new(1, 1, 20.0),
],
).unwrap();
let b = col![15.0, -3.0];
let lu = A.sp_lu().unwrap();
let x = lu.solve(&b);
is a tall matrix
when the linear system is over-determined, an exact solution may not necessarily exist, in which case we can get a best-effort result by computing the least squares solution. that is, the solution that minimizes .
this can be done using the qr decomposition.
use faer::prelude::*;
use faer::sparse::*;
let A = SparseColMat::<usize, f64>::try_new_from_triplets(
3,
2,
&[
Triplet::new(0, 0, 10.0),
Triplet::new(1, 0, 2.0),
Triplet::new(2, 0, 3.0),
Triplet::new(0, 1, 4.0),
Triplet::new(1, 1, 20.0),
Triplet::new(2, 1, -45.0),
],
).unwrap();
let b = col![15.0, -3.0, 33.0];
let qr = A.sp_qr().unwrap();
let x = qr.solve_lstsq(&b);