From ce8879c37ad0f823b15bbc80e79ce26cabc795c0 Mon Sep 17 00:00:00 2001 From: sebcrozet Date: Sun, 3 Feb 2019 14:18:55 +0100 Subject: [PATCH] Add all the missing docs. --- ci/build.sh | 2 +- src/io/matrix_market.rs | 2 + src/io/mod.rs | 4 +- src/sparse/cs_matrix.rs | 69 ++++++++++++++++++++++++------ src/sparse/cs_matrix_cholesky.rs | 19 ++++---- src/sparse/cs_matrix_conversion.rs | 18 +++----- src/sparse/cs_matrix_ops.rs | 12 +++--- src/sparse/cs_matrix_solve.rs | 18 ++++---- src/sparse/mod.rs | 4 +- 9 files changed, 95 insertions(+), 53 deletions(-) diff --git a/ci/build.sh b/ci/build.sh index 4c5c4d1b..550c9a69 100755 --- a/ci/build.sh +++ b/ci/build.sh @@ -11,7 +11,7 @@ if [ -z "$NO_STD" ]; then cargo build --verbose -p nalgebra --features "serde-serialize"; cargo build --verbose -p nalgebra --features "abomonation-serialize"; cargo build --verbose -p nalgebra --features "debug"; - cargo build --verbose -p nalgebra --features "debug arbitrary mint serde-serialize abomonation-serialize"; + cargo build --verbose -p nalgebra --all-features else cargo build -p nalgebra-lapack; fi diff --git a/src/io/matrix_market.rs b/src/io/matrix_market.rs index 12fb6c55..f4919cd4 100644 --- a/src/io/matrix_market.rs +++ b/src/io/matrix_market.rs @@ -10,12 +10,14 @@ use Real; struct MatrixMarketParser; // FIXME: return an Error instead of an Option. +/// Parses a Matrix Market file at the given path, and returns the corresponding sparse matrix. pub fn cs_matrix_from_matrix_market>(path: P) -> Option> { let file = fs::read_to_string(path).ok()?; cs_matrix_from_matrix_market_str(&file) } // FIXME: return an Error instead of an Option. +/// Parses a Matrix Market file described by the given string, and returns the corresponding sparse matrix. pub fn cs_matrix_from_matrix_market_str(data: &str) -> Option> { let file = MatrixMarketParser::parse(Rule::Document, data) .unwrap() diff --git a/src/io/mod.rs b/src/io/mod.rs index fd7dc536..1b172b20 100644 --- a/src/io/mod.rs +++ b/src/io/mod.rs @@ -1,3 +1,5 @@ -pub use self::matrix_market::*; +//! Parsers for various matrix formats. + +pub use self::matrix_market::{cs_matrix_from_matrix_market, cs_matrix_from_matrix_market_str}; mod matrix_market; diff --git a/src/sparse/cs_matrix.rs b/src/sparse/cs_matrix.rs index a02e8613..7ddc4deb 100644 --- a/src/sparse/cs_matrix.rs +++ b/src/sparse/cs_matrix.rs @@ -1,17 +1,14 @@ -use alga::general::{ClosedAdd, ClosedMul}; -use num::{One, Zero}; +use alga::general::ClosedAdd; +use num::Zero; use std::iter; use std::marker::PhantomData; -use std::ops::{Add, Mul, Range}; +use std::ops::Range; use std::slice; use allocator::Allocator; -use constraint::{AreMultipliable, DimEq, SameNumberOfRows, ShapeConstraint}; use sparse::cs_utils; -use storage::{Storage, StorageMut}; use { - DVector, DefaultAllocator, Dim, Dynamic, Matrix, MatrixMN, MatrixVec, Real, Scalar, Vector, - VectorN, U1, + DefaultAllocator, Dim, Dynamic, Scalar, Vector, VectorN, U1 }; pub struct ColumnEntries<'a, N> { @@ -47,38 +44,66 @@ impl<'a, N: Copy> Iterator for ColumnEntries<'a, N> { // FIXME: this structure exists for now only because impl trait // cannot be used for trait method return types. +/// Trait for iterable compressed-column matrix storage. pub trait CsStorageIter<'a, N, R, C = U1> { + /// Iterator through all the rows of a specific columns. + /// + /// The elements are given as a tuple (row_index, value). type ColumnEntries: Iterator; + /// Iterator through the row indices of a specific column. type ColumnRowIndices: Iterator; + /// Iterates through all the row indices of the j-th column. fn column_row_indices(&'a self, j: usize) -> Self::ColumnRowIndices; #[inline(always)] + /// Iterates through all the entries of the j-th column. fn column_entries(&'a self, j: usize) -> Self::ColumnEntries; } +/// Trait for mutably iterable compressed-column sparse matrix storage. pub trait CsStorageIterMut<'a, N: 'a, R, C = U1> { + /// Mutable iterator through all the values of the sparse matrix. type ValuesMut: Iterator; + /// Mutable iterator through all the rows of a specific columns. + /// + /// The elements are given as a tuple (row_index, value). type ColumnEntriesMut: Iterator; + /// A mutable iterator through the values buffer of the sparse matrix. fn values_mut(&'a mut self) -> Self::ValuesMut; + /// Iterates mutably through all the entries of the j-th column. fn column_entries_mut(&'a mut self, j: usize) -> Self::ColumnEntriesMut; } +/// Trait for compressed column sparse matrix storage. pub trait CsStorage: for<'a> CsStorageIter<'a, N, R, C> { + /// The shape of the stored matrix. fn shape(&self) -> (R, C); + /// Retrieve the i-th row index of the underlying row index buffer. + /// + /// No bound-checking is performed. unsafe fn row_index_unchecked(&self, i: usize) -> usize; + /// The i-th value on the contiguous value buffer of this storage. + /// + /// No bound-checking is performed. unsafe fn get_value_unchecked(&self, i: usize) -> &N; + /// The i-th value on the contiguous value buffer of this storage. fn get_value(&self, i: usize) -> &N; + /// Retrieve the i-th row index of the underlying row index buffer. fn row_index(&self, i: usize) -> usize; + /// The value indices for the `i`-th column. fn column_range(&self, i: usize) -> Range; + /// The size of the value buffer (i.e. the entries known as possibly being non-zero). fn len(&self) -> usize; } +/// Trait for compressed column sparse matrix mutable storage. pub trait CsStorageMut: CsStorage + for<'a> CsStorageIterMut<'a, N, R, C> { } +/// A storage of column-compressed sparse matrix based on a Vec. #[derive(Clone, Debug, PartialEq)] pub struct CsVecStorage where DefaultAllocator: Allocator @@ -92,12 +117,17 @@ where DefaultAllocator: Allocator impl CsVecStorage where DefaultAllocator: Allocator { + /// The value buffer of this storage. pub fn values(&self) -> &[N] { &self.vals } + + /// The column shifts buffer. pub fn p(&self) -> &[usize] { self.p.as_slice() } + + /// The row index buffers. pub fn i(&self) -> &[usize] { &self.i } @@ -209,15 +239,18 @@ pub struct CsMatrix< C: Dim = Dynamic, S: CsStorage = CsVecStorage, > { - pub data: S, + pub(crate) data: S, _phantoms: PhantomData<(N, R, C)>, } +/// A column compressed sparse vector. pub type CsVector> = CsMatrix; impl CsMatrix where DefaultAllocator: Allocator { + /// Creates a new compressed sparse column matrix with the specified dimension and + /// `nvals` possible non-zero values. pub fn new_uninitialized_generic(nrows: R, ncols: C, nvals: usize) -> Self { let mut i = Vec::with_capacity(nvals); unsafe { @@ -242,7 +275,8 @@ where DefaultAllocator: Allocator } } - pub fn from_parts_generic( + /* + pub(crate) fn from_parts_generic( nrows: R, ncols: C, p: VectorN, @@ -285,11 +319,12 @@ where DefaultAllocator: Allocator res.dedup(); res - } + }*/ } +/* impl CsMatrix { - pub fn from_parts( + pub(crate) fn from_parts( nrows: usize, ncols: usize, p: Vec, @@ -299,36 +334,42 @@ impl CsMatrix { { let nrows = Dynamic::new(nrows); let ncols = Dynamic::new(ncols); - let p = DVector::from_data(MatrixVec::new(ncols, U1, p)); + let p = DVector::from_data(VecStorage::new(ncols, U1, p)); Self::from_parts_generic(nrows, ncols, p, i, vals) } } +*/ impl> CsMatrix { - pub fn from_data(data: S) -> Self { + pub(crate) fn from_data(data: S) -> Self { CsMatrix { data, _phantoms: PhantomData, } } + /// The size of the data buffer. pub fn len(&self) -> usize { self.data.len() } + /// The number of rows of this matrix. pub fn nrows(&self) -> usize { self.data.shape().0.value() } + /// The number of rows of this matrix. pub fn ncols(&self) -> usize { self.data.shape().1.value() } + /// The shape of this matrix. pub fn shape(&self) -> (usize, usize) { let (nrows, ncols) = self.data.shape(); (nrows.value(), ncols.value()) } + /// Whether this matrix is square or not. pub fn is_square(&self) -> bool { let (nrows, ncols) = self.data.shape(); nrows.value() == ncols.value() @@ -360,6 +401,7 @@ impl> CsMatrix { true } + /// Computes the transpose of this sparse matrix. pub fn transpose(&self) -> CsMatrix where DefaultAllocator: Allocator { let (nrows, ncols) = self.data.shape(); @@ -392,6 +434,7 @@ impl> CsMatrix { } impl> CsMatrix { + /// Iterator through all the mutable values of this sparse matrix. #[inline] pub fn values_mut(&mut self) -> impl Iterator { self.data.values_mut() diff --git a/src/sparse/cs_matrix_cholesky.rs b/src/sparse/cs_matrix_cholesky.rs index 000332e7..5d834ef2 100644 --- a/src/sparse/cs_matrix_cholesky.rs +++ b/src/sparse/cs_matrix_cholesky.rs @@ -1,17 +1,11 @@ -use alga::general::{ClosedAdd, ClosedMul}; -use num::{One, Zero}; use std::iter; -use std::marker::PhantomData; use std::mem; -use std::ops::{Add, Mul, Range}; -use std::slice; use allocator::Allocator; -use constraint::{AreMultipliable, DimEq, SameNumberOfRows, ShapeConstraint}; -use sparse::{CsMatrix, CsStorage, CsStorageIter, CsStorageIterMut, CsVecStorage, CsVector}; -use storage::{Storage, StorageMut}; -use {DefaultAllocator, Dim, Matrix, MatrixMN, Real, Scalar, Vector, VectorN, U1}; +use sparse::{CsMatrix, CsStorage, CsStorageIter, CsStorageIterMut, CsVecStorage}; +use {DefaultAllocator, Dim, Real, VectorN, U1}; +/// The cholesky decomposition of a column compressed sparse matrix. pub struct CsCholesky where DefaultAllocator: Allocator + Allocator { @@ -68,6 +62,7 @@ where DefaultAllocator: Allocator + Allocator } } + /// The lower-triangular matrix of the cholesky decomposition. pub fn l(&self) -> Option<&CsMatrix> { if self.ok { Some(&self.l) @@ -76,6 +71,7 @@ where DefaultAllocator: Allocator + Allocator } } + /// Extracts the lower-triangular matrix of the cholesky decomposition. pub fn unwrap_l(self) -> Option> { if self.ok { Some(self.l) @@ -84,6 +80,8 @@ where DefaultAllocator: Allocator + Allocator } } + /// Perform a numerical left-looking cholesky decomposition of a matrix with the same structure as the + /// one used to initialize `self`, but with different non-zero values provided by `values`. pub fn decompose_left_looking(&mut self, values: &[N]) -> bool { assert!( values.len() >= self.original_i.len(), @@ -152,7 +150,8 @@ where DefaultAllocator: Allocator + Allocator true } - // Performs the numerical Cholesky decomposition given the set of numerical values. + /// Perform a numerical up-looking cholesky decomposition of a matrix with the same structure as the + /// one used to initialize `self`, but with different non-zero values provided by `values`. pub fn decompose_up_looking(&mut self, values: &[N]) -> bool { assert!( values.len() >= self.original_i.len(), diff --git a/src/sparse/cs_matrix_conversion.rs b/src/sparse/cs_matrix_conversion.rs index f37ef61d..0017340f 100644 --- a/src/sparse/cs_matrix_conversion.rs +++ b/src/sparse/cs_matrix_conversion.rs @@ -1,19 +1,14 @@ -use alga::general::{ClosedAdd, ClosedMul}; -use num::{One, Zero}; -use std::iter; -use std::marker::PhantomData; -use std::ops::{Add, Mul, Range}; -use std::slice; +use alga::general::ClosedAdd; +use num::Zero; use allocator::Allocator; -use constraint::{AreMultipliable, DimEq, SameNumberOfRows, ShapeConstraint}; use sparse::cs_utils; -use sparse::{CsMatrix, CsStorage, CsVector}; -use storage::{Storage, StorageMut}; -use {DefaultAllocator, Dim, Dynamic, Matrix, MatrixMN, Real, Scalar, Vector, VectorN, U1}; +use sparse::{CsMatrix, CsStorage}; +use storage::Storage; +use {DefaultAllocator, Dim, Dynamic, Matrix, MatrixMN, Scalar}; impl<'a, N: Scalar + Zero + ClosedAdd> CsMatrix { - // FIXME: implement for dimensions other than Dynamic too. + /// Creates a column-compressed sparse matrix from a sparse matrix in triplet form. pub fn from_triplet( nrows: usize, ncols: usize, @@ -29,6 +24,7 @@ impl<'a, N: Scalar + Zero + ClosedAdd> CsMatrix { impl<'a, N: Scalar + Zero + ClosedAdd, R: Dim, C: Dim> CsMatrix where DefaultAllocator: Allocator + Allocator { + /// Creates a column-compressed sparse matrix from a sparse matrix in triplet form. pub fn from_triplet_generic( nrows: R, ncols: C, diff --git a/src/sparse/cs_matrix_ops.rs b/src/sparse/cs_matrix_ops.rs index 5ebf099a..47804847 100644 --- a/src/sparse/cs_matrix_ops.rs +++ b/src/sparse/cs_matrix_ops.rs @@ -1,15 +1,12 @@ use alga::general::{ClosedAdd, ClosedMul}; use num::{One, Zero}; -use std::iter; -use std::marker::PhantomData; -use std::ops::{Add, Mul, Range}; -use std::slice; +use std::ops::{Add, Mul}; use allocator::Allocator; -use constraint::{AreMultipliable, DimEq, SameNumberOfRows, ShapeConstraint}; +use constraint::{AreMultipliable, DimEq, ShapeConstraint}; use sparse::{CsMatrix, CsStorage, CsStorageMut, CsVector}; -use storage::{Storage, StorageMut}; -use {DefaultAllocator, Dim, Matrix, MatrixMN, Real, Scalar, Vector, VectorN, U1}; +use storage::StorageMut; +use {DefaultAllocator, Dim, Scalar, Vector, VectorN, U1}; impl> CsMatrix { fn scatter( @@ -80,6 +77,7 @@ impl CsVector { */ impl> Vector { + /// Perform a sparse axpy operation: `self = alpha * x + beta * self` operation. pub fn axpy_cs(&mut self, alpha: N, x: &CsVector, beta: N) where S2: CsStorage, diff --git a/src/sparse/cs_matrix_solve.rs b/src/sparse/cs_matrix_solve.rs index 9cd25def..2a13188e 100644 --- a/src/sparse/cs_matrix_solve.rs +++ b/src/sparse/cs_matrix_solve.rs @@ -1,17 +1,11 @@ -use alga::general::{ClosedAdd, ClosedMul}; -use num::{One, Zero}; -use std::iter; -use std::marker::PhantomData; -use std::ops::{Add, Mul, Range}; -use std::slice; - use allocator::Allocator; -use constraint::{AreMultipliable, DimEq, SameNumberOfRows, ShapeConstraint}; +use constraint::{SameNumberOfRows, ShapeConstraint}; use sparse::{CsMatrix, CsStorage, CsVector}; use storage::{Storage, StorageMut}; -use {DefaultAllocator, Dim, Matrix, MatrixMN, Real, Scalar, Vector, VectorN, U1}; +use {DefaultAllocator, Dim, Matrix, MatrixMN, Real, VectorN, U1}; impl> CsMatrix { + /// Solve a lower-triangular system with a dense right-hand-side. pub fn solve_lower_triangular( &self, b: &Matrix, @@ -29,6 +23,7 @@ impl> CsMatrix { } } + /// Solve a lower-triangular system with `self` transposed and a dense right-hand-side. pub fn tr_solve_lower_triangular( &self, b: &Matrix, @@ -46,6 +41,7 @@ impl> CsMatrix { } } + /// Solve in-place a lower-triangular system with a dense right-hand-side. pub fn solve_lower_triangular_mut( &self, b: &mut Matrix, @@ -90,6 +86,7 @@ impl> CsMatrix { true } + /// Solve a lower-triangular system with `self` transposed and a dense right-hand-side. pub fn tr_solve_lower_triangular_mut( &self, b: &mut Matrix, @@ -135,6 +132,7 @@ impl> CsMatrix { true } + /// Solve a lower-triangular system with a sparse right-hand-side. pub fn solve_lower_triangular_cs( &self, b: &CsVector, @@ -195,6 +193,7 @@ impl> CsMatrix { Some(result) } + /* // Computes the reachable, post-ordered, nodes from `b`. fn lower_triangular_reach_postordered( &self, @@ -240,6 +239,7 @@ impl> CsMatrix { xi.push(j) } } + */ // Computes the nodes reachable from `b` in an arbitrary order. fn lower_triangular_reach(&self, b: &CsVector, xi: &mut Vec) diff --git a/src/sparse/mod.rs b/src/sparse/mod.rs index 546507eb..5df2d75d 100644 --- a/src/sparse/mod.rs +++ b/src/sparse/mod.rs @@ -1,3 +1,5 @@ +//! Sparse matrices. + pub use self::cs_matrix::{ CsMatrix, CsStorage, CsStorageIter, CsStorageIterMut, CsStorageMut, CsVecStorage, CsVector, }; @@ -8,4 +10,4 @@ mod cs_matrix_cholesky; mod cs_matrix_conversion; mod cs_matrix_ops; mod cs_matrix_solve; -pub mod cs_utils; +pub(crate) mod cs_utils;