Skip to main content

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}