mathrand/
mathrand.rs

1// Copyright 2023 The rust-ggstd authors.
2// SPDX-License-Identifier: 0BSD
3
4use ggstd::image::{self, color, png, Image};
5use ggstd::math::rand;
6
7fn main() {
8    println!("global rand without seed:");
9    println!("{:x}", rand::int());
10    println!("{:x}", rand::int());
11    println!("{:x}", rand::int());
12    println!("{:x}", rand::int());
13
14    #[allow(deprecated)]
15    rand::seed(1);
16
17    println!();
18    println!("global rand with seed(1):");
19    println!("{:x}", rand::int());
20    println!("{:x}", rand::int());
21    println!("{:x}", rand::int());
22    println!("{:x}", rand::int());
23
24    println!();
25    println!("rand::Rand::new(rand::new_source(1)):");
26    let mut r = rand::Rand::new(rand::new_source(1));
27    println!("{:x}", r.int());
28    println!("{:x}", r.int());
29    println!("{:x}", r.int());
30    println!("{:x}", r.int());
31
32    println!();
33    println!("global rand::float64:");
34    println!("{}", rand::float64());
35    println!("{}", rand::float64());
36    println!("{}", rand::float64());
37    println!("{}", rand::float64());
38
39    println!();
40    println!("global rand::norm_float64:");
41    println!("{}", rand::norm_float64());
42    println!("{}", rand::norm_float64());
43    println!("{}", rand::norm_float64());
44    println!("{}", rand::norm_float64());
45
46    // create 3 png images with random dot placements
47    for seq in 0..3 {
48        random_dots_png(seq);
49    }
50
51    // showing that random numbers are uniformely distributed
52    uniformity_ints_png();
53    uniformity_floats_png();
54
55    // unless we want normal distribution
56    normal_distr_floats_png();
57}
58
59fn uniformity_ints_png() {
60    let width = 1000;
61    let samples = 100000;
62    let mut counters = vec![0_usize; width];
63    for _ in 0..samples {
64        let x = rand::intn(width as isize) as usize;
65        counters[x] += 1;
66    }
67    save_counters_to_png(width, width / 4, &counters, "uniform-ints.png");
68}
69
70fn uniformity_floats_png() {
71    let width = 1000;
72    let samples = 100000;
73    let mut counters = vec![0_usize; width];
74    for _ in 0..samples {
75        let x = (rand::float32() * width as f32) as usize;
76        counters[x] += 1;
77    }
78    save_counters_to_png(width, width / 4, &counters, "uniform-floats.png");
79}
80
81fn normal_distr_floats_png() {
82    let width = 1000;
83    let samples = 400000;
84    let mut counters = vec![0_usize; width];
85    for _ in 0..samples {
86        let x = (rand::norm_float64() * width as f64 / 3.0 + width as f64) / 2.0;
87        if x >= 0.0 && x < width as f64 {
88            counters[x as usize] += 1;
89        }
90    }
91    save_counters_to_png(width, width, &counters, "normal-distr-floats.png");
92}
93
94fn save_counters_to_png(width: usize, height: usize, counters: &[usize], file_name: &str) {
95    let mut img = white_image(width, height);
96    (0..width).for_each(|x| {
97        img.set(
98            x as isize,
99            height as isize - counters[x] as isize,
100            &color::BLACK,
101        );
102    });
103    let mut f = std::fs::File::create(file_name).unwrap();
104    png::encode(&mut f, &img).unwrap();
105}
106
107fn random_dots_png(number: usize) {
108    let size = 500;
109    let count = 5000;
110    let mut img = white_image(size, size);
111    for _ in 0..count {
112        img.set(
113            rand::intn(size as isize),
114            rand::intn(size as isize),
115            &color::BLACK,
116        );
117    }
118    let mut f = std::fs::File::create(format!("random-dots-{:02}.png", number)).unwrap();
119    png::encode(&mut f, &img).unwrap();
120}
121
122fn white_image(width: usize, height: usize) -> image::Img {
123    let mut img = image::Img::new_nrgba(&image::rect(0, 0, width as isize, height as isize));
124    for y in 0..height {
125        for x in 0..width {
126            img.set(x as isize, y as isize, &color::WHITE);
127        }
128    }
129    img
130}