matrixlab/matrix/
dense.rs1use std::ops::{Mul,Add,Sub};
20use crate::matrix::MatrixElement;
21use crate::vector::{Vector,VectorTrait,FloatVectorTrait};
22use crate::error::Error;
23use rayon::prelude::*;
24
25#[derive(PartialEq,Debug)]
26pub struct DenseMatrix<A> {
27 columns: Vec<Vector<A>>
28}
29impl<A> DenseMatrix<A> {
30 pub fn new(columns: Vec<Vector<A>>) -> DenseMatrix<A> {
32 DenseMatrix {
33 columns
34 }
35 }
36 pub fn add_column(&mut self, column: Vector<A>) {
37 self.columns.push(column);
38 }
39 pub fn num_rows(&self) -> usize {
40 match self.columns.get(0) {
43 Some(column) => column.len(),
44 None => 0
45 }
46 }
47 pub fn num_columns(&self) -> usize {
48 self.columns.len()
49 }
50
51}
52impl<A: Clone> DenseMatrix<A> {
54 pub fn transpose(&self) -> DenseMatrix<A> {
55 let mut columns = Vec::with_capacity(self.num_rows());
57 for _ in 0 .. self.num_rows() {
58 columns.push(Vec::with_capacity(self.num_columns()));
59 }
60
61 for column in self.columns.iter() {
63 for (i,entry) in column.iter().enumerate() {
64 columns[i].push(entry.clone());
65 }
66 }
67
68 DenseMatrix::new(columns)
69 }
70 pub fn from_rows(rows: Vec<Vector<A>>) -> DenseMatrix<A> {
72 DenseMatrix {
73 columns: rows
74 }.transpose()
75 }
76}
77
78impl<A: MatrixElement + Mul<Output=A> + Add<Output=A> + Sub<Output=A> + Default> DenseMatrix<A> {
80 pub fn scale(&self, other: &A) -> DenseMatrix<A> {
81 let columns = self.columns.par_iter()
82 .map_with(other,
83 |&mut o, column| column.iter()
84 .map(|e| *o**e)
85 .collect())
86 .collect();
87 DenseMatrix::new(columns)
88 }
89 pub fn vec_mul(&self, other: &Vector<A>) -> Result<Vector<A>,Error> {
90 if other.len() != self.columns.len() {
93 return Err(Error::SizeMismatch);
94 }
95 Ok(self.columns.par_iter()
96 .zip(other.par_iter())
97 .map(|(column,scale)| column.iter()
101 .map(|x| *x**scale)
102 .collect::<Vec<A>>())
103 .reduce(
104 || [Default::default()]
105 .into_iter()
106 .cycle()
107 .take(self.num_rows())
108 .cloned()
109 .collect(),
110 |x,y| x.add(&y)))
111 }
113 pub fn safe_mul(&self, other: &DenseMatrix<A>) -> Result<DenseMatrix<A>,Error> {
114 if self.num_columns() != other.num_rows() {
115 return Err(Error::SizeMismatch);
116 }
117
118 let new_cols = other.columns.par_iter()
119 .map_with(self, |&mut s, col| s.vec_mul(col))
120 .collect::<Result<Vec<Vec<A>>,Error>>()?;
121
122 Ok(DenseMatrix::new(new_cols))
123
124 }
125}
126impl DenseMatrix<f64> {
127 pub fn backsolve(&self, b: &Vector<f64>) -> Vector<f64> {
130 let mut solutions: Vec<f64> = b.clone();
132 for (i,column) in self.columns.iter().rev().enumerate() {
134 let last_element = b.len()-1-i;
136 solutions[last_element] /= column[last_element];
137 for (j,element) in column.iter().rev().skip(1+i).enumerate() {
140 let last_element = b.len()-1-i;
142 let current_element = last_element - 1-j;
146 solutions[current_element] -= solutions[last_element] * element;
147 }
148 }
149 solutions
150 }
151 pub fn least_squares(&self, r: &Vector<f64>) -> Result<Vector<f64>,Error> {
153 let q = self.factor_q();
155 let q_transpose = q.transpose();
156 let rhs = q_transpose.vec_mul(&r)?;
157 let r = q_transpose.safe_mul(self).expect("Error in least squares, multiplication failed");;
158
159 Ok(r.backsolve(&rhs))
161 }
162 pub fn factor_q(&self) -> DenseMatrix<f64> {
163 let mut q_vectors: Vec<Vector<f64>> = Vec::with_capacity(self.num_columns());
164 for column in self.columns.iter() {
165 let mut maybe_q = column.clone();
166 for orthogonal in q_vectors.iter() {
167 let c = column.inner(orthogonal);
168 maybe_q = maybe_q.sub(&orthogonal.scale(c));
170 }
171 let q = maybe_q.normalize();
172 q_vectors.push(q);
173 }
174
175 DenseMatrix::new(q_vectors)
176 }
177 pub fn orthogonal_to(&self,other: &Vector<f64>) -> Vector<f64> {
180 let mut final_vec = other.clone();
181 for column in self.columns.iter() {
182 final_vec = final_vec.sub(&column.scale(other.inner(column)));
183 }
184 final_vec
185 }
186}