use crate::clifford::{CliffordAlgebra, Multivector};
use crate::linalg::f2;
use crate::scalar::{nim_add, Nimber};
pub fn dickson_matrix(g: &[Vec<u128>]) -> u128 {
let n = g.len();
let mut m: Vec<Vec<u128>> = g.to_vec();
for i in 0..n {
m[i][i] = nim_add(m[i][i], 1); }
(f2::nim_rank(m) % 2) as u128
}
pub fn dickson_of_versor(alg: &CliffordAlgebra<Nimber>, v: &Multivector<Nimber>) -> Option<u128> {
let dickson = crate::clifford::versor_grade_parity(v)?;
alg.versor_inverse(v)?;
Some(dickson)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::clifford::{CliffordAlgebra, Metric};
use crate::scalar::nim_mul;
#[test]
fn dickson_separates_rotations_from_reflections() {
assert_eq!(dickson_matrix(&[vec![1, 0], vec![0, 1]]), 0);
assert_eq!(dickson_matrix(&[vec![0, 1], vec![1, 0]]), 1);
assert_eq!(dickson_matrix(&[vec![2, 0], vec![0, 3]]), 0);
let swap = [[0u128, 1], [1, 0]];
let mut comp = vec![vec![0u128; 2]; 2];
for i in 0..2 {
for j in 0..2 {
let mut acc = 0u128;
for k in 0..2 {
acc ^= nim_mul(swap[i][k], swap[k][j]);
}
comp[i][j] = acc;
}
}
assert_eq!(dickson_matrix(&comp), 0);
}
#[test]
fn dickson_of_versor_is_grade_parity() {
let alg = CliffordAlgebra::new(2, Metric::diagonal(vec![Nimber(1), Nimber(1)]));
let scalar_one = alg.scalar(Nimber(1));
let e0 = alg.e(0);
let e0e1 = alg.mul(&alg.e(0), &alg.e(1));
assert_eq!(dickson_of_versor(&alg, &scalar_one), Some(0)); assert_eq!(dickson_of_versor(&alg, &e0), Some(1)); assert_eq!(dickson_of_versor(&alg, &e0e1), Some(0)); let mixed = alg.add(&e0, &e0e1);
assert_eq!(dickson_of_versor(&alg, &mixed), None);
let null_alg = CliffordAlgebra::new(1, Metric::grassmann(1));
assert_eq!(dickson_of_versor(&null_alg, &null_alg.e(0)), None);
}
}