use crate::element::Tropical;
use crate::matrix::{MAX_DIM, TropMatrix};
pub fn eigenvalue(a: &TropMatrix) -> Tropical {
let n = a.n;
if n == 0 {
return Tropical::INF;
}
let mut d = [[Tropical::INF; MAX_DIM]; MAX_DIM + 1];
d[0][0] = Tropical::ONE;
for k in 0..n {
for v in 0..n {
if d[k][v].is_inf() {
continue;
}
for w in 0..n {
let edge = a.get(v, w);
let candidate = d[k][v].mul(edge);
d[k + 1][w] = d[k + 1][w].add(candidate);
}
}
}
let mut best_num: u64 = u64::MAX;
let mut best_den: u64 = 1;
let mut found = false;
for v in 0..n {
if d[n][v].is_inf() {
continue;
}
let mut worst_num: u64 = 0;
let mut worst_den: u64 = 1;
let mut v_valid = false;
for k in 0..n {
if d[k][v].is_inf() {
continue;
}
let dn = d[n][v].as_u64();
let dk = d[k][v].as_u64();
if dn < dk {
continue;
}
let num = dn - dk;
let den = (n - k) as u64;
if !v_valid ๏ฟฟ๏ฟฟ num * worst_den > worst_num * den {
worst_num = num;
worst_den = den;
v_valid = true;
}
}
if v_valid && (!found ๏ฟฟ๏ฟฟ worst_num * best_den < best_num * worst_den) {
best_num = worst_num;
best_den = worst_den;
found = true;
}
}
if !found {
return Tropical::INF;
}
Tropical::from_u64(best_num / best_den)
}