wiki-euler-mascheroni-constant.rs

1.5 kB · rust · 46 lines

1use mrlycore::errors::Result;2use mrlyfig::{ink, plot, save, Board};3use mrlynum::series::{harmonic, EULER};45const TOP: usize = 30;6const SAMPLES: usize = 1600;78fn main() -> Result<()> {9    let mut board = Board::square();10    let frame = board.frame(0.08);11    let left = 1.0;12    let right = (TOP + 1) as f64;13    let peak = harmonic(TOP);14    let across = |x: f64| frame.x + frame.w * (x - left) / (right - left);15    let up = |v: f64| frame.y + frame.h * (1.0 - v / peak);1617    let strip = ink::fade(ink::blue(), 0.28);18    let width = frame.w / SAMPLES as f64;19    for k in 0..SAMPLES {20        let x = left + (right - left) * (k as f64 + 0.5) / SAMPLES as f64;21        let crest = up(harmonic(x.floor() as usize));22        let foot = up(x.ln());23        board.rect(across(x) - width, crest, width * 2.0, foot - crest, strip);24    }2526    let mut curve = Vec::with_capacity(SAMPLES + 1);27    for k in 0..=SAMPLES {28        let x = left + (right - left) * k as f64 / SAMPLES as f64;29        curve.push((across(x), up(x.ln())));30    }31    board.polyline(&curve, 3.4, ink::blue());3233    let mut stair = Vec::with_capacity(2 * TOP);34    for n in 1..=TOP {35        let v = harmonic(n);36        stair.push((across(n as f64), up(v)));37        stair.push((across((n + 1) as f64), up(v)));38    }39    board.polyline(&stair, 3.4, ink::yellow());4041    plot::axis(&mut board, frame, ink::line());42    assert_eq!(stair.len(), 2 * TOP);43    assert!((peak - (TOP as f64).ln() - EULER).abs() < 0.02);44    save("wiki-euler-mascheroni-constant", &board)?;45    Ok(())46}