weights.rs

6.1 kB · rust · 178 lines

1use mrlycore::colors::DARK;2use mrlydemo::bang::random_between;3use mrlydemo::weights::*;45const OBJECT: &str = "69";6const CARPET: &str = "495";7const MASSES: [f64; 3] = [3.0, 2.0, 3.0];89fn point(weights: &[f64], s: f64) -> Vec<f64> {10    weights_point(OBJECT, 3, 3, weights, s).unwrap()11}1213fn nine(values: &[f64]) -> String {14    values15        .iter()16        .map(|v| format!("{v:.9}"))17        .collect::<Vec<String>>()18        .join(" ")19}2021#[test]22fn the_corner_order_is_the_row_major_tile() {23    assert_eq!(24        weights_corners(OBJECT, 3, 3).unwrap(),25        vec![0, 0, 0, 2, 2, 0]26    );27    assert_eq!(weights_corners(CARPET, 3, 3).unwrap().len(), 16);28    assert!(weights_corners("0", 3, 3).is_err());29    assert!(weights_dims(OBJECT, 3, 3, &[1.0, 1.0]).is_err());30    assert!(weights_dims(OBJECT, 3, 3, &[1.0, 0.0, 1.0]).is_err());31}3233#[test]34fn the_pressure_is_the_research_pages_table() {35    assert_eq!(36        nine(&point(&MASSES, -2.0)),37        "-2.000000000 3.102620937 1.088179391 0.926262155"38    );39    assert_eq!(40        nine(&point(&MASSES, -1.0)),41        "-1.000000000 2.033103256 1.050962223 0.982141033"42    );43    assert_eq!(44        nine(&point(&MASSES, 0.0)),45        "0.000000000 1.000000000 1.015812676 1.000000000"46    );47    assert_eq!(48        nine(&point(&MASSES, 1.0)),49        "1.000000000 0.000000000 0.985056822 0.985056822"50    );51    assert_eq!(52        nine(&point(&MASSES, 2.0)),53        "2.000000000 -0.971990429 0.959892942 0.947795455"54    );55    assert_eq!(56        nine(&point(&MASSES, 3.0)),57        "3.000000000 -1.921688171 0.940411228 0.899545513"58    );59    let walk = weights_pressure(OBJECT, 3, 3, &MASSES, -2.0, 3.0, 6).unwrap();60    assert_eq!(walk.len(), 12);61    let read: Vec<String> = walk62        .chunks(2)63        .map(|pair| format!("{:.6}", pair[1]))64        .collect();65    assert_eq!(66        read.join(" "),67        "3.102621 2.033103 1.000000 0.000000 -0.971990 -1.921688"68    );69    assert_eq!(walk[0], -2.0);70    assert!(weights_pressure(OBJECT, 3, 3, &MASSES, 3.0, -2.0, 6).is_err());71}7273#[test]74fn the_local_dimensions_bracket_the_information_exponent() {75    assert_eq!(76        nine(&weights_dims(OBJECT, 3, 3, &MASSES).unwrap()),77        "0.892789261 1.261859507 0.985056822 1.000000000"78    );79    let seed = random_between(7, &[1; 8], &[32; 8]);80    let drawn: Vec<f64> = seed.iter().map(|n| f64::from(*n)).collect();81    assert!(drawn.iter().any(|w| *w != drawn[0]));82    let read = weights_dims(CARPET, 3, 3, &drawn).unwrap();83    assert!(read[0] < read[2] && read[2] < read[1], "{read:?}");84    assert!((read[3] - 8f64.ln() / 3f64.ln()).abs() < 1e-12);85}8687#[test]88fn equal_weights_reproduce_the_zero_one_design() {89    for (code, count) in [(OBJECT, 3.0), (CARPET, 8.0)] {90        let flat = vec![1.0; count as usize];91        let dimension = f64::ln(count) / 3f64.ln();92        for step in -6..=6 {93            let s = f64::from(step) / 2.0;94            let read = weights_point(code, 3, 3, &flat, s).unwrap();95            assert!((read[1] - (1.0 - s) * dimension).abs() < 1e-12, "{read:?}");96            assert!((read[2] - dimension).abs() < 1e-12);97        }98        assert_eq!(99            nine(&weights_point(code, 3, 3, &flat, 2.5).unwrap()),100            format!(101                "2.500000000 {:.9} {dimension:.9} {dimension:.9}",102                -1.5 * dimension103            )104        );105        let curve = weights_spectrum(code, 3, 3, &flat, 64).unwrap();106        assert!(curve107            .chunks(2)108            .all(|pair| (f64::from(pair[0]) - dimension).abs() < 1e-6109                && (f64::from(pair[1]) - dimension).abs() < 1e-6));110    }111}112113#[test]114fn the_masses_are_integers_over_the_denominator_to_the_level() {115    let field = weights_mass(OBJECT, 3, 2, 3, &MASSES).unwrap();116    assert_eq!(field.len(), 81);117    assert_eq!(field[0], 9.0 / 64.0);118    assert_eq!(field[2], 6.0 / 64.0);119    assert_eq!(field[8], 4.0 / 64.0);120    assert_eq!(field.iter().filter(|mass| **mass > 0.0).count(), 9);121    let counted: f64 = field.iter().map(|mass| f64::from(*mass) * 64.0).sum();122    assert!((counted - 64.0).abs() < 1e-12);123    let deep = weights_mass(OBJECT, 3, 6, 3, &MASSES).unwrap();124    assert_eq!(deep.len(), 531441);125    assert_eq!(deep.iter().filter(|mass| **mass > 0.0).count(), 729);126    let peak = deep.iter().copied().fold(f32::MIN, f32::max);127    let least = deep128        .iter()129        .copied()130        .filter(|mass| *mass > 0.0)131        .fold(f32::MAX, f32::min);132    assert!((f64::from(peak / least) - 1.5f64.powi(6)).abs() < 1e-5);133    assert!(weights_mass(OBJECT, 3, 7, 3, &MASSES).is_err());134    assert!(weights_mass(OBJECT, 3, 0, 3, &MASSES).is_err());135}136137#[test]138fn the_spectrum_spans_the_whole_range_under_the_transform() {139    let read = weights_dims(OBJECT, 3, 3, &MASSES).unwrap();140    let curve = weights_spectrum(OBJECT, 3, 3, &MASSES, 241).unwrap();141    assert_eq!(curve.len(), 482);142    assert!((f64::from(curve[0]) - read[1]).abs() < 1e-4);143    assert!((f64::from(curve[480]) - read[0]).abs() < 1e-4);144    assert_eq!(145        format!("{:.6},{:.6}", curve[0], curve[480]),146        "1.261856,0.892790"147    );148    for pair in curve.chunks(2) {149        let (alpha, f) = (f64::from(pair[0]), f64::from(pair[1]));150        assert!(151            alpha >= read[0] - 1e-6 && alpha <= read[1] + 1e-6,152            "{alpha}"153        );154        assert!(f <= read[3] + 1e-6 && f >= -1e-6, "{f}");155        for step in -8..=8 {156            let s = f64::from(step) / 2.0;157            let held = point(&MASSES, s);158            assert!(f <= alpha * s + held[1] + 1e-6, "{alpha} {f} at {s}");159        }160    }161    let held = point(&MASSES, 1.0);162    assert!((held[2] - held[3]).abs() < 1e-12);163}164165#[test]166fn the_painted_field_is_the_support_on_the_ground() {167    let sheet = weights_pixels(OBJECT, 3, 4, 3, &MASSES, 0.35).unwrap();168    assert_eq!((sheet.width, sheet.height), (81, 81));169    let ground = sheet170        .rgba171        .chunks(4)172        .filter(|c| c[..3] == [DARK.ground.r, DARK.ground.g, DARK.ground.b])173        .count();174    assert_eq!(ground, 81 * 81 - 81);175    let yellow = DARK.yellow;176    assert_eq!(&sheet.rgba[0..4], &[yellow.r, yellow.g, yellow.b, 255]);177    assert!(weights_pixels(OBJECT, 3, 4, 3, &MASSES, 0.0).is_err());178}