opensrdk_linear_algebra/matrix/ge/
mod.rs

1pub mod mm;
2pub mod operations;
3pub mod operators;
4pub mod or_un;
5pub mod svd;
6pub mod sy_he;
7pub mod tr;
8pub mod trf;
9pub mod tri;
10pub mod trs;
11
12use crate::{
13    number::{c64, Number},
14    MatrixError,
15};
16use rayon::prelude::*;
17use serde::{Deserialize, Serialize};
18use std::error::Error;
19
20/// # Matrix
21/// ```
22/// use opensrdk_linear_algebra::*;
23///
24/// let a = mat!(
25///   1.0, 2.0;
26///   3.0, 4.0
27/// );
28/// assert_eq!(a[0], [1.0, 3.0]);
29/// assert_eq!(a[1], [2.0, 4.0]);
30///
31/// assert_eq!(a[(0, 0)], 1.0);
32/// assert_eq!(a[(0, 1)], 2.0);
33/// assert_eq!(a[(1, 0)], 3.0);
34/// assert_eq!(a[(1, 1)], 4.0);
35/// ```
36#[derive(Clone, Debug, Default, PartialEq, Hash, Serialize, Deserialize)]
37pub struct Matrix<T = f64>
38where
39    T: Number,
40{
41    rows: usize,
42    cols: usize,
43    elems: Vec<T>,
44}
45
46impl From<Box<dyn Error + Send + Sync>> for MatrixError {
47    fn from(e: Box<dyn Error + Send + Sync>) -> Self {
48        MatrixError::Others(e)
49    }
50}
51
52impl<T> Matrix<T>
53where
54    T: Number,
55{
56    pub fn new(rows: usize, cols: usize) -> Self {
57        Self {
58            rows,
59            cols,
60            elems: vec![T::default(); rows * cols],
61        }
62    }
63
64    /// You can do `unwrap()` if you have a conviction that `elems.len() % rows == 0`
65    pub fn from(rows: usize, elems: Vec<T>) -> Result<Self, MatrixError> {
66        let cols = elems.len() / rows;
67
68        if elems.len() != rows * cols {
69            return Err(MatrixError::DimensionMismatch);
70        }
71
72        Ok(Self { rows, cols, elems })
73    }
74
75    pub fn is_same_size(&self, other: &Matrix<T>) -> bool {
76        self.rows == other.rows && self.cols == other.cols
77    }
78
79    pub fn rows(&self) -> usize {
80        self.rows
81    }
82
83    pub fn cols(&self) -> usize {
84        self.cols
85    }
86
87    pub fn vec(self) -> Vec<T> {
88        self.elems
89    }
90
91    pub fn elems(&self) -> &[T] {
92        &self.elems
93    }
94
95    pub fn elems_mut(&mut self) -> &mut [T] {
96        &mut self.elems
97    }
98
99    pub fn reshape(mut self, rows: usize) -> Self {
100        self.rows = rows;
101        self.cols = self.elems.len() / rows;
102
103        self
104    }
105
106    pub fn eject_row(&self, index: usize) -> Vec<T> {
107        (0..self.cols)
108            .into_iter()
109            .map(|j| self[(index, j)])
110            .collect()
111    }
112
113    pub fn eject_sub_matrix(
114        &self,
115        start_i: usize,
116        start_j: usize,
117        rows: usize,
118        cols: usize,
119    ) -> Matrix<T> {
120        Matrix::from(
121            rows,
122            (0..cols)
123                .into_iter()
124                .flat_map(|j| (0..rows).into_iter().map(move |i| (i, j)))
125                .map(|(i, j)| self[(start_i + i, start_j + j)])
126                .collect(),
127        )
128        .unwrap()
129    }
130}
131
132impl From<Matrix<f64>> for Matrix<c64> {
133    fn from(m: Matrix<f64>) -> Self {
134        Matrix::<c64>::from(
135            m.rows,
136            m.elems.par_iter().map(|&e| c64::new(e, 0.0)).collect(),
137        )
138        .unwrap()
139    }
140}
141
142impl Matrix<c64> {
143    pub fn real(&self) -> (Matrix<f64>, Matrix<f64>) {
144        (
145            Matrix::from(self.rows, self.elems.par_iter().map(|e| e.re).collect()).unwrap(),
146            Matrix::from(self.rows, self.elems.par_iter().map(|e| e.im).collect()).unwrap(),
147        )
148    }
149}
150
151pub trait Vector<T>
152where
153    T: Number,
154{
155    fn row_mat(self) -> Matrix<T>;
156    fn col_mat(self) -> Matrix<T>;
157}
158
159impl<T> Vector<T> for Vec<T>
160where
161    T: Number,
162{
163    fn row_mat(self) -> Matrix<T> {
164        Matrix::<T>::from(1, self).unwrap()
165    }
166
167    fn col_mat(self) -> Matrix<T> {
168        Matrix::<T>::from(self.len(), self).unwrap()
169    }
170}