mdarray_linalg/solve.rs
1//! Linear system solving utilities for equations of the form Ax = B
2//!```rust, ignore
3//!use mdarray_linalg_backend::Backend; // Use the real backend here, Lapack, Faer, ...
4//!let bd = Backend::default();
5//!use mdarray_linalg::solve::Solve;
6//!
7//!let a = darray![[2.0_f64, 1.0, 0.0], [1.0, 3.0, 1.0], [0.0, 1.0, 2.0]];
8//!let b = darray![[1.0_f64], [2.0], [1.0]];
9//!
10//!let xr = Lapack::default().solve(&mut a.clone(), &b);
11//!
12//!let x = xr.unwrap();
13//!let ax = Naive.matvec(&a, &x.view(.., 0)).eval(); // Ax = b
14//!```
15use mdarray::{Array, Dim, Layout, Slice};
16use thiserror::Error;
17
18/// Error types related to linear system solving
19#[derive(Debug, Error)]
20pub enum SolveError {
21 #[error("Backend error code: {0}")]
22 BackendError(i32),
23
24 #[error("Matrix is singular: U({diagonal},{diagonal}) is exactly zero")]
25 SingularMatrix { diagonal: i32 },
26
27 #[error("Invalid matrix dimensions")]
28 InvalidDimensions,
29}
30
31/// Linear system solver.
32pub trait Solve<T, D: Dim> {
33 /// Solves linear system AX = B, overwriting B with the solution X.
34 ///
35 /// The backend may also overwrite A with intermediate factorization data;
36 /// callers should not rely on A's contents after this call.
37 fn solve_write<R: Dim, La: Layout, Lb: Layout>(
38 &self,
39 a: &mut Slice<T, (D, D), La>,
40 b: &mut Slice<T, (D, R), Lb>,
41 ) -> Result<(), SolveError>;
42
43 /// Solves linear system AX = B with a newly allocated solution matrix.
44 ///
45 /// The backend may overwrite A with intermediate factorization data;
46 /// callers should not rely on A's contents after this call.
47 fn solve<R: Dim, La: Layout, Lb: Layout>(
48 &self,
49 a: &mut Slice<T, (D, D), La>,
50 b: &Slice<T, (D, R), Lb>,
51 ) -> Result<Array<T, (D, R)>, SolveError>;
52}