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