sprs是用纯Rust实现的部分稀疏矩阵数据结构和线性代数算法
矩阵创建
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);
}
}