pub fn signed_permutation(
a: MatRef<'_, f64>,
reference: MatRef<'_, f64>,
check_finite: bool,
) -> Result<SignedPermutationAlignment, ProcrustesError>Expand description
Solve min_{P ∈ S_K, s ∈ {±1}^K} ‖a · P · diag(s) − reference‖_F exactly.
§Algorithm
For K ≤ 3: brute-force enumeration of K! permutations
(cost-per-cell nb[p[k]] − 2·|dot[p[k], k]| + nr[k], optimal sign per
permutation closed-form). For K ≥ 4: Jonker-Volgenant linear assignment
on -|aᵀ·reference|, O(K³). Both paths return the global optimum;
permutation at exact cost ties is implementation-defined and may
differ between the two paths.
§Errors
Same as crate::orthogonal.
§Examples
use procrustes::Mat;
// a is the 4×2 identity columns swapped, with column 1 sign-flipped.
let a = Mat::<f64>::from_fn(4, 2, |i, j| match (i, j) {
(0, 1) => 1.0,
(1, 0) => -1.0,
_ => 0.0,
});
let reference = Mat::<f64>::from_fn(4, 2, |i, j| if i == j { 1.0 } else { 0.0 });
let aln = procrustes::signed_permutation(a.as_ref(), reference.as_ref(), true).unwrap();
assert_eq!(aln.assigned, vec![1, 0]);
assert_eq!(aln.signs, vec![1.0, -1.0]);
assert!(aln.residual_frobenius < 1e-10);