2个版本

0.2.3 2023年9月9日
0.2.2 2023年9月9日

#6 in #方程

BSD-3-Clause

44KB
984

csparse21

使用稀疏矩阵方法求解大型复数线性方程组。

* 这是对 sparse21 的分支,用于复数稀疏矩阵。

** 可能最好让sparse21适用于泛型类型参数,但我没有时间做这个。

use num_complex::Complex64;
let mut m = csparse21::Matrix::from_entries(vec![
            (0, 0, Complex64{re: 1.0 , im: 1.0}),
            (0, 1, Complex64{re: 1.0 , im: 1.0}),
            (0, 2, Complex64{re: 1.0 , im: 1.0}),
            (1, 1, Complex64{re: 2.0 , im: 1.0}),
            (1, 2, Complex64{re: 5.0 , im: 1.0}),
            (2, 0, Complex64{re: 2.0 , im: 1.0}),
            (2, 1, Complex64{re: 5.0 , im: 1.0}),
            (2, 2, Complex64{re: -1.0, im: 1.0}),
        ]);

        let soln = m.solve(vec![
          Complex64{re: 6.0, im: 5.0},
          Complex64{re:-4.0, im: 27.0},
          Complex64{re: 5.0, im: -5.0},
        ]);

稀疏方法主要用于非零元素数量远小于矩阵总体大小的系统。这种情况在物理系统中很常见,包括电子电路仿真。除非另有说明,否则假设稀疏矩阵的所有元素都是零值。

用法

CSparse21公开了两种主要数据结构

  • Matrix 表示一个 Complex64 值的稀疏矩阵
  • System 表示形式为 Ax=b 的线性方程组,包括一个 Matrix (A) 和右手边 Vec (b)。

一旦创建了矩阵和系统,它们的主要公共方法是 solve,它返回一个(密集)Vec 解向量。

矩阵

CSparse21矩阵可以从少量数据源构建

Matrix::new 创建一个空矩阵,可以通过 add_elementadd_elements 方法添加元素。

let mut m = Matrix::new();

m.add_element(0, 0, Complex64{re:11.0, im: 12.0});
m.add_element(7, 0, Complex64{re:22.0, im: 23.0});
m.add_element(0, 7, Complex64{re:33.0, im: 0.0});
m.add_element(7, 7, Complex64{re:44.0, im: -3.0});
let mut m = Matrix::new();

m.add_elements(vec![
    (0, 0, Complex64{re: 1.0 , im: 1.0}),
    (0, 1, Complex64{re: 1.0 , im: 1.0}),
    (0, 2, Complex64{re: 1.0 , im: 1.0}),
    (2, 1, Complex64{re: 5.0 , im: 1.0}),
    (2, 2, Complex64{re: -1.0, im: 1.0}),
]);

add_element 的参数是行 (usize)、列 (usize) 和值 (Complex64)。通过 add_elements 添加元素(复数)需要一系列 (usize, usize, Complex64) 元组,表示行、列和值。

与常见的数学符号不同,csparse21 矩阵和向量的所有位置都是零索引。在“第一个”矩阵元素中添加非零值因此意味着调用 add_element(0, 0, val)

使用 MatrixMatrix::from_entries 方法从数据条目中创建矩阵

let mut m = Matrix::from_entries(vec![
    (0, 0, Complex64{re: 1.0 , im: 1.0}),
    (0, 1, Complex64{re: 1.0 , im: 1.0}),
    (0, 2, Complex64{re: 1.0 , im: 1.0}),
    (1, 1, Complex64{re: 2.0 , im: 1.0}),
    (1, 2, Complex64{re: 5.0 , im: 1.0}),
    (2, 0, Complex64{re: 2.0 , im: 1.0}),
    (2, 1, Complex64{re: 5.0 , im: 1.0}),
    (2, 2, Complex64{re: -1.0, im: 1.0}),
]);

Matrix::identity 方法返回一个大小为 (n x n) 的新单位矩阵

let mut m = Matrix::identity(3);

求解

CSparse21 矩阵是为求解方程组而构建的。Matrix 的主要公共方法是 solve(),它接受一个作为其唯一参数的 Vec 右侧向量,并返回一个相同大小的解 Vec

矩阵可变性

您可能已经注意到迄今为止的所有示例都将矩阵声明为 mut,可能是不必要的。这是故意的。Matrix::solve 方法(非 Rust 风格地)修改了矩阵(就地)。对于较大的矩阵,就地修改可以节省数个数量级的内存,以及创建和销毁元素的时间。虽然就地自我修改与 Rust 的精神不符,但它遵循了科学计算工具的长期传统,用于此类和类似任务。

因此:为了求解,矩阵必须声明为 mut

依赖关系

~320KB