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);