research-mobius.rs

2.0 kB · rust · 70 lines

1use mrlycore::errors::Result;2use mrlyfig::{ink, plot, save, Board};3use mrlynum::factor::mobius;45const LENGTH: u32 = 16;6const STEPS: usize = 1 << LENGTH;7const DRAWN: usize = 4096;89fn spread(index: usize) -> usize {10    let mut value = 0usize;11    for bit in 0..LENGTH {12        if index >> bit & 1 == 1 {13            value += 4usize.pow(bit);14        }15    }16    value17}1819fn walks() -> (Vec<f64>, Vec<f64>) {20    let mut low = Vec::with_capacity(STEPS + 1);21    let mut high = Vec::with_capacity(STEPS + 1);22    let (mut a, mut b) = (0i64, 0i64);23    low.push(0.0);24    high.push(0.0);25    for index in 0..STEPS {26        let value = spread(index);27        a += mobius(value) as i64;28        b += mobius(2 * value) as i64;29        assert_eq!(b, -a);30        low.push(a as f64);31        high.push(b as f64);32    }33    (low, high)34}3536fn main() -> Result<()> {37    let (low, high) = walks();38    let reach = (STEPS as f64).sqrt();39    let peak = low.iter().fold(0.0f64, |m, v| m.max(v.abs()));40    assert!(peak < reach);4142    let mut board = Board::square();43    let frame = board.frame(0.08);44    let at = |index: f64, meter: f64| {45        (46            frame.x + frame.w * index / STEPS as f64,47            frame.y + frame.h * (0.5 - meter / (2.0 * reach)),48        )49    };50    board.segment(at(0.0, 0.0), at(STEPS as f64, 0.0), 1.6, ink::line());51    plot::axis(&mut board, frame, ink::line());52    for sign in [1.0f64, -1.0] {53        let envelope: Vec<(f64, f64)> = (0..=DRAWN)54            .map(|k| {55                let index = STEPS as f64 * k as f64 / DRAWN as f64;56                at(index, sign * index.sqrt())57            })58            .collect();59        board.polyline(&envelope, 2.0, ink::fade(ink::dim(), 0.75));60    }61    let stride = STEPS / DRAWN;62    for (walk, color) in [(&low, ink::blue()), (&high, ink::orange())] {63        let trace: Vec<(f64, f64)> = (0..=DRAWN)64            .map(|k| at((k * stride) as f64, walk[k * stride]))65            .collect();66        board.polyline(&trace, 2.4, color);67    }68    save("research-mobius", &board)?;69    Ok(())70}