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}