rand

Random number generators and other randomness functionality

rand-badge

Example: Monte carlo integration

Use the rand crate to generate random samples and approximate $\int_{0}^{\pi} sin(x) dx$ using monte carlo.

Key concepts:

  • Creating thread-specific RNG
  • Generating real numbers over an interval
extern crate rand;

use rand::Rng;
use std::f32;

/// f(x) = sin(x)
fn f(x: f32) -> f32 {
    x.sin()
}

/// Compute integral of f(x) dx from a to b using n samples
fn monte_carlo(a: f32, b: f32, n: u32) -> f32 {
    // Generate numbers specific to this thread
    let mut rng = rand::thread_rng();

    let mut samples: Vec<f32> = Vec::new();

    // Generate n samples between [a, b)
    for _ in 0..n {
        samples.push(rng.gen_range(a, b)); 
    }

    // Find function values
    let mut sum = 0.;
    for x in samples {
        sum += f(x);
    }
    
    // Returns average of samples over interval
    (b - a) / n as f32 * sum
}

fn main() {
    println!("{}", monte_carlo(0., f32::consts::PI, 200_000));
}

Example: Generating random RGB colors

A trait is a language feature that tells the Rust compiler about functionality a type must provide.

Rust has the powerful ability to create traits for your own types. One example is rand::Rand. Any type that implements Rand can use the polymorphic function Rng::gen() to generate random types.

Key concepts:

  • Generating a random structure
extern crate rand;

use rand::Rng;
use rand::Rand;

#[derive(Debug)] // Allows us to print using {:?} format specifier
struct Color { // RGB Color struct
    r: f64,
    g: f64,
    b: f64,
}

// Implementing Rand for type Color
impl Rand for Color {
    fn rand<R: Rng>(rng: &mut R) -> Self {
        Color {r: rng.next_f64(), b: rng.next_f64(), g: rng.next_f64()}
    }
}

fn main() {
    // Generate a random Color and print to stdout
    let mut rng = rand::thread_rng();
    let c: Color = rng.gen();
    println!("{:?}", c);
}