sample.rs
2.2 kB · rust · 79 lines
1use super::Lattice;2use crate::core::error::Result;3use crate::math::bang::{code_to_corners, Code};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.29///30/// # Errors31///32/// Errors when the code is out of range for the dimension and base.33pub fn membership(code: u128, base: usize, dimension: usize) -> Result<Vec<bool>> {34 let corners = code_to_corners(Code::from(code), dimension, base)?;35 let total = base.pow(dimension as u32);36 let mut table = vec![false; total];37 for corner in corners {38 let mut idx = 0usize;39 for &d in &corner {40 idx = idx * base + d as usize;41 }42 table[idx] = true;43 }44 Ok(table)45}4647/// Folds residues into a base-q index of the truth table.48#[inline]49pub fn pack(residues: &[usize], base: usize) -> usize {50 let mut idx = 0usize;51 for &r in residues {52 idx = idx * base + r;53 }54 idx55}5657#[cfg(test)]58mod tests {59 use super::*;60 #[test]61 fn square_axes_are_pixel_centres() {62 let (a, b) = axes(4, Lattice::Square, 0);63 assert!((a[0] - 0.125).abs() < 1e-12);64 assert!((b[0] - 0.125).abs() < 1e-12);65 assert!((a[3] - 0.875).abs() < 1e-12);66 }67 #[test]68 fn membership_matches_corners() {69 let t = membership(1, 2, 2).unwrap();70 assert_eq!(t.len(), 4);71 assert!(t[pack(&[0, 0], 2)]);72 assert!(!t[pack(&[1, 1], 2)]);73 }74 #[test]75 fn full_code_is_all_true() {76 let t = membership(15, 2, 2).unwrap();77 assert!(t.iter().all(|&x| x));78 }79}