Crate rsparse

source ·
Expand description

rsparse

A Rust library for solving sparse linear systems using direct methods.

GitHub Workflow Status Crates.io Crates.io


§Data structures

  • CSC matrix (Sprs)
  • Triplet matrix (Trpl)

§Features

  • Convert from dense [Vec<f64>] or Vec<Vec<64>> matrix to CSC sparse matrix Sprs
  • Convert from sparse to dense Vec<Vec<f64>>
  • Convert from a triplet format matrix Trpl to CSC Sprs
  • Sparse matrix addition [C=A+B]
  • Sparse matrix multiplication [C=A*B]
  • Transpose sparse matrices
  • Solve sparse linear systems

§Solvers

  • lsolve: Solve a lower triangular system. Solves Lx=b where x and b are dense.
  • ltsolve: Solve L’x=b where x and b are dense.
  • usolve: Solve an upper triangular system. Solves Ux=b where x and b are dense
  • utsolve: Solve U’x=b where x and b are dense
  • cholsol: A\b solver using Cholesky factorization. Where A is a defined positive Sprs matrix and b is a dense vector
  • lusol: A\b solver using LU factorization. Where A is a square Sprs matrix and b is a dense vector
  • qrsol: A\b solver using QR factorization. Where A is a rectangular Sprs matrix and b is a dense vector

§Examples

§Basic matrix operations

// Create a CSC sparse matrix A
let a = rsparse::data::Sprs{
    // Maximum number of entries
    nzmax: 5,
    // number of rows
    m: 3,
    // number of columns
    n: 3,
    // Values
    x: vec![1., 9., 9., 2., 9.],
    // Indices
    i: vec![1, 2, 2, 0, 2],
    // Pointers
    p: vec![0, 2, 3, 5]
};

// Import the same matrix from a dense structure
let mut a2 = rsparse::data::Sprs::new_from_vec(
    &[
        vec![0., 0., 2.],
        vec![1., 0., 0.],
        vec![9., 9., 9.]
    ]
);

// Check if they are the same
assert_eq!(a.nzmax, a2.nzmax);
assert_eq!(a.m,a2.m);
assert_eq!(a.n,a2.n);
assert_eq!(a.x,a2.x);
assert_eq!(a.i,a2.i);
assert_eq!(a.p,a2.p);

// Transform A to dense and print result
println!("\nA");
print_matrix(&a.to_dense());

// Transpose A
let at = rsparse::transpose(&a);
// Transform to dense and print result
println!("\nAt");
print_matrix(&at.to_dense());

// B = A + A'
let b = &a + &at;
// Transform to dense and print result
println!("\nB");
print_matrix(&b.to_dense());

// C = A * B
let c = &a * &b;
// Transform to dense and print result
println!("\nC");
print_matrix(&c.to_dense());

fn print_matrix(vec: &[Vec<f64>]) {
    for row in vec {
        println!("{:?}", row);
    }
}

Output:

A
0   0   2
1   0   0
9   9   9

At
0   1   9
0   0   9
2   0   9

B
0   1   11
1   0   9
11  9   18

C
22  18  36
0   1   11
108 90  342

§Solve a linear system

// Arbitrary A matrix (dense)
let a = [
    vec![8.2541e-01, 9.5622e-01, 4.6698e-01, 8.4410e-03, 6.3193e-01, 7.5741e-01, 5.3584e-01, 3.9448e-01],
    vec![7.4808e-01, 2.0403e-01, 9.4649e-01, 2.5086e-01, 2.6931e-01, 5.5866e-01, 3.1827e-01, 2.9819e-02],
    vec![6.3980e-01, 9.1615e-01, 8.5515e-01, 9.5323e-01, 7.8323e-01, 8.6003e-01, 7.5761e-01, 8.9255e-01],
    vec![1.8726e-01, 8.9339e-01, 9.9796e-01, 5.0506e-01, 6.1439e-01, 4.3617e-01, 7.3369e-01, 1.5565e-01],
    vec![2.8015e-02, 6.3404e-01, 8.4771e-01, 8.6419e-01, 2.7555e-01, 3.5909e-01, 7.6644e-01, 8.9905e-02],
    vec![9.1817e-01, 8.6629e-01, 5.9917e-01, 1.9346e-01, 2.1960e-01, 1.8676e-01, 8.7020e-01, 2.7891e-01],
    vec![3.1999e-01, 5.9988e-01, 8.7402e-01, 5.5710e-01, 2.4707e-01, 7.5652e-01, 8.3682e-01, 6.3145e-01],
    vec![9.3807e-01, 7.5985e-02, 7.8758e-01, 3.6881e-01, 4.4553e-01, 5.5005e-02, 3.3908e-01, 3.4573e-01],
];

// Convert A to sparse
let mut a_sparse = rsparse::data::Sprs::new_from_vec(&a);

// Generate arbitrary b vector
let mut b = [
    0.4377,
    0.7328,
    0.1227,
    0.1817,
    0.2634,
    0.6876,
    0.8711,
    0.4201
];

// Known solution:
/*
    0.264678,
    -1.228118,
    -0.035452,
    -0.676711,
    -0.066194,
    0.761495,
    1.852384,
    -0.282992
*/

// A*x=b -> solve for x -> place x in b
rsparse::lusol(&a_sparse, &mut b, 1, 1e-6);
println!("\nX");
println!("{:?}", &b);

Output:

X
[0.2646806068156303, -1.2280777288645675, -0.035491404094236435, -0.6766064748053932, -0.06619898266432682, 0.7615102544801993, 1.8522970972589123, -0.2830302118359591]

§Sources

MIT License Copyright (c) 2023 Ricard Lado

Modules§

  • Data structures for rsparse

Functions§

  • C = alpha * A + beta * B
  • L = chol (A, [Pinv parent cp]), Pinv is optional
  • A\b solver using Cholesky factorization.
  • Generalized A times X Plus Y
  • Solves a lower triangular system. Solves Lx=b. Where x and b are dense.
  • Solves L’x=b. Where x and b are dense.
  • (L,U,Pinv) = lu(A, (Q lnz unz)). lnz and unz can be guess
  • A\b solver using LU factorization.
  • C = A * B
  • Computes the 1-norm of a sparse matrix
  • Sparse QR factorization (V,beta,p,R) = qr (A)
  • A\b solver using QR factorization.
  • Ordering and symbolic analysis for a Cholesky factorization
  • Scalar plus sparse matrix. C = alpha + A
  • Scalar times sparse matrix. C = alpha * A
  • Print a sparse matrix
  • Symbolic analysis for QR or LU
  • C = A’
  • Solves an upper triangular system. Solves U*x=b.
  • Solves U’x=b where x and b are dense.