use russell_lab::Matrix;
pub trait AsMatrix9x9 {
fn at(&self, i: usize, j: usize) -> f64;
}
impl AsMatrix9x9 for Vec<Vec<f64>> {
fn at(&self, i: usize, j: usize) -> f64 {
self[i][j]
}
}
impl AsMatrix9x9 for &[&[f64]] {
fn at(&self, i: usize, j: usize) -> f64 {
self[i][j]
}
}
impl AsMatrix9x9 for [[f64; 9]; 9] {
fn at(&self, i: usize, j: usize) -> f64 {
self[i][j]
}
}
impl AsMatrix9x9 for Matrix {
fn at(&self, i: usize, j: usize) -> f64 {
self.get(i, j)
}
}
#[cfg(test)]
mod tests {
use super::AsMatrix9x9;
use crate::MN_TO_IJKL;
use russell_lab::Matrix;
fn diagonal(mat: &dyn AsMatrix9x9) -> Vec<f64> {
let mut res = vec![0.0; 9];
for i in 0..9 {
res[i] = mat.at(i, i);
}
res
}
#[test]
fn as_matrix_9x9_works() {
let mut mat = vec![vec![0.0; 9]; 9];
for m in 0..9 {
for n in 0..9 {
let (i, j, k, l) = MN_TO_IJKL[m][n];
mat[m][n] = (1000 * (i + 1) + 100 * (j + 1) + 10 * (k + 1) + (l + 1)) as f64;
}
}
assert_eq!(
diagonal(&mat),
&[1111.0, 2222.0, 3333.0, 1212.0, 2323.0, 1313.0, 2121.0, 3232.0, 3131.0]
);
let ___ = 0.0;
let mat: &[&[f64]] = &[
&[1.0, ___, ___, ___, ___, ___, ___, ___, ___],
&[___, 2.0, ___, ___, ___, ___, ___, ___, ___],
&[___, ___, 3.0, ___, ___, ___, ___, ___, ___],
&[___, ___, ___, 4.0, ___, ___, ___, ___, ___],
&[___, ___, ___, ___, 5.0, ___, ___, ___, ___],
&[___, ___, ___, ___, ___, 6.0, ___, ___, ___],
&[___, ___, ___, ___, ___, ___, 7.0, ___, ___],
&[___, ___, ___, ___, ___, ___, ___, 8.0, ___],
&[___, ___, ___, ___, ___, ___, ___, ___, 9.0],
];
assert_eq!(diagonal(&mat), &[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]);
let mat = [
[1.0, ___, ___, ___, ___, ___, ___, ___, ___],
[___, 2.0, ___, ___, ___, ___, ___, ___, ___],
[___, ___, 3.0, ___, ___, ___, ___, ___, ___],
[___, ___, ___, 4.0, ___, ___, ___, ___, ___],
[___, ___, ___, ___, 5.0, ___, ___, ___, ___],
[___, ___, ___, ___, ___, 6.0, ___, ___, ___],
[___, ___, ___, ___, ___, ___, 7.0, ___, ___],
[___, ___, ___, ___, ___, ___, ___, 8.0, ___],
[___, ___, ___, ___, ___, ___, ___, ___, 9.0],
];
assert_eq!(diagonal(&mat), &[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]);
let diag = [10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0];
let mat = Matrix::diagonal(&diag);
assert_eq!(diagonal(&mat), &diag);
}
}