#稀疏矩阵 #线性代数 #矩阵 #稀疏 #线性 #稠密矩阵 #矩阵运算

rsparse

使用直接方法解决稀疏线性方程组的Rust库

15个版本 (1个稳定版)

1.0.0 2024年4月12日
0.2.3 2023年4月5日
0.2.0 2023年2月4日
0.1.9 2023年1月31日

#86数学

Download history 13/week @ 2024-04-19 8/week @ 2024-04-26 1/week @ 2024-05-03 6/week @ 2024-05-10 7/week @ 2024-05-17 13/week @ 2024-05-24 7/week @ 2024-05-31 4/week @ 2024-06-07 3/week @ 2024-06-14 1/week @ 2024-06-21 6/week @ 2024-07-05 76/week @ 2024-07-26 9/week @ 2024-08-02

85 每月下载量
用于 2 crates

MIT 许可证

655KB
2K SLoC

rsparse

使用直接方法解决稀疏线性方程组的Rust库。

GitHub Workflow Status Crates.io Crates.io


数据结构

  • CSC矩阵 (Sprs)
  • 三元组矩阵 (Trpl)

特性

  • 将稠密矩阵转换为CSC稀疏矩阵 Sprs
  • 将稀疏矩阵转换为稠密矩阵 Vec<Vec<f64>>
  • 将三元组格式矩阵 Trpl 转换为CSC Sprs
  • 稀疏矩阵加法 [C=A+B]
  • 稀疏矩阵乘法 [C=A*B]
  • 转置稀疏矩阵
  • 求解稀疏线性方程组

求解器

  • lsolve:求解下三角系统。解 Lx=b,其中 x 和 b 都是稠密的。
  • ltsolve:解 L’x=b,其中 x 和 b 都是稠密的。
  • usolve:求解上三角系统。解 Ux=b,其中 x 和 b 都是稠密的。
  • utsolve:解 U’x=b,其中 x 和 b 都是稠密的。
  • cholsol:使用Cholesky分解的A\b求解器。其中 A 是定义的正 Sprs 矩阵,b 是稠密向量。
  • lusol:使用LU分解的A\b求解器。其中 A 是方 Sprs 矩阵,b 是稠密向量。
  • qrsol:使用QR分解的A\b求解器。其中A是一个矩形Sprs矩阵,b是一个稠密向量

示例

基本矩阵操作

use rsparse;

fn main() {
    // 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);
    }
}

输出

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

求解线性方程组

use rsparse;

fn main() {
    // 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();
    a_sparse.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);
}

输出

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

文档

文档可在docs.rs找到。

来源

无运行时依赖