use crate::matrix::Matrix;
use rayon::prelude::*;
use std::ops::{Add, Mul};
use crate::numlib::Zero;
impl<T: Send + Sync + Copy + Zero + Add<T, Output = T> + Mul<T, Output = T> + std::ops::Sub<Output = T>>
Matrix<T>
{
pub fn product_matrix(&self, other: &Matrix<T>) -> Result<Matrix<T>, &'static str> {
if self.width != other.height {
return Err("Matrices have mismatched sizes");
}
let mut other_t = Vec::with_capacity(other.size);
for row in 0..other.width {
for col in 0..other.height {
other_t.push(other[(col, row)]);
}
}
let res: Vec<T> = (0..self.height() * other.width())
.into_par_iter()
.map(|index| {
let row = index / other.width();
let col = index % other.width();
let mut entry = T::zero();
for index in 0..self.width {
entry = entry
+ self.data[row * self.width + index]
* other_t[col * other.width + index];
}
entry
}).collect();
Matrix::new(other.width, self.height, res)
}
#[deprecated(
since = "0.1.7",
note = "simple_product_matrix is a slower method use product_matrix to use the fastest algorithm"
)]
pub fn simple_product_matrix(&self, other: &Matrix<T>) -> Result<Matrix<T>, &'static str> {
if self.width != other.height {
return Err("Matrices have mismatched sizes");
}
let mut res = Vec::with_capacity(self.height * other.width);
for col in other.get_cols() {
res.extend(self.product_vector(&col).unwrap().as_vec());
}
Ok(Matrix::new(self.height, other.width, res)
.unwrap()
.transpose())
}
#[deprecated(
since = "0.2.0",
note = "trivial_product_matrix is a slower method use product_matrix to use the fastest algorithm"
)]
pub fn trivial_product_matrix(&self, other: &Matrix<T>) -> Result<Matrix<T>, &'static str> {
if self.width != other.height {
return Err("Matrices have mismatched sizes");
}
let mut other_t = Vec::with_capacity(other.size);
for row in 0..other.width {
for col in 0..other.height {
other_t.push(other[(col, row)]);
}
}
let mut res = vec![T::zero(); self.height * other.width];
for row in 0..self.height {
for col in 0..other.width {
let mut entry = res[row * other.width + col];
for index in 0..self.width {
entry = entry
+ self.data[row * self.width + index]
* other_t[col * other.width + index];
}
res[row * other.width + col] = entry;
}
}
Matrix::new(other.width, self.height, res)
}
}