echo.rs
5.5 kB · rust · 157 lines
1use mrlycore::json::parse;2use mrlydemo::echo::*;3use mrlynum::design;45fn read(base: u32, mask: u32, depth: usize, subtract: bool) -> (Echo, mrlycore::Json) {6 let echo = echo_read(base, mask, depth, subtract).unwrap();7 let json = parse(&echo.read).unwrap();8 (echo, json)9}1011fn shown(value: &mrlycore::Json, places: usize) -> String {12 format!("{:.*}", places, value.as_f64().unwrap())13}1415fn census(base: u64, digits: &[u64], depth: usize) -> (i64, i64) {16 let values = design::elements(base, digits, depth);17 let running = design::meter(&design::mobius_of(&values));18 (19 running.last().copied().unwrap(),20 running.iter().map(|value| value.abs()).max().unwrap(),21 )22}2324#[test]25fn the_meter_reproduces_the_design_census() {26 let anchors = [27 (3u64, vec![0u64, 1], 14usize, (11i64, 105i64)),28 (3, vec![0, 1], 16, (149, 173)),29 (3, vec![0, 2], 14, (-10, 67)),30 (3, vec![1, 2], 8, (-31, 33)),31 ];32 for (base, digits, depth, want) in anchors {33 assert_eq!(34 census(base, &digits, depth),35 want,36 "lab/rs/mobius-designs and lab/py/design-meter read base {base} {digits:?} at depth {depth} as (M_F, max abs M_F) {want:?}"37 );38 }39 assert_eq!(design::size(&[0, 1], 14), 16383);40 assert_eq!(design::size(&[0, 1], 20), 1048575);41}4243#[test]44fn the_full_set_is_the_classical_mertens_control() {45 let full: Vec<u64> = (0..10).collect();46 let running = design::meter(&design::mobius_of(&design::elements(10, &full, 6)));47 assert_eq!(48 running.last().copied().unwrap(),49 212,50 "A084237 reads M(10^6) as 212 and mu(10^6) is zero"51 );52 let (_, page) = read(10, 0b11_1111_1111, 5, false);53 assert_eq!(page["count"], 99999);54 assert_eq!(page["last"], -48, "A084237 reads M(10^5) as -48");55 assert_eq!(page["peak"], 132);56 assert_eq!(shown(&page["alpha"], 6), "1.000000");57}5859#[test]60fn the_control_peaks_land_on_the_zeta_ordinates() {61 let (_, page) = read(10, 0b11_1111_1111, 5, false);62 assert_eq!(page["zeros"].as_array().unwrap().len(), 13);63 assert_eq!(page["lattice"].as_array().unwrap().len(), 20);64 assert_eq!(shown(&page["bin"], 6), "0.545618");65 assert_eq!(66 format!("{} {} {}", page["found"], page["hits"], page["lines"]),67 "13 10 6"68 );69 assert_eq!(shown(&page["chance"], 6), "0.253323");70 assert_eq!(shown(&page["chanceLines"], 6), "0.389727");71 let leading: Vec<String> = page["peaks"]72 .as_array()73 .unwrap()74 .iter()75 .take(5)76 .map(|row| shown(&row["gamma"], 4))77 .collect();78 assert_eq!(leading.join(" "), "30.5546 32.7371 25.0984 21.2791 14.1861");79 let (two, wide) = read(2, 0b11, 18, false);80 assert_eq!(81 format!("{} {} {}", wide["found"], wide["hits"], wide["lines"]),82 "13 10 0"83 );84 assert_eq!(wide["last"], 24);85 assert_eq!(wide["lattice"].as_array().unwrap().len(), 6);86 assert_eq!(two.gamma.len(), 2049);87}8889#[test]90fn the_full_set_is_its_own_echo() {91 let (page, full) = read(10, 0b11_1111_1111, 5, false);92 assert_eq!(shown(&full["share"], 6), "1.000000");93 assert_eq!(shown(&full["residual"], 6), "0.000000");94 assert_eq!(95 page.rest.iter().map(|v| v.abs()).fold(0.0f32, f32::max),96 0.097 );98 assert_eq!(page.echo, page.meter);99}100101#[test]102fn the_design_carries_the_zeros_through_its_echo() {103 let (page, meter) = read(10, 0b1_1111_1111, 5, false);104 assert_eq!(meter["count"], 59048);105 assert_eq!(meter["last"], 201);106 assert_eq!(meter["peak"], 268);107 assert_eq!(shown(&meter["alpha"], 6), "0.954243");108 assert_eq!(shown(&meter["span"], 6), "11.395132");109 assert_eq!(shown(&meter["bin"], 6), "0.551257");110 assert_eq!(111 format!("{} {} {}", meter["found"], meter["hits"], meter["lines"]),112 "5 5 2"113 );114 assert_eq!(shown(&meter["chance"], 6), "0.255941");115 assert_eq!(shown(&meter["chanceLines"], 6), "0.393755");116 assert_eq!(shown(&meter["peaks"][0]["gamma"], 4), "14.3327");117 assert_eq!(shown(&meter["peaks"][0]["score"], 4), "32.2266");118 assert_eq!(shown(&meter["peaks"][0]["zeta"], 4), "0.1980");119 assert_eq!(shown(&meter["share"], 6), "0.354137");120 assert_eq!(shown(&meter["residual"], 6), "0.967810");121 assert_eq!(shown(&meter["rate"], 6), "-0.022879");122 assert_eq!(page.logx.len(), 4096);123124 let (_, rest) = read(10, 0b1_1111_1111, 5, true);125 assert_eq!(126 format!("{} {}", rest["found"], rest["hits"]),127 "0 0",128 "the residual carries no peak once the echo is taken out"129 );130}131132#[test]133fn the_caps_hold_the_depth_and_the_sieve() {134 let caps = parse(&echo_caps(3, 0b011).unwrap()).unwrap();135 assert_eq!(136 format!("{} {} {}", caps["deepest"], caps["sieved"], caps["least"]),137 "17 15 3"138 );139 assert_eq!(shown(&caps["alpha"], 6), "0.630930");140 assert_eq!(caps["samples"], 4096);141 let (_, deep) = read(3, 0b011, 17, false);142 assert_eq!(deep["sieve"], false);143 assert_eq!(deep["share"], mrlycore::Json::Null);144 let (thin, shallow) = read(3, 0b011, 14, false);145 assert_eq!(deep["last"], 157);146 assert_eq!(shallow["last"], 11);147 assert_eq!(shallow["peak"], 105);148 assert_eq!(shallow["sieve"], true);149 assert_eq!(thin.echo.len(), 4096);150 assert_eq!(shown(&shallow["rate"], 6), "-0.184535");151152 assert!(echo_caps(11, 0b011).is_err());153 assert!(echo_caps(3, 0b1011).is_err());154 assert!(echo_caps(3, 0b001).is_err());155 assert!(echo_read(3, 0b011, 18, false).is_err());156 assert!(echo_read(3, 0b011, 2, false).is_err());157}