mdarray_linalg/
lib.rs

1//! Linear algebra backends for [`mdarray`](https://crates.io/crates/mdarray)
2//!
3//! This crate defines a set of traits (`MatVec`, `MatMul`, `Eig`, `SVD`, …) that are
4//! implemented by different backends, allowing users to switch between them depending
5//! on their needs (performance, portability, or debugging).
6//!
7//! # Backends
8//!
9//! - [`Blas`](https://docs.rs/mdarray-linalg-blas): bindings to [BLAS](https://www.netlib.org/blas/)
10//! - [`Lapack`](https://docs.rs/mdarray-linalg-lapack): bindings to [LAPACK](https://www.netlib.org/lapack/)
11//! - [`Faer`](https://docs.rs/mdarray-linalg-faer): bindings to [Faer](https://faer.veganb.tw/)
12//! - `Naive`: simple demo backend, integrated into this crate
13//! > **Note:** Not all backends support all functionalities.
14//!
15// ! <details>
16// ! <summary>Click to expand the feature support table</summary>
17//!
18//! | Functionality                                     | BLAS | LAPACK | Naive | Faer |
19//! |---------------------------------------------------|:----:|:------:|:-----:|:----:|
20//! | **▶︎ Basic vector/matrix operations**              |||||
21//! | [Matrix/vector multiplications](crate::matvec::MatVec) | ✅ | ⬜ | 🔧 | 🔧 |
22//! | [Operations on vectors](crate::matvec::VecOps)     | ✅ | ⬜ | 🔧 | 🔧 |
23//! | [Matrix multiplication](crate::matmul::MatMul)     | ✅ | ⬜ | ✅ | ✅ |
24//! | [Argmax](crate::matvec::Argmax)                    | ✅ | ⬜ | ✅ | ⬜ |
25//! | **▶︎ Linear algebra**                              |||||
26//! | [Eigen decomposition](crate::eig::Eig)             | ⬜ | ✅ | ⬜ | ✅ |
27//! | [SVD decomposition](crate::svd::SVD)               | ⬜ | ✅ | ⬜ | ✅ |
28//! | [LU decomposition](crate::lu::LU)                  | ⬜ | ✅ | ⬜ | ✅ |
29//! | [Solve and inverse](crate::solve::Solve)           | ⬜ | ✅ | ⬜ | ✅ |
30//! | [QR decomposition](crate::qr::QR)                  | ⬜ | ✅ | ⬜ | ✅ |
31//! | [Cholesky decomposition](crate::lu::LU)| ⬜ | ✅ | ⬜ | 🔧 |
32//! | [Schur decomposition](crate::eig::Eig)         | ⬜ | ✅ | ⬜ | 🔧 |
33//! | **▶︎ Advanced**                                   |||||
34//! | [Tensor contraction](crate::matmul::MatMul)        | ✅ | ⬜ | ✅ | ✅ |
35//!
36//! ✅ = implemented
37//! 🔧 = not implemented yet / partially implemented
38//! ⬜ = not applicable / not part of the backend’s scope
39//!
40// </details>
41//!
42//! # Example
43//!
44//! > **Note:**
45//! > When running doctests with Blas or Lapack, linking issues may occur due to this Rust issue:
46//! > [rust-lang/rust#125657](https://github.com/rust-lang/rust/issues/125657). In that case, run the doctests with:
47//! > `RUSTDOCFLAGS="-L native=/usr/lib -C link-arg=-lopenblas" cargo test --doc`
48//! >
49//! > See also the section **Troubleshooting** below.
50//!
51//! The following example demonstrates basic functionality:
52//!
53//! ```rust
54//! use mdarray::tensor;
55//!
56//! // The prelude does not expose any names.  It only provides traits as _.
57//! use mdarray_linalg::prelude::*;
58//!
59//! // Backends are provided in partner crates (e.g. mdarray-linalg-blas or mdarray-linalg-faer),
60//! // the naive backend exists mostly as a demonstration.
61//! use mdarray_linalg::Naive;
62//!
63//! fn main() {
64//!     // Declare two vectors
65//!     let x = tensor![1., 2.];
66//!     let y = tensor![2., 4.];
67//!
68//!     // Declare two matrices
69//!     let a = tensor![[1., 2.], [3., 4.]];
70//!     let b = tensor![[5., 6.], [7., 8.]];
71//!
72//!     // ----- Scalar product -----
73//!     let dot_result = Naive.dot(&x, &y);
74//!     println!("dot(x, y) = {}", dot_result); // x · y
75//!
76//!     // ----- Matrix multiplication -----
77//!     let mut c = Naive.matmul(&a, &b).eval(); // C ← A ✕ B
78//!     Naive.matmul(&b, &a).add_to(&mut c);     // C ← B ✕ A + C
79//!     println!("A * B + B * A = {:?}", c);
80//! }
81//! ```
82//!Some notes:
83//!
84//! - **Memory usage**: Each trait provides a method returning new
85//!   matrices and an overwrite variant using user-allocated buffers.
86//!   In that last case, output shapes must match exactly.
87//!
88//! - **Backend configuration**: Some accept parameters; for example, SVD
89//!   may choose an optimal algorithm by default, but the user can
90//!   select a specific one if desired.
91//!
92//! - **Errors**: Convergence issues return a Result; other problems
93//!   (dimension mismatch) may panic.
94//!
95//! # Troubleshooting
96//!
97//! If you encounter linking issues with BLAS or LAPACK on Linux,
98//! one solution is to add a `build.rs` file and configure it to link the libraries manually.
99//! In your `Cargo.toml`, add:
100//!
101//! ```toml
102//! [package]
103//! build = "build.rs"
104//! ```
105//!
106//! Then, create a `build.rs` file with the following content:
107//!
108//! ```rust
109//! fn main() {
110//!     println!("cargo:rustc-link-lib=openblas");
111//!     println!("cargo:rustc-link-search=native=/usr/lib");
112//! }
113//! ```
114
115pub mod prelude;
116
117pub mod eig;
118pub mod lu;
119pub mod matmul;
120pub mod matvec;
121pub mod qr;
122pub mod solve;
123pub mod svd;
124
125pub mod utils;
126pub use utils::*;
127
128mod naive;
129pub use naive::Naive;
130
131pub mod testing;