wiki-mertens-function.rs

1.7 kB · rust · 56 lines

1use mrlycore::errors::Result;2use mrlyfig::{ink, plot, save, Board};3use mrlynum::factor::mobius_sieve;45const TOP: usize = 1000;67fn main() -> Result<()> {8    let mut board = Board::square();9    let frame = board.frame(0.08);10    let reach = (TOP as f64).sqrt() * 1.1;11    let across = |n: f64| frame.x + frame.w * (n - 1.0) / (TOP as f64 - 1.0);12    let up = |v: f64| frame.y + frame.h * (1.0 - (v + reach) / (2.0 * reach));1314    let mu = mobius_sieve(TOP);15    let mut walk: Vec<i64> = Vec::with_capacity(TOP);16    let mut sum = 0i64;17    for n in 1..=TOP {18        sum += i64::from(mu[n]);19        walk.push(sum);20    }2122    let mut over = Vec::with_capacity(TOP);23    let mut under = Vec::with_capacity(TOP);24    for n in 1..=TOP {25        let root = (n as f64).sqrt();26        over.push((across(n as f64), up(root)));27        under.push((across(n as f64), up(-root)));28    }29    board.polyline(&over, 2.6, ink::dim());30    board.polyline(&under, 2.6, ink::dim());31    board.segment(32        (frame.x, up(0.0)),33        (frame.x + frame.w, up(0.0)),34        1.6,35        ink::line(),36    );3738    let mut steps = Vec::with_capacity(2 * TOP);39    for (i, &m) in walk.iter().enumerate() {40        let n = (i + 1) as f64;41        steps.push((across(n), up(m as f64)));42        steps.push((across(n + 1.0), up(m as f64)));43    }44    board.polyline(&steps, 2.6, ink::blue());4546    plot::axis(&mut board, frame, ink::line());47    assert_eq!(walk.len(), TOP);48    assert_eq!(walk[999], 2);49    assert_eq!(walk.iter().copied().min(), Some(-12));50    assert!(walk51        .iter()52        .enumerate()53        .all(|(i, &m)| (m as f64).abs() <= ((i + 1) as f64).sqrt()));54    save("wiki-mertens-function", &board)?;55    Ok(())56}