pub fn transpose_matrix(matrix: &[usize], rows: usize, cols: usize) -> Vec<Vec<usize>> {
(0..cols)
.map(|col| (0..rows).map(|row| matrix[row * cols + col]).collect())
.collect()
}
pub fn reshape_to_matrix(vec: Vec<usize>, rows: usize, cols: usize) -> Vec<Vec<usize>> {
vec.chunks(cols).map(|chunk| chunk.to_vec()).collect()
}
use nalgebra::*;
fn modular_inverse(x: f32, modulus: i32) -> Option<f32> {
for i in 1..modulus {
if (i as f32 * x % modulus as f32 + modulus as f32) % modulus as f32 == 1.0 {
return Some(i as f32);
}
}
None
}
fn minor(matrix: &DMatrix<f32>, row: usize, col: usize) -> f32 {
let submatrix = matrix.clone().remove_row(row).remove_column(col);
submatrix.determinant()
}
fn adjugate(matrix: &DMatrix<f32>) -> DMatrix<f32> {
let cofactor_matrix = matrix.map_with_location(|i, j, _| {
let sign = if (i + j) % 2 == 0 { 1.0 } else { -1.0 };
sign * minor(matrix, i, j)
});
cofactor_matrix.transpose()
}
#[test]
fn test_things() {
let m = Matrix3::new(5.0, 17.0, 6.0, 2.0, 21.0, 14.0, 19.0, 3.0, 11.0);
let determinant = m.determinant();
let det_mod: f32 = (determinant % 28.0 + 28.0) % 28.0;
dbg!(&determinant);
match modular_inverse(det_mod, 28) {
Some(det_mod_inverse) => {
let adjugate = Matrix3::new(
m[(1, 1)] * m[(2, 2)] - m[(1, 2)] * m[(2, 1)],
-(m[(1, 0)] * m[(2, 2)] - m[(1, 2)] * m[(2, 0)]),
m[(1, 0)] * m[(2, 1)] - m[(1, 1)] * m[(2, 0)],
-(m[(0, 1)] * m[(2, 2)] - m[(0, 2)] * m[(2, 1)]),
m[(0, 0)] * m[(2, 2)] - m[(0, 2)] * m[(2, 0)],
-(m[(0, 0)] * m[(2, 1)] - m[(0, 1)] * m[(2, 0)]),
m[(0, 1)] * m[(1, 2)] - m[(0, 2)] * m[(1, 1)],
-(m[(0, 0)] * m[(1, 2)] - m[(0, 2)] * m[(1, 0)]),
m[(0, 0)] * m[(1, 1)] - m[(0, 1)] * m[(1, 0)],
)
.transpose();
let modular_inverse = adjugate.map(|x| ((x * det_mod_inverse) % 28.0 + 28.0) % 28.0);
println!("Modular Inverse:\n{}", modular_inverse);
}
None => println!("Matrix is not invertible in mod 28"),
}
let m = Matrix3::new(5.0, 17.0, 6.0, 2.0, 21.0, 14.0, 19.0, 3.0, 11.0);
let m = DMatrix::from_row_slice(3, 3, m.as_slice());
let adj = adjugate(&m);
println!("Adjugate Matrix:\n{}", &adj);
let adj_trans = adj.transpose();
println!("Transposed Adjugate Matrix:\n{}", &adj_trans);
let determinant = m.determinant();
let det_mod: f32 = (determinant % 28.0 + 28.0) % 28.0;
dbg!(&determinant);
match modular_inverse(det_mod, 28) {
Some(det_mod_inverse) => {
let modular_inverse = adj_trans.map(|x| ((x * det_mod_inverse) % 28.0 + 28.0) % 28.0);
println!("Modular Inverse:\n{}", modular_inverse);
}
None => println!("Matrix is not invertible in mod 28"),
}
println!("===================================================");
let m = Matrix2::new(6.0, 25.0, 3.0, 11.0);
let m = DMatrix::from_row_slice(2, 2, m.as_slice());
let adj = adjugate(&m);
let adj_trans = adj.transpose();
let determinant = m.determinant();
let det_mod: f32 = (determinant % 28.0 + 28.0) % 28.0;
match modular_inverse(det_mod, 28) {
Some(det_mod_inverse) => {
let modular_inverse = adj_trans.map(|x| ((x * det_mod_inverse) % 28.0 + 28.0) % 28.0);
println!("Modular Inverse:\n{}", modular_inverse);
}
None => println!("Matrix is not invertible in mod 28"),
}
}