Skip to main content

nalgebra_sparse/ops/serial/
mod.rs

1//! Serial sparse matrix arithmetic routines.
2//!
3//! All routines are single-threaded.
4//!
5//! Some operations have the `prealloc` suffix. This means that they expect that the sparsity
6//! pattern of the output matrix has already been pre-allocated: that is, the pattern of the result
7//! of the operation fits entirely in the output pattern. In the future, there will also be
8//! some operations which will be able to dynamically adapt the output pattern to fit the
9//! result, but these have yet to be implemented.
10
11macro_rules! assert_compatible_spmm_dims {
12    ($c:expr, $a:expr, $b:expr) => {{
13        use crate::ops::Op::{NoOp, Transpose};
14        match (&$a, &$b) {
15            (&NoOp(ref a), &NoOp(ref b)) => {
16                assert_eq!($c.nrows(), a.nrows(), "C.nrows() != A.nrows()");
17                assert_eq!($c.ncols(), b.ncols(), "C.ncols() != B.ncols()");
18                assert_eq!(a.ncols(), b.nrows(), "A.ncols() != B.nrows()");
19            }
20            (&Transpose(ref a), &NoOp(ref b)) => {
21                assert_eq!($c.nrows(), a.ncols(), "C.nrows() != A.ncols()");
22                assert_eq!($c.ncols(), b.ncols(), "C.ncols() != B.ncols()");
23                assert_eq!(a.nrows(), b.nrows(), "A.nrows() != B.nrows()");
24            }
25            (&NoOp(ref a), &Transpose(ref b)) => {
26                assert_eq!($c.nrows(), a.nrows(), "C.nrows() != A.nrows()");
27                assert_eq!($c.ncols(), b.nrows(), "C.ncols() != B.nrows()");
28                assert_eq!(a.ncols(), b.ncols(), "A.ncols() != B.ncols()");
29            }
30            (&Transpose(ref a), &Transpose(ref b)) => {
31                assert_eq!($c.nrows(), a.ncols(), "C.nrows() != A.ncols()");
32                assert_eq!($c.ncols(), b.nrows(), "C.ncols() != B.nrows()");
33                assert_eq!(a.nrows(), b.ncols(), "A.nrows() != B.ncols()");
34            }
35        }
36    }};
37}
38
39macro_rules! assert_compatible_spadd_dims {
40    ($c:expr, $a:expr) => {
41        use crate::ops::Op;
42        match $a {
43            Op::NoOp(a) => {
44                assert_eq!($c.nrows(), a.nrows(), "C.nrows() != A.nrows()");
45                assert_eq!($c.ncols(), a.ncols(), "C.ncols() != A.ncols()");
46            }
47            Op::Transpose(a) => {
48                assert_eq!($c.nrows(), a.ncols(), "C.nrows() != A.ncols()");
49                assert_eq!($c.ncols(), a.nrows(), "C.ncols() != A.nrows()");
50            }
51        }
52    };
53}
54
55mod cs;
56mod csc;
57mod csr;
58mod pattern;
59
60pub use csc::*;
61pub use csr::*;
62pub use pattern::*;
63use std::fmt;
64use std::fmt::Formatter;
65
66/// A description of the error that occurred during an arithmetic operation.
67#[derive(Clone, Debug)]
68pub struct OperationError {
69    error_kind: OperationErrorKind,
70    message: String,
71}
72
73/// The different kinds of operation errors that may occur.
74#[non_exhaustive]
75#[derive(Copy, Clone, Debug)]
76pub enum OperationErrorKind {
77    /// Indicates that one or more sparsity patterns involved in the operation violate the
78    /// expectations of the routine.
79    ///
80    /// For example, this could indicate that the sparsity pattern of the output is not able to
81    /// contain the result of the operation.
82    InvalidPattern,
83
84    /// Indicates that a matrix is singular when it is expected to be invertible.
85    Singular,
86}
87
88impl OperationError {
89    fn from_kind_and_message(error_type: OperationErrorKind, message: String) -> Self {
90        Self {
91            error_kind: error_type,
92            message,
93        }
94    }
95
96    /// The operation error kind.
97    #[must_use]
98    pub fn kind(&self) -> &OperationErrorKind {
99        &self.error_kind
100    }
101
102    /// The underlying error message.
103    #[must_use]
104    pub fn message(&self) -> &str {
105        self.message.as_str()
106    }
107}
108
109impl fmt::Display for OperationError {
110    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
111        write!(f, "Sparse matrix operation error: ")?;
112        match self.kind() {
113            OperationErrorKind::InvalidPattern => {
114                write!(f, "InvalidPattern")?;
115            }
116            OperationErrorKind::Singular => {
117                write!(f, "Singular")?;
118            }
119        }
120        write!(f, " Message: {}", self.message)
121    }
122}
123
124impl std::error::Error for OperationError {}