sprs/
lib.rs

1/*!
2
3sprs is a sparse linear algebra library for Rust.
4
5It features a sparse matrix type, [**`CsMat`**](struct.CsMatBase.html), and a sparse vector type,
6[**`CsVec`**](struct.CsVecBase.html), both based on the
7[compressed storage scheme](https://en.wikipedia.org/wiki/Sparse_matrix#Compressed_sparse_row_.28CSR.2C_CRS_or_Yale_format.29).
8
9## Features
10
11- sparse matrix/sparse matrix addition, multiplication.
12- sparse vector/sparse vector addition, dot product.
13- sparse matrix/dense matrix addition, multiplication.
14- sparse triangular solves.
15- powerful iteration over the sparse structure, enabling easy extension of the library.
16- matrix construction using the [triplet format](struct.TriMatBase.html),
17  vertical and horizontal stacking, block construction.
18- sparse cholesky solver in the separate crate `sprs-ldl`.
19- fully generic integer type for the storage of indices, enabling compact
20  representations.
21- planned interoperability with existing sparse solvers such as `SuiteSparse`.
22
23## Quick Examples
24
25
26Matrix construction:
27
28```rust
29use sprs::{CsMat, TriMat};
30
31let mut a = TriMat::new((4, 4));
32a.add_triplet(0, 0, 3.0_f64);
33a.add_triplet(1, 2, 2.0);
34a.add_triplet(3, 0, -2.0);
35
36// This matrix type does not allow computations, and must to
37// converted to a compatible sparse type, using for example
38let b: CsMat<_> = a.to_csr();
39```
40
41Constructing matrix using the more efficient direct sparse constructor
42
43```rust
44use sprs::{CsMat, CsVec};
45let eye : CsMat<f64> = CsMat::eye(3);
46let a = CsMat::new_csc((3, 3),
47                       vec![0, 2, 4, 5],
48                       vec![0, 1, 0, 2, 2],
49                       vec![1., 2., 3., 4., 5.]);
50```
51
52Matrix vector multiplication:
53
54```rust
55use sprs::{CsMat, CsVec};
56let eye = CsMat::eye(5);
57let x = CsVec::new(5, vec![0, 2, 4], vec![1., 2., 3.]);
58let y = &eye * &x;
59assert_eq!(x, y);
60```
61
62Matrix matrix multiplication, addition:
63
64```rust
65use sprs::{CsMat, CsVec};
66let eye = CsMat::eye(3);
67let a = CsMat::new_csc((3, 3),
68                       vec![0, 2, 4, 5],
69                       vec![0, 1, 0, 2, 2],
70                       vec![1., 2., 3., 4., 5.]);
71let b = &eye * &a;
72assert_eq!(a, b.to_csc());
73```
74
75*/
76#![allow(clippy::redundant_slicing)]
77
78pub mod array_backend;
79mod dense_vector;
80pub mod errors;
81pub mod indexing;
82pub mod io;
83mod mul_acc;
84pub mod num_kinds;
85pub mod num_matrixmarket;
86mod range;
87mod sparse;
88pub mod stack;
89
90pub type Ix1 = ndarray::Ix1;
91pub type Ix2 = ndarray::Ix2;
92
93pub use crate::indexing::SpIndex;
94
95pub use crate::sparse::{
96    csmat::CsIter,
97    indptr::{IndPtr, IndPtrBase, IndPtrView},
98    kronecker::kronecker_product,
99    CsMat, CsMatBase, CsMatI, CsMatVecView, CsMatView, CsMatViewI,
100    CsMatViewMut, CsMatViewMutI, CsStructure, CsStructureI, CsStructureView,
101    CsStructureViewI, CsVec, CsVecBase, CsVecI, CsVecView, CsVecViewI,
102    CsVecViewMut, CsVecViewMutI, SparseMat, TriMat, TriMatBase, TriMatI,
103    TriMatIter, TriMatView, TriMatViewI, TriMatViewMut, TriMatViewMutI,
104};
105
106pub use crate::dense_vector::{DenseVector, DenseVectorMut};
107pub use crate::mul_acc::MulAcc;
108
109pub use crate::sparse::symmetric::is_symmetric;
110
111pub use crate::sparse::permutation::{
112    perm_is_valid, permute_cols, permute_rows, transform_mat_papt,
113    transform_mat_paq, PermOwned, PermOwnedI, PermView, PermViewI, Permutation,
114};
115
116pub use crate::sparse::CompressedStorage::{self, CSC, CSR};
117
118pub use crate::sparse::binop;
119pub use crate::sparse::linalg;
120pub use crate::sparse::prod;
121pub use crate::sparse::smmp;
122pub use crate::sparse::special_mats;
123pub use crate::sparse::visu;
124
125pub mod vec {
126    pub use crate::sparse::{CsVec, CsVecBase, CsVecView, CsVecViewMut};
127
128    pub use crate::sparse::vec::{
129        IntoSparseVecIter, NnzEither, NnzIndex, NnzOrZip, SparseIterTools,
130        VecDim, VectorIterator, VectorIteratorMut,
131    };
132}
133
134pub use crate::sparse::construct::{bmat, hstack, vstack};
135
136pub use crate::sparse::to_dense::assign_to_dense;
137
138/// The shape of a matrix. This a 2-tuple with the first element indicating
139/// the number of rows, and the second element indicating the number of
140/// columns.
141pub type Shape = (usize, usize); // FIXME: maybe we could use Ix2 here?
142
143/// Configuration enum to ask for symmetry checks in algorithms
144#[derive(Copy, Clone, Eq, PartialEq, Debug)]
145pub enum SymmetryCheck {
146    CheckSymmetry,
147    DontCheckSymmetry,
148}
149pub use SymmetryCheck::*;
150
151/// Configuration enum to ask for permutation checks in algorithms
152#[derive(Copy, Clone, Eq, PartialEq, Debug)]
153pub enum PermutationCheck {
154    CheckPerm,
155    DontCheckPerm,
156}
157pub use PermutationCheck::*;
158
159/// The different kinds of fill-in-reduction algorithms supported by sprs
160#[derive(Copy, Clone, Eq, PartialEq, Debug)]
161#[non_exhaustive]
162pub enum FillInReduction {
163    NoReduction,
164    ReverseCuthillMcKee,
165    #[allow(clippy::upper_case_acronyms)]
166    CAMDSuiteSparse,
167}
168
169#[cfg(feature = "approx")]
170/// Traits for comparing vectors and matrices using the approx traits
171///
172/// Comparisons of sparse matrices with different storages might be slow.
173/// It is advised to compare using the same storage order for efficiency
174///
175/// These traits requires the `approx` feature to be activated
176pub mod approx {
177    pub use approx::{AbsDiffEq, RelativeEq, UlpsEq};
178}
179
180#[cfg(test)]
181mod test_data;
182
183#[cfg(test)]
184mod test {
185    use super::CsMat;
186
187    #[test]
188    fn iter_rbr() {
189        let mat = CsMat::new(
190            (3, 3),
191            vec![0, 2, 3, 3],
192            vec![1, 2, 0],
193            vec![0.1, 0.2, 0.3],
194        );
195        let view = mat.view();
196        let mut iter = view.iter();
197        assert_eq!(iter.next(), Some((&0.1, (0, 1))));
198        assert_eq!(iter.next(), Some((&0.2, (0, 2))));
199        assert_eq!(iter.next(), Some((&0.3, (1, 0))));
200        assert_eq!(iter.next(), None);
201    }
202}