2020-07-21 23:39:06 +08:00
|
|
|
//! Sparse matrices and algorithms for nalgebra.
|
|
|
|
//!
|
|
|
|
//! TODO: Docs
|
2020-09-22 16:51:29 +08:00
|
|
|
//!
|
|
|
|
//!
|
|
|
|
//! ### Planned functionality
|
|
|
|
//!
|
|
|
|
//! Below we list desired functionality. This further needs to be refined into what is needed
|
|
|
|
//! for an initial contribution, and what can be added in future contributions.
|
|
|
|
//!
|
|
|
|
//! - Sparsity pattern type. Functionality:
|
|
|
|
//! - [x] Access to offsets, indices as slices.
|
|
|
|
//! - [x] Return number of nnz
|
|
|
|
//! - [x] Access a given lane as a slice of minor indices
|
|
|
|
//! - [x] Construct from valid offset + index data
|
|
|
|
//! - [ ] Construct from unsorted (but otherwise valid) offset + index data
|
|
|
|
//! - [x] Iterate over entries (i, j) in the pattern
|
2020-09-24 15:55:09 +08:00
|
|
|
//! - [x] "Disassemble" the sparsity pattern into the raw index data arrays.
|
2020-09-22 16:51:29 +08:00
|
|
|
//! - CSR matrix type. Functionality:
|
|
|
|
//! - [x] Access to CSR data as slices.
|
|
|
|
//! - [x] Return number of nnz
|
|
|
|
//! - [x] Access a given row, which gives convenient access to the data associated
|
|
|
|
//! with a particular row
|
|
|
|
//! - [x] Construct from valid CSR data
|
|
|
|
//! - [ ] Construct from unsorted CSR data
|
|
|
|
//! - [x] Iterate over entries (i, j, v) in the matrix (+mutable).
|
|
|
|
//! - [x] Iterate over rows in the matrix (+ mutable).
|
2020-09-24 15:55:09 +08:00
|
|
|
//! - [x] "Disassemble" the CSR matrix into the raw CSR data arrays.
|
2020-09-22 16:51:29 +08:00
|
|
|
//!
|
|
|
|
//! - CSC matrix type. Functionality:
|
2020-09-28 17:36:00 +08:00
|
|
|
//! - [x] Access to CSC data as slices.
|
|
|
|
//! - [x] Return number of nnz
|
|
|
|
//! - [x] Access a given column, which gives convenient access to the data associated
|
|
|
|
//! with a particular column
|
|
|
|
//! - [x] Construct from valid CSC data
|
|
|
|
//! - [ ] Construct from unsorted CSC data
|
|
|
|
//! - [x] Iterate over entries (i, j, v) in the matrix (+mutable).
|
|
|
|
//! - [x] Iterate over rows in the matrix (+ mutable).
|
|
|
|
//! - [x] "Disassemble" the CSC matrix into the raw CSC data arrays.
|
2020-09-22 16:51:29 +08:00
|
|
|
//! - COO matrix type. Functionality:
|
|
|
|
//! - [x] Construct new "empty" COO matrix
|
|
|
|
//! - [x] Construct from triplet arrays.
|
|
|
|
//! - [x] Push new triplets to the matrix.
|
|
|
|
//! - [x] Iterate over triplets.
|
|
|
|
//! - [x] "Disassemble" the COO matrix into its underlying triplet arrays.
|
|
|
|
//! - Format conversion:
|
|
|
|
//! - [x] COO -> Dense
|
2020-11-25 00:36:03 +08:00
|
|
|
//! - [x] CSR -> Dense
|
|
|
|
//! - [x] CSC -> Dense
|
|
|
|
//! - [x] COO -> CSR
|
|
|
|
//! - [x] COO -> CSC
|
|
|
|
//! - [x] CSR -> CSC
|
|
|
|
//! - [x] CSC -> CSR
|
|
|
|
//! - [x] CSR -> COO
|
|
|
|
//! - [x] CSC -> COO
|
|
|
|
//! - [x] Dense -> COO
|
|
|
|
//! - [x] Dense -> CSR
|
|
|
|
//! - [x] Dense -> CSC
|
2020-09-22 16:51:29 +08:00
|
|
|
//! - Arithmetic. In general arithmetic is only implemented between instances of the same format,
|
|
|
|
//! or between dense and instances of a given format. For example, we do not implement
|
|
|
|
//! CSR * CSC, only CSR * CSR and CSC * CSC.
|
|
|
|
//! - CSR:
|
|
|
|
//! - [ ] Dense = CSR * Dense (the other way around is not particularly useful)
|
|
|
|
//! - [ ] CSR = CSR * CSR
|
|
|
|
//! - [ ] CSR = CSR +- CSR
|
|
|
|
//! - [ ] CSR +=/-= CSR
|
|
|
|
//! - COO:
|
|
|
|
//! - [ ] Dense = COO * Dense (sometimes useful for very sparse matrices)
|
|
|
|
//! - CSC:
|
|
|
|
//! - Same as CSR
|
|
|
|
//! - Cholesky factorization (port existing factorization from nalgebra's sparse module)
|
|
|
|
//!
|
|
|
|
//!
|
2020-11-18 21:14:38 +08:00
|
|
|
//! TODO: Write docs on the following:
|
|
|
|
//!
|
|
|
|
//! - Overall design ("easy API" vs. "expert" API etc.)
|
|
|
|
//! - Conversions (From, explicit "expert" API etc.)
|
|
|
|
//! - Matrix ops design
|
2020-07-21 23:39:06 +08:00
|
|
|
#![deny(non_camel_case_types)]
|
|
|
|
#![deny(unused_parens)]
|
|
|
|
#![deny(non_upper_case_globals)]
|
|
|
|
#![deny(unused_qualifications)]
|
|
|
|
#![deny(unused_results)]
|
|
|
|
#![deny(missing_docs)]
|
|
|
|
|
2020-09-23 15:34:19 +08:00
|
|
|
pub mod coo;
|
2020-09-28 17:36:00 +08:00
|
|
|
pub mod csc;
|
2020-09-23 15:34:19 +08:00
|
|
|
pub mod csr;
|
|
|
|
pub mod pattern;
|
2020-07-14 00:44:40 +08:00
|
|
|
pub mod ops;
|
2020-11-18 21:14:38 +08:00
|
|
|
pub mod convert;
|
2020-07-14 00:44:40 +08:00
|
|
|
|
2020-12-30 23:09:46 +08:00
|
|
|
pub(crate) mod cs;
|
2020-12-22 17:19:17 +08:00
|
|
|
|
2020-11-12 18:49:19 +08:00
|
|
|
#[cfg(feature = "proptest-support")]
|
|
|
|
pub mod proptest;
|
|
|
|
|
2020-07-14 00:44:40 +08:00
|
|
|
use std::error::Error;
|
|
|
|
use std::fmt;
|
2020-12-09 22:25:16 +08:00
|
|
|
use num_traits::Zero;
|
2020-07-14 00:44:40 +08:00
|
|
|
|
2020-07-21 23:39:06 +08:00
|
|
|
/// Errors produced by functions that expect well-formed sparse format data.
|
2020-07-14 00:44:40 +08:00
|
|
|
#[derive(Debug)]
|
2020-09-22 23:50:47 +08:00
|
|
|
pub struct SparseFormatError {
|
|
|
|
kind: SparseFormatErrorKind,
|
|
|
|
// Currently we only use an underlying error for generating the `Display` impl
|
|
|
|
error: Box<dyn Error>
|
|
|
|
}
|
|
|
|
|
|
|
|
impl SparseFormatError {
|
|
|
|
/// The type of error.
|
|
|
|
pub fn kind(&self) -> &SparseFormatErrorKind {
|
|
|
|
&self.kind
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn from_kind_and_error(kind: SparseFormatErrorKind, error: Box<dyn Error>) -> Self {
|
|
|
|
Self {
|
|
|
|
kind,
|
|
|
|
error
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Helper functionality for more conveniently creating errors.
|
|
|
|
pub(crate) fn from_kind_and_msg(kind: SparseFormatErrorKind, msg: &'static str) -> Self {
|
|
|
|
Self::from_kind_and_error(kind, Box::<dyn Error>::from(msg))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// The type of format error described by a [SparseFormatError](struct.SparseFormatError.html).
|
2020-09-25 21:11:43 +08:00
|
|
|
#[non_exhaustive]
|
2020-09-25 20:48:10 +08:00
|
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
2020-09-22 23:50:47 +08:00
|
|
|
pub enum SparseFormatErrorKind {
|
2020-07-14 00:44:40 +08:00
|
|
|
/// Indicates that the index data associated with the format contains at least one index
|
|
|
|
/// out of bounds.
|
2020-09-22 23:50:47 +08:00
|
|
|
IndexOutOfBounds,
|
2020-07-14 00:44:40 +08:00
|
|
|
|
|
|
|
/// Indicates that the provided data contains at least one duplicate entry, and the
|
|
|
|
/// current format does not support duplicate entries.
|
2020-09-22 23:50:47 +08:00
|
|
|
DuplicateEntry,
|
2020-07-14 00:44:40 +08:00
|
|
|
|
|
|
|
/// Indicates that the provided data for the format does not conform to the high-level
|
|
|
|
/// structure of the format.
|
|
|
|
///
|
|
|
|
/// For example, the arrays defining the format data might have incompatible sizes.
|
2020-09-22 23:50:47 +08:00
|
|
|
InvalidStructure,
|
2020-07-14 00:44:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for SparseFormatError {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2020-09-22 23:50:47 +08:00
|
|
|
write!(f, "{}", self.error)
|
2020-07-14 00:44:40 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-09 22:25:16 +08:00
|
|
|
impl Error for SparseFormatError {}
|
|
|
|
|
|
|
|
/// TODO
|
|
|
|
#[derive(Debug, PartialEq, Eq)]
|
|
|
|
pub enum SparseEntry<'a, T> {
|
|
|
|
/// TODO
|
|
|
|
NonZero(&'a T),
|
|
|
|
/// TODO
|
|
|
|
Zero
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a, T: Clone + Zero> SparseEntry<'a, T> {
|
|
|
|
/// TODO
|
|
|
|
pub fn to_value(self) -> T {
|
|
|
|
match self {
|
|
|
|
SparseEntry::NonZero(value) => value.clone(),
|
|
|
|
SparseEntry::Zero => T::zero()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// TODO
|
|
|
|
#[derive(Debug, PartialEq, Eq)]
|
|
|
|
pub enum SparseEntryMut<'a, T> {
|
|
|
|
/// TODO
|
|
|
|
NonZero(&'a mut T),
|
|
|
|
/// TODO
|
|
|
|
Zero
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a, T: Clone + Zero> SparseEntryMut<'a, T> {
|
|
|
|
/// TODO
|
|
|
|
pub fn to_value(self) -> T {
|
|
|
|
match self {
|
|
|
|
SparseEntryMut::NonZero(value) => value.clone(),
|
|
|
|
SparseEntryMut::Zero => T::zero()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|