peroxide/traits/
matrix.rs

1use std::ops::{Index, IndexMut};
2
3pub trait MatrixTrait:
4    Sized + Index<(usize, usize), Output = Self::Scalar> + IndexMut<(usize, usize)>
5{
6    type Scalar;
7    fn ptr(&self) -> *const Self::Scalar;
8    fn mut_ptr(&mut self) -> *mut Self::Scalar;
9    fn as_slice(&self) -> &[Self::Scalar];
10    fn as_mut_slice(&mut self) -> &mut [Self::Scalar];
11    fn change_shape(&self) -> Self;
12    fn change_shape_mut(&mut self);
13    fn spread(&self) -> String;
14    fn col(&self, index: usize) -> Vec<Self::Scalar>;
15    fn row(&self, index: usize) -> Vec<Self::Scalar>;
16    fn diag(&self) -> Vec<Self::Scalar>;
17    fn transpose(&self) -> Self;
18    fn t(&self) -> Self {
19        self.transpose()
20    }
21    fn subs_col(&mut self, idx: usize, v: &[Self::Scalar]);
22    fn subs_row(&mut self, idx: usize, v: &[Self::Scalar]);
23    fn from_index<F, G>(f: F, size: (usize, usize)) -> Self
24    where
25        F: Fn(usize, usize) -> G + Copy,
26        G: Into<Self::Scalar>;
27    fn to_vec(&self) -> Vec<Vec<Self::Scalar>>;
28    fn to_diag(&self) -> Self;
29    fn submat(&self, start: (usize, usize), end: (usize, usize)) -> Self;
30    fn subs_mat(&mut self, start: (usize, usize), end: (usize, usize), m: &Self);
31}
32
33// ┌─────────────────────────────────────────────────────────┐
34//  For Linear Algebra
35// └─────────────────────────────────────────────────────────┘
36/// Linear algebra trait
37pub trait LinearAlgebra<M: MatrixTrait> {
38    fn back_subs(&self, b: &[M::Scalar]) -> Vec<M::Scalar>;
39    fn forward_subs(&self, b: &[M::Scalar]) -> Vec<M::Scalar>;
40    fn lu(&self) -> PQLU<M>;
41    fn waz(&self, d_form: Form) -> Option<WAZD<M>>;
42    fn qr(&self) -> QR<M>;
43    fn svd(&self) -> SVD<M>;
44    #[cfg(feature = "O3")]
45    fn cholesky(&self, uplo: UPLO) -> M;
46    fn rref(&self) -> M;
47    fn det(&self) -> M::Scalar;
48    fn block(&self) -> (M, M, M, M);
49    fn inv(&self) -> M;
50    fn pseudo_inv(&self) -> M;
51    fn solve(&self, b: &[M::Scalar], sk: SolveKind) -> Vec<M::Scalar>;
52    fn solve_mat(&self, m: &M, sk: SolveKind) -> M;
53    fn is_symmetric(&self) -> bool;
54}
55
56#[allow(non_snake_case)]
57pub fn solve<M: MatrixTrait + LinearAlgebra<M>>(A: &M, b: &M, sk: SolveKind) -> M {
58    A.solve_mat(b, sk)
59}
60
61/// Data structure for Complete Pivoting LU decomposition
62///
63/// # Usage
64/// ```rust
65/// use peroxide::fuga::*;
66///
67/// let a = ml_matrix("1 2;3 4");
68/// let pqlu = a.lu();
69/// let (p, q, l, u) = pqlu.extract();
70/// // p, q are permutations
71/// // l, u are matrices
72/// l.print(); // lower triangular
73/// u.print(); // upper triangular
74/// ```
75#[derive(Debug, Clone)]
76pub struct PQLU<M: MatrixTrait> {
77    pub p: Vec<usize>,
78    pub q: Vec<usize>,
79    pub l: M,
80    pub u: M,
81}
82
83#[derive(Debug, Clone)]
84pub struct WAZD<M: MatrixTrait> {
85    pub w: M,
86    pub z: M,
87    pub d: M,
88}
89
90#[derive(Debug, Clone)]
91pub struct QR<M: MatrixTrait> {
92    pub q: M,
93    pub r: M,
94}
95
96#[derive(Debug, Copy, Clone)]
97pub enum Form {
98    Diagonal,
99    Identity,
100}
101
102#[derive(Debug, Copy, Clone)]
103pub enum SolveKind {
104    LU,
105    WAZ,
106}
107
108#[allow(non_camel_case_types)]
109#[derive(Debug, Copy, Clone, Eq, PartialEq)]
110pub enum UPLO {
111    Upper,
112    Lower,
113}
114
115impl<M: MatrixTrait> QR<M> {
116    pub fn q(&self) -> &M {
117        &self.q
118    }
119
120    pub fn r(&self) -> &M {
121        &self.r
122    }
123}
124
125#[derive(Debug, Clone)]
126pub struct SVD<M: MatrixTrait> {
127    pub s: Vec<f64>,
128    pub u: M,
129    pub vt: M,
130}