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}