use crate::Matrix;
impl Matrix {
pub fn mul_rows_by(&self, vec: &[f64]) -> Matrix {
assert_eq!(
vec.len(),
self.rows(),
"mul_rows_by: vec length {} != rows {}",
vec.len(),
self.rows()
);
let mut data = self.as_slice().to_vec();
for (r, &factor) in vec.iter().enumerate().take(self.rows()) {
let start = r * self.cols();
for c in 0..self.cols() {
data[start + c] *= factor;
}
}
Matrix::from_vec(data, self.rows(), self.cols())
}
pub fn mul_cols_by(&self, vec: &[f64]) -> Matrix {
assert_eq!(
vec.len(),
self.cols(),
"mul_cols_by: vec length {} != cols {}",
vec.len(),
self.cols()
);
let mut data = self.as_slice().to_vec();
for r in 0..self.rows() {
let start = r * self.cols();
for c in 0..self.cols() {
data[start + c] *= vec[c];
}
}
Matrix::from_vec(data, self.rows(), self.cols())
}
pub fn outer_sub(a: &[f64], b: &[f64]) -> Matrix {
Matrix::from_fn(a.len(), b.len(), |i, j| a[i] - b[j])
}
pub fn outer_mul(a: &[f64], b: &[f64]) -> Matrix {
Matrix::from_fn(a.len(), b.len(), |i, j| a[i] * b[j])
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_mul_rows_by() {
let m = Matrix::from_rows(&[&[1.0, 2.0], &[3.0, 4.0], &[5.0, 6.0]]);
let result = m.mul_rows_by(&[1.0, 2.0, 3.0]);
assert_eq!(result.row(0), &[1.0, 2.0]);
assert_eq!(result.row(1), &[6.0, 8.0]);
assert_eq!(result.row(2), &[15.0, 18.0]);
}
#[test]
fn test_mul_cols_by() {
let m = Matrix::from_rows(&[&[1.0, 2.0], &[3.0, 4.0], &[5.0, 6.0]]);
let result = m.mul_cols_by(&[10.0, 20.0]);
assert_eq!(result.row(0), &[10.0, 40.0]);
assert_eq!(result.row(1), &[30.0, 80.0]);
assert_eq!(result.row(2), &[50.0, 120.0]);
}
#[test]
fn test_outer_sub() {
let result = Matrix::outer_sub(&[1.0, 2.0], &[10.0, 20.0, 30.0]);
assert_eq!(result.shape(), (2, 3));
assert_eq!(result.row(0), &[-9.0, -19.0, -29.0]);
assert_eq!(result.row(1), &[-8.0, -18.0, -28.0]);
}
#[test]
fn test_outer_mul() {
let result = Matrix::outer_mul(&[2.0, 3.0], &[10.0, 20.0]);
assert_eq!(result.shape(), (2, 2));
assert_eq!(result.row(0), &[20.0, 40.0]);
assert_eq!(result.row(1), &[30.0, 60.0]);
}
#[test]
#[should_panic(expected = "mul_rows_by")]
fn test_mul_rows_by_wrong_length() {
let m = Matrix::zeros(3, 2);
m.mul_rows_by(&[1.0, 2.0]);
}
#[test]
#[should_panic(expected = "mul_cols_by")]
fn test_mul_cols_by_wrong_length() {
let m = Matrix::zeros(3, 2);
m.mul_cols_by(&[1.0, 2.0, 3.0]);
}
}