当前位置 : 主页 > 编程语言 > java >

【每周一库】- sprs - 用Rust实现的稀疏矩阵库

来源:互联网 收集:自由互联 发布时间:2022-06-22
sprs是用纯Rust实现的部分稀疏矩阵数据结构和线性代数算法 特性 结构 矩阵 三元组矩阵 稀疏向量 运算 稀疏矩阵 / 稀疏向量积 稀疏矩阵 / 稀疏矩阵积 稀疏矩阵 / 稀疏矩阵加法,减法 稀

sprs是用纯Rust实现的部分稀疏矩阵数据结构和线性代数算法

特性

结构

  • 矩阵
  • 三元组矩阵
  • 稀疏向量

运算

  • 稀疏矩阵 / 稀疏向量积
  • 稀疏矩阵 / 稀疏矩阵积
  • 稀疏矩阵 / 稀疏矩阵加法,减法
  • 稀疏向量 / 稀疏向量加法,减法,点积
  • 稀疏 / 稠密矩阵运算

算法

  • 压缩稀疏矩阵的外部迭代器
  • 稀疏向量迭代
  • 稀疏向量联合非零迭代
  • 简单的稀疏矩阵Cholesky分解 (需要选择接受 LGPL 许可)
  • 等式右侧为稠密矩阵或向量情况下的稀疏矩阵解三角方程组

示例

矩阵创建

use sprs::TriMat;

let mut a = TriMat::new((4, 4));
a.add_triplet(0, 0, 3.0_f64);
a.add_triplet(1, 2, 2.0);
a.add_triplet(3, 0, -2.0);

// 这个矩阵类型不允许进行计算,需要
// 转换为兼容的稀疏矩阵类型,例如
let b = a.to_csr();

用更高效直接的稀疏矩阵生成器来构建矩阵

use sprs::{CsMat, CsMatOwned, CsVec};
let eye : CsMatOwned<f64> = CsMat::eye(3);
let a = CsMat::new_csc((3, 3),
vec![0, 2, 4, 5],
vec![0, 1, 0, 2, 2],
vec![1., 2., 3., 4., 5.]);

矩阵向量乘法

use sprs::{CsMat, CsVec};
let eye = CsMat::eye(5);
let x = CsVec::new(5, vec![0, 2, 4], vec![1., 2., 3.]);
let y = &eye * &x;
assert_eq!(x, y);

矩阵乘法,加法

use sprs::{CsMat, CsVec};
let eye = CsMat::eye(3);
let a = CsMat::new_csc((3, 3),
vec![0, 2, 4, 5],
vec![0, 1, 0, 2, 2],
vec![1., 2., 3., 4., 5.]);
let b = &eye * &a;
assert_eq!(a, b.to_csr());

其他示例

pub mod array_backend;
pub mod errors;
pub mod indexing;
pub mod io;
pub mod num_kinds;
mod sparse;
pub mod stack;

pub type Ix1 = ndarray::Ix1;
pub type Ix2 = ndarray::Ix2;

pub use crate::indexing::SpIndex;

pub use crate::sparse::{
csmat::CsIter, csmat::OuterIterator, csmat::OuterIteratorMut,
csmat::OuterIteratorPerm, kronecker::kronecker_product, CsMat, CsMatBase,
CsMatI, CsMatVecView, CsMatView, CsMatViewI, CsMatViewMut, CsMatViewMutI,
CsStructure, CsStructureI, CsStructureView, CsStructureViewI, CsVec,
CsVecBase, CsVecI, CsVecView, CsVecViewI, CsVecViewMut, CsVecViewMutI,
SparseMat, TriMat, TriMatBase, TriMatI, TriMatIter, TriMatView,
TriMatViewI, TriMatViewMut, TriMatViewMutI,
};

pub use crate::sparse::symmetric::is_symmetric;

pub use crate::sparse::permutation::{
perm_is_valid, transform_mat_papt, PermOwned, PermOwnedI, PermView,
PermViewI, Permutation,
};

pub use crate::sparse::CompressedStorage::{self, CSC, CSR};

pub use crate::sparse::binop;
pub use crate::sparse::linalg;
pub use crate::sparse::prod;
pub use crate::sparse::smmp;
pub use crate::sparse::special_mats;
pub use crate::sparse::visu;

pub mod vec {
pub use crate::sparse::{CsVec, CsVecBase, CsVecView, CsVecViewMut};

pub use crate::sparse::vec::{
IntoSparseVecIter, NnzEither, NnzIndex, NnzOrZip, SparseIterTools,
VecDim, VectorIterator, VectorIteratorMut,
};
}

pub use crate::sparse::construct::{bmat, hstack, vstack};

pub use crate::sparse::to_dense::assign_to_dense;

/// 矩阵的形状,第一个元素表明这是一个双元素元组
/// 行数, 第二个元素表明列数
pub type Shape = (usize, usize); // FIXME: 或许此处可以用Ix2?

pub type SpRes<T> = Result<T, errors::SprsError>;

/// 用枚举作为配置项来对算法进行对称性检查
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub enum SymmetryCheck {
CheckSymmetry,
DontCheckSymmetry,
}
pub use SymmetryCheck::*;

/// 用枚举作为配置项来对算法进行排列检查
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub enum PermutationCheck {
CheckPerm,
DontCheckPerm,
}
pub use PermutationCheck::*;

/// sprs支持的不同种类的填充归约算法
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
#[non_exhaustive]
pub enum FillInReduction {
NoReduction,
ReverseCuthillMcKee,
CAMDSuiteSparse,
}

#[cfg(feature = "approx")]
/// 用于比较向量和矩阵的特征使用了近似特征
///
/// 使用不同的存储来比较稀疏矩阵可能会很慢
/// 为了高效,建议使用同样的存储顺序
///
/// 这些特征需要 `approx` 特性在激活状态
pub mod approx {
pub use approx::{AbsDiffEq, RelativeEq, UlpsEq};
}

#[cfg(test)]
mod test_data;

#[cfg(test)]
mod test {
use super::CsMat;

#[test]
fn iter_rbr() {
let mat = CsMat::new(
(3, 3),
vec![0, 2, 3, 3],
vec![1, 2, 0],
vec![0.1, 0.2, 0.3],
);
let view = mat.view();
let mut iter = view.iter();
assert_eq!(iter.next(), Some((&0.1, (0, 1))));
assert_eq!(iter.next(), Some((&0.2, (0, 2))));
assert_eq!(iter.next(), Some((&0.3, (1, 0))));
assert_eq!(iter.next(), None);
}
}


网友评论