use crate::element::Tropical;
use crate::matrix::TropMatrix;
const MAX_NAIVE_DIM: usize = 10;
pub fn determinant(a: &TropMatrix) -> Tropical {
let n = a.n;
if n == 0 {
return Tropical::ONE; }
assert!(
n <= MAX_NAIVE_DIM,
"determinant: n={} exceeds naive limit {}; use Hungarian algorithm",
n,
MAX_NAIVE_DIM
);
let mut perm: [usize; MAX_NAIVE_DIM] = [0; MAX_NAIVE_DIM];
for (i, elem) in perm.iter_mut().take(n).enumerate() {
*elem = i;
}
let mut best = Tropical::INF;
permutation_search(a, &mut perm, n, n, &mut best);
best
}
fn eval_perm(a: &TropMatrix, perm: &[usize], n: usize, best: &mut Tropical) {
let mut cost = Tropical::ONE; for (i, &col) in perm.iter().enumerate().take(n) {
cost = cost.mul(a.get(i, col));
if cost.is_inf() {
return; }
}
*best = best.add(cost);
}
fn permutation_search(
a: &TropMatrix,
perm: &mut [usize; 10],
k: usize,
n: usize,
best: &mut Tropical,
) {
if k == 1 {
eval_perm(a, perm, n, best);
return;
}
for i in 0..k {
permutation_search(a, perm, k - 1, n, best);
if k.is_multiple_of(2) {
perm.swap(i, k - 1);
} else {
perm.swap(0, k - 1);
}
}
}