use super::codes::{barnes_wall_16, divided_lattice_from_rows, reed_muller_code};
use super::lattice::IntegralForm;
use std::fmt;
pub const BW16_CLIFFORD_SPINOR_DIMENSION: usize = 16;
pub const BW16_CLIFFORD_ROW_DIVISOR: i128 = 4;
pub const BW16_AUTOMORPHISM_GROUP_ORDER: u128 = 89_181_388_800;
pub const BW16_REAL_CLIFFORD_GROUP_ORDER: u128 = 178_362_777_600;
pub const BW16_AUTOMORPHISM_INDEX_IN_CLIFFORD_GROUP: u128 = 2;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct CliffordBarnesWall16Invariants {
pub lattice: IntegralForm,
pub construction_d_lattice: IntegralForm,
pub spinor_dimension: usize,
pub row_divisor: i128,
pub quadratic_phase_row_count: usize,
pub coordinate_weight_row_count: usize,
pub matches_construction_d: bool,
pub automorphism_group_order: u128,
pub full_clifford_group_order: u128,
pub automorphism_index_in_clifford_group: u128,
}
impl CliffordBarnesWall16Invariants {
pub fn determinant(&self) -> i128 {
self.lattice.determinant()
}
pub fn minimum(&self) -> Option<i128> {
self.lattice.minimum()
}
pub fn kissing_number(&self) -> Option<usize> {
self.lattice.kissing_number()
}
pub fn recorded_group_orders_are_consistent(&self) -> bool {
self.automorphism_group_order
.checked_mul(self.automorphism_index_in_clifford_group)
== Some(self.full_clifford_group_order)
}
pub fn display(&self) -> String {
self.to_string()
}
}
impl fmt::Display for CliffordBarnesWall16Invariants {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"CliffordBarnesWall16Invariants(dim={}, det={}, matches_construction_d={}, aut_order={}, full_clifford_order={}, index={})",
self.spinor_dimension,
self.determinant(),
self.matches_construction_d,
self.automorphism_group_order,
self.full_clifford_group_order,
self.automorphism_index_in_clifford_group,
)
}
}
pub fn clifford_barnes_wall_16_numerator_rows() -> Vec<Vec<i128>> {
let rm2 = reed_muller_code(2, 4).expect("RM(2,4) exists");
let mut rows = Vec::with_capacity(1 + rm2.dim() + BW16_CLIFFORD_SPINOR_DIMENSION);
rows.push(vec![1i128; BW16_CLIFFORD_SPINOR_DIMENSION]);
for row in rm2.generators() {
rows.push(
row.iter()
.map(|&bit| 1i128 - 2i128 * i128::from(bit))
.collect(),
);
}
for i in 0..BW16_CLIFFORD_SPINOR_DIMENSION {
let mut row = vec![0i128; BW16_CLIFFORD_SPINOR_DIMENSION];
row[i] = BW16_CLIFFORD_ROW_DIVISOR;
rows.push(row);
}
rows
}
pub fn clifford_barnes_wall_16() -> IntegralForm {
divided_lattice_from_rows(
clifford_barnes_wall_16_numerator_rows(),
BW16_CLIFFORD_SPINOR_DIMENSION,
BW16_CLIFFORD_ROW_DIVISOR,
)
.expect("Clifford BW16 rows give an integral full-rank lattice")
}
pub fn clifford_barnes_wall_16_report() -> CliffordBarnesWall16Invariants {
let rows = clifford_barnes_wall_16_numerator_rows();
let lattice = divided_lattice_from_rows(
rows.clone(),
BW16_CLIFFORD_SPINOR_DIMENSION,
BW16_CLIFFORD_ROW_DIVISOR,
)
.expect("Clifford BW16 rows give an integral full-rank lattice");
let construction_d_lattice = barnes_wall_16();
let coordinate_weight_row_count = BW16_CLIFFORD_SPINOR_DIMENSION;
let quadratic_phase_row_count = rows.len() - coordinate_weight_row_count;
let matches_construction_d = lattice.gram() == construction_d_lattice.gram();
CliffordBarnesWall16Invariants {
lattice,
construction_d_lattice,
spinor_dimension: BW16_CLIFFORD_SPINOR_DIMENSION,
row_divisor: BW16_CLIFFORD_ROW_DIVISOR,
quadratic_phase_row_count,
coordinate_weight_row_count,
matches_construction_d,
automorphism_group_order: BW16_AUTOMORPHISM_GROUP_ORDER,
full_clifford_group_order: BW16_REAL_CLIFFORD_GROUP_ORDER,
automorphism_index_in_clifford_group: BW16_AUTOMORPHISM_INDEX_IN_CLIFFORD_GROUP,
}
}
#[cfg(test)]
mod tests {
use super::*;
fn order_o_plus(m: u32, q: u128) -> u128 {
let mut order = 2 * q.pow(m * (m - 1)) * (q.pow(m) - 1);
for i in 1..m {
order *= q.pow(2 * i) - 1;
}
order
}
#[test]
fn real_clifford_group_order_matches_the_orthogonal_group_closed_form() {
let o_plus_8_2 = order_o_plus(4, 2);
assert_eq!(o_plus_8_2, 348_364_800);
let real_clifford = (1u128 << 9) * o_plus_8_2;
assert_eq!(real_clifford, BW16_REAL_CLIFFORD_GROUP_ORDER);
assert_eq!(real_clifford / 2, BW16_AUTOMORPHISM_GROUP_ORDER);
}
#[test]
fn clifford_rows_recover_construction_d_barnes_wall_16() {
let rows = clifford_barnes_wall_16_numerator_rows();
assert_eq!(rows.len(), 28);
assert_eq!(rows[0], vec![1; BW16_CLIFFORD_SPINOR_DIMENSION]);
let bw = clifford_barnes_wall_16();
assert_eq!(bw.gram(), barnes_wall_16().gram());
assert_eq!(bw.dim(), 16);
assert!(bw.is_even());
assert_eq!(bw.determinant(), 256);
assert_eq!(bw.minimum(), Some(4));
assert_eq!(bw.kissing_number(), Some(4320));
}
#[test]
fn clifford_barnes_wall_report_pins_the_group_order_boundary() {
let report = clifford_barnes_wall_16_report();
assert!(report.matches_construction_d);
assert_eq!(report.quadratic_phase_row_count, 12);
assert_eq!(report.coordinate_weight_row_count, 16);
assert_eq!(report.determinant(), 256);
assert_eq!(report.minimum(), Some(4));
assert_eq!(report.kissing_number(), Some(4320));
assert!(report.recorded_group_orders_are_consistent());
assert_eq!(
report.automorphism_group_order * report.automorphism_index_in_clifford_group,
report.full_clifford_group_order
);
}
#[test]
fn clifford_barnes_wall_16_invariants_display_renders_the_certificate() {
let report = clifford_barnes_wall_16_report();
assert_eq!(
report.to_string(),
"CliffordBarnesWall16Invariants(dim=16, det=256, matches_construction_d=true, aut_order=89181388800, full_clifford_order=178362777600, index=2)"
);
assert_eq!(report.display(), report.to_string());
}
}