linfa_linalg/
lib.rs

1//! Provides pure-Rust implementations of linear algebra routines for `ndarray` without depending
2//! on external LAPACK/BLAS libraries.
3//!
4//! ## Eliminating BLAS dependencies
5//!
6//! If this crate is being used as a BLAS-less replacement for `ndarray-linalg`, make sure to
7//! remove `ndarray-linalg` from the entire dependency tree of your crate. This is because
8//! `ndarray-linalg`, even as a transitive dependency, forces `ndarray` to be built with the `blas`
9//! feature, which forces all matrix multiplications to rely on a BLAS backend. This leads to
10//! linker errors if no BLAS backend is specified.
11
12#![allow(clippy::many_single_char_names)]
13#![allow(clippy::result_large_err)]
14
15pub mod bidiagonal;
16pub mod cholesky;
17pub mod eigh;
18mod givens;
19mod householder;
20mod index;
21#[cfg(feature = "iterative")]
22pub mod lobpcg;
23pub mod norm;
24pub mod qr;
25pub mod reflection;
26pub mod svd;
27pub mod triangular;
28pub mod tridiagonal;
29
30use ndarray::{ArrayBase, Ix2, RawData, ShapeError};
31use thiserror::Error;
32
33#[derive(Debug, Error)]
34#[non_exhaustive]
35pub enum LinalgError {
36    /// Non-square matrix
37    #[error("Matrix of ({rows}, {cols}) is not square")]
38    NotSquare { rows: usize, cols: usize },
39    /// Matrix rows less than columns
40    #[error("Expected matrix rows({rows}) >= cols({cols})")]
41    NotThin { rows: usize, cols: usize },
42    /// Non-positive definite matrix
43    #[error("Matrix is not positive definite")]
44    NotPositiveDefinite,
45    /// Non-invertible matrix
46    #[error("Matrix is non-invertible")]
47    NonInvertible,
48    /// Unexpected empty matrix
49    #[error("Matrix is empty")]
50    EmptyMatrix,
51    /// Wrong number of columns in matrix
52    #[error("Matrix must have {expected} columns, not {actual}")]
53    WrongColumns { expected: usize, actual: usize },
54    /// Wrong number of rows in matrix
55    #[error("Matrix must have {expected} rows, not {actual}")]
56    WrongRows { expected: usize, actual: usize },
57    /// ShapeError from `ndarray`
58    #[error(transparent)]
59    Shape(#[from] ShapeError),
60}
61
62pub type Result<T> = std::result::Result<T, LinalgError>;
63
64pub(crate) fn check_square<S: RawData>(arr: &ArrayBase<S, Ix2>) -> Result<usize> {
65    let (n, m) = (arr.nrows(), arr.ncols());
66    if n != m {
67        Err(LinalgError::NotSquare { rows: n, cols: m })
68    } else {
69        Ok(n)
70    }
71}
72
73/// Find largest or smallest eigenvalues
74///
75/// Corresponds to descending and ascending order
76#[derive(Debug, Copy, Clone, PartialEq, Eq)]
77pub enum Order {
78    Largest,
79    Smallest,
80}