#[cfg(test)]
mod test;
use super::structures::*;
impl<const R: usize, const C: usize> Matrix<R, C> {
pub fn add_matrix_with_matrix(
augend: &Self,
addend: &Self,
) -> Self {
let mut sum = Self::default();
for r in 0..R {
for c in 0..C {
sum.rows[r][c] = augend.rows[r][c] + addend.rows[r][c];
}
}
sum
}
pub fn add_matrix_with_scalar(
augend: &Self,
addend: f64,
) -> Self {
let mut sum = Self::new(addend);
for r in 0..R {
for c in 0..C {
sum.rows[r][c] += augend.rows[r][c];
}
}
sum
}
pub fn divide_matrix_by_matrix_entrywise(
dividend_matrix: &Self,
divisor_matrix: &Self,
) -> Self {
let mut quotient_matrix = Self::default();
for r in 0..R {
for c in 0..C {
quotient_matrix.rows[r][c] =
dividend_matrix.rows[r][c] / divisor_matrix.rows[r][c];
}
}
quotient_matrix
}
pub fn divide_matrix_by_scalar(
dividend: &Self,
divisor: f64,
) -> Self {
let mut quotient = Self::default();
for r in 0..R {
for c in 0..C {
quotient.rows[r][c] = dividend.rows[r][c] / divisor;
}
}
quotient
}
pub fn multiply_matrix_with_matrix<const K: usize>(
multiplicand: &Self,
multiplier: &Matrix<C, K>,
) -> Matrix<R, K> {
let mut product = Matrix::<R, K>::default();
for r in 0..R {
for k in 0..K {
for i in 0..C {
product.rows[r][k] += multiplicand.rows[r][i] * multiplier.rows[i][k];
}
}
}
product
}
pub fn multiply_matrix_with_matrix_entrywise(
original_matrix: &Self,
weighting_matrix: &Self,
) -> Self {
let mut hadamard_product = Self::default();
for r in 0..R {
for c in 0..C {
hadamard_product.rows[r][c] =
original_matrix.rows[r][c] * weighting_matrix.rows[r][c];
}
}
hadamard_product
}
pub fn multiply_matrix_with_scalar(
multiplicand: &Self,
multiplier: f64,
) -> Self {
let mut product = Self::new(multiplier);
for r in 0..R {
for c in 0..C {
product.rows[r][c] *= multiplicand.rows[r][c];
}
}
product
}
pub fn negate_matrix(matrix: &Self) -> Self {
let mut negated_matrix = Self::default();
for r in 0..R {
for c in 0..C {
negated_matrix.rows[r][c] = -matrix.rows[r][c];
}
}
negated_matrix
}
pub fn new(value: f64) -> Self {
Self {
rows: [[value; C]; R],
}
}
pub fn subtract_matrix_from_matrix(
minuend: &Self,
subtrahend: &Self,
) -> Self {
let mut difference = Self::default();
for r in 0..R {
for c in 0..C {
difference.rows[r][c] = minuend.rows[r][c] - subtrahend.rows[r][c];
}
}
difference
}
pub fn subtract_matrix_from_scalar(
minuend: f64,
subtrahend: &Self,
) -> Self {
let mut difference = Self::new(minuend);
for r in 0..R {
for c in 0..C {
difference.rows[r][c] -= subtrahend.rows[r][c];
}
}
difference
}
pub fn subtract_scalar_from_matrix(
minuend: &Self,
subtrahend: f64,
) -> Self {
let mut difference = Self::default();
for r in 0..R {
for c in 0..C {
difference.rows[r][c] = minuend.rows[r][c] - subtrahend;
}
}
difference
}
}
impl<const R: usize> Matrix<R, R> {
pub fn identity() -> Self {
let mut identity_matrix = Self::default();
for r in 0..R {
identity_matrix.rows[r][r] = 1.0;
}
identity_matrix
}
}
impl Matrix<3, 3> {
pub fn to_rotation_matrix_x_from_degrees(degrees: Degrees) -> Self {
Self::to_rotation_matrix_x_from_radians(degrees.into())
}
pub fn to_rotation_matrix_x_from_radians(radians: Radians) -> Self {
let cos = radians.0.cos();
let sin = radians.0.sin();
Matrix {
rows: [
[
1.0, 0.0, 0.0,
],
[
0.0, cos, -sin,
],
[
0.0, sin, cos,
],
],
}
}
pub fn to_rotation_matrix_y_from_degrees(degrees: Degrees) -> Self {
Self::to_rotation_matrix_y_from_radians(degrees.into())
}
pub fn to_rotation_matrix_y_from_radians(radians: Radians) -> Self {
let cos = radians.0.cos();
let sin = radians.0.sin();
Matrix {
rows: [
[
cos, 0.0, sin,
],
[
0.0, 1.0, 0.0,
],
[
-sin, 0.0, cos,
],
],
}
}
pub fn to_rotation_matrix_z_from_degrees(degrees: Degrees) -> Self {
Self::to_rotation_matrix_z_from_radians(degrees.into())
}
pub fn to_rotation_matrix_z_from_radians(radians: Radians) -> Self {
let cos = radians.0.cos();
let sin = radians.0.sin();
Matrix {
rows: [
[
cos, -sin, 0.0,
],
[
sin, cos, 0.0,
],
[
0.0, 0.0, 1.0,
],
],
}
}
}