pub trait Casimir {
type Representation;
fn quadratic_casimir_eigenvalue(irrep: &Self::Representation) -> f64;
fn higher_casimir_eigenvalues(_irrep: &Self::Representation) -> Vec<f64> {
vec![]
}
fn rank() -> usize;
fn num_casimirs() -> usize {
Self::rank()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_trait_compiles() {
}
#[test]
fn test_casimir_identity_su2_fundamental() {
use crate::representation::Spin;
use crate::su2::Su2Algebra;
use ndarray::Array2;
use num_complex::Complex64;
let sigma1: Array2<Complex64> = Array2::from_shape_vec(
(2, 2),
vec![
Complex64::new(0.0, 0.0),
Complex64::new(1.0, 0.0),
Complex64::new(1.0, 0.0),
Complex64::new(0.0, 0.0),
],
)
.unwrap();
let sigma2: Array2<Complex64> = Array2::from_shape_vec(
(2, 2),
vec![
Complex64::new(0.0, 0.0),
Complex64::new(0.0, -1.0),
Complex64::new(0.0, 1.0),
Complex64::new(0.0, 0.0),
],
)
.unwrap();
let sigma3: Array2<Complex64> = Array2::from_shape_vec(
(2, 2),
vec![
Complex64::new(1.0, 0.0),
Complex64::new(0.0, 0.0),
Complex64::new(0.0, 0.0),
Complex64::new(-1.0, 0.0),
],
)
.unwrap();
let t1 = &sigma1 / Complex64::new(2.0, 0.0);
let t2 = &sigma2 / Complex64::new(2.0, 0.0);
let t3 = &sigma3 / Complex64::new(2.0, 0.0);
let casimir_sum = t1.dot(&t1) + t2.dot(&t2) + t3.dot(&t3);
let expected_casimir = Su2Algebra::quadratic_casimir_eigenvalue(&Spin::HALF);
let expected_matrix: Array2<Complex64> =
Array2::eye(2) * Complex64::new(expected_casimir, 0.0);
for i in 0..2 {
for j in 0..2 {
let diff = (casimir_sum[[i, j]] - expected_matrix[[i, j]]).norm();
assert!(
diff < 1e-10,
"Casimir identity violated at ({},{}): got {}, expected {}",
i,
j,
casimir_sum[[i, j]],
expected_matrix[[i, j]]
);
}
}
assert!(
(expected_casimir - 0.75).abs() < 1e-10,
"C_{{1/2}} should be 3/4"
);
}
#[test]
fn test_casimir_identity_su2_adjoint() {
use crate::representation::Spin;
use crate::su2::Su2Algebra;
let epsilon = |a: usize, b: usize, c: usize| -> f64 {
if (a, b, c) == (0, 1, 2) || (a, b, c) == (1, 2, 0) || (a, b, c) == (2, 0, 1) {
1.0
} else if (a, b, c) == (0, 2, 1) || (a, b, c) == (2, 1, 0) || (a, b, c) == (1, 0, 2) {
-1.0
} else {
0.0
}
};
let mut t_adj: [[[f64; 3]; 3]; 3] = [[[0.0; 3]; 3]; 3];
for a in 0..3 {
for b in 0..3 {
for c in 0..3 {
t_adj[a][b][c] = epsilon(a, b, c);
}
}
}
let mut casimir_sum = [[0.0; 3]; 3];
for b in 0..3 {
for d in 0..3 {
for a in 0..3 {
for c in 0..3 {
casimir_sum[b][d] += t_adj[a][b][c] * t_adj[a][c][d];
}
}
}
}
let expected_casimir = Su2Algebra::quadratic_casimir_eigenvalue(&Spin::ONE);
for b in 0..3 {
for d in 0..3 {
let expected = if b == d { -expected_casimir } else { 0.0 };
let diff = (casimir_sum[b][d] - expected).abs();
assert!(
diff < 1e-10,
"Adjoint Casimir identity violated at ({},{}): got {}, expected {}",
b,
d,
casimir_sum[b][d],
expected
);
}
}
assert!(
(casimir_sum[0][0].abs() - expected_casimir).abs() < 1e-10,
"|∑_a (T^a T^a)_{{00}}| should equal C_adjoint = 2"
);
}
}