use matten::Tensor;
fn matrix_power(a: &Tensor, k: u32) -> Tensor {
let mut acc = a.clone();
for _ in 1..k {
acc = acc.matmul(a);
}
acc
}
fn print_matrix(label: &str, m: &Tensor) {
let (rows, cols) = (m.shape()[0], m.shape()[1]);
println!("{label}:");
for i in 0..rows {
let row: Vec<String> = (0..cols)
.map(|j| format!("{:.0}", m.get(&[i, j]).expect("index in bounds")))
.collect();
println!(" [{}]", row.join(", "));
}
}
fn main() {
let a = Tensor::new(
vec![
0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, ],
&[4, 4],
);
let a2 = matrix_power(&a, 2);
let a3 = matrix_power(&a, 3);
print_matrix("A^2", &a2);
print_matrix("A^3", &a3);
let walks2 = a2.get(&[0, 3]).expect("index in bounds");
let walks3 = a3.get(&[0, 3]).expect("index in bounds");
println!("walks of length 2 from 0 to 3 = {walks2:.0}");
println!("walks of length 3 from 0 to 3 = {walks3:.0}");
assert_eq!(walks2, 2.0);
assert_eq!(walks3, 1.0);
println!("Graph path counting: OK");
}