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}