sample.rs
2.1 kB · rust · 75 lines
1use super::Lattice;2use mrlycore::errors::Result;3use mrlymath::bang::code_to_corners;45/// Returns the two lattice coordinates of each pixel centre along a row.6pub fn axes(size: usize, lattice: Lattice, row: usize) -> (Vec<f64>, Vec<f64>) {7 let inv = 1.0 / size as f64;8 let v = (row as f64 + 0.5) * inv;9 let mut a = Vec::with_capacity(size);10 let mut b = Vec::with_capacity(size);11 for col in 0..size {12 let u = (col as f64 + 0.5) * inv;13 match lattice {14 Lattice::Square => {15 a.push(u);16 b.push(v);17 }18 Lattice::Hex => {19 let sqrt3 = 3.0f64.sqrt();20 a.push(u - v / sqrt3);21 b.push(2.0 * v / sqrt3);22 }23 }24 }25 (a, b)26}2728/// Unpacks a code into its residue-corner truth table.29pub fn membership(code: u128, base: usize, dimension: usize) -> Result<Vec<bool>> {30 let corners = code_to_corners(code, dimension, base)?;31 let total = base.pow(dimension as u32);32 let mut table = vec![false; total];33 for corner in corners {34 let mut idx = 0usize;35 for &d in &corner {36 idx = idx * base + d as usize;37 }38 table[idx] = true;39 }40 Ok(table)41}4243/// Folds residues into a base-q index of the truth table.44#[inline]45pub fn pack(residues: &[usize], base: usize) -> usize {46 let mut idx = 0usize;47 for &r in residues {48 idx = idx * base + r;49 }50 idx51}5253#[cfg(test)]54mod tests {55 use super::*;56 #[test]57 fn square_axes_are_pixel_centres() {58 let (a, b) = axes(4, Lattice::Square, 0);59 assert!((a[0] - 0.125).abs() < 1e-12);60 assert!((b[0] - 0.125).abs() < 1e-12);61 assert!((a[3] - 0.875).abs() < 1e-12);62 }63 #[test]64 fn membership_matches_corners() {65 let t = membership(1, 2, 2).unwrap();66 assert_eq!(t.len(), 4);67 assert!(t[pack(&[0, 0], 2)]);68 assert!(!t[pack(&[1, 1], 2)]);69 }70 #[test]71 fn full_code_is_all_true() {72 let t = membership(15, 2, 2).unwrap();73 assert!(t.iter().all(|&x| x));74 }75}