MoosicBox Random
A basic random number generation library providing a unified interface for random number generation with optional seeding and distribution utilities.
Features
- Generic RNG Interface: Unified trait for different random number generators
- Thread-Safe Wrapper: Safe concurrent access to random number generators
- Basic Random Generation: Generate u32, i32, u64 values and fill byte arrays
- Distribution Support: Sample from various probability distributions using rand crate
- Optional Features: Conditional compilation for rand and simulator modules
- Custom Distributions: Non-uniform distribution utilities
Installation
Add this to your Cargo.toml
:
[dependencies]
moosicbox_random = "0.1.1"
Usage
Basic Random Generation
use moosicbox_random::{Rng, GenericRng};
fn main() {
let rng = Rng::new();
let random_u32 = rng.next_u32();
let random_i32 = rng.next_i32();
let random_u64 = rng.next_u64();
println!("Random u32: {}", random_u32);
println!("Random i32: {}", random_i32);
println!("Random u64: {}", random_u64);
let mut bytes = [0u8; 16];
rng.fill_bytes(&mut bytes);
println!("Random bytes: {:?}", bytes);
}
Seeded Random Generation
use moosicbox_random::Rng;
fn main() {
let rng = Rng::from_seed(Some(12345));
let value1 = rng.next_u32();
let value2 = rng.next_u32();
let rng2 = Rng::from_seed(Some(12345));
assert_eq!(value1, rng2.next_u32());
assert_eq!(value2, rng2.next_u32());
}
Distribution Sampling
use moosicbox_random::Rng;
use rand::distributions::{Normal, Uniform};
fn main() {
let rng = Rng::new();
let uniform_float: f64 = rng.random();
let uniform_int: i32 = rng.random();
let dice_roll = rng.gen_range(1..=6);
let percentage = rng.gen_range(0.0..100.0);
println!("Uniform float: {}", uniform_float);
println!("Uniform int: {}", uniform_int);
println!("Dice roll: {}", dice_roll);
println!("Percentage: {}", percentage);
let coin_flip = rng.gen_bool(0.5); let biased = rng.gen_ratio(3, 4);
println!("Coin flip: {}", coin_flip);
println!("Biased (75%): {}", biased);
}
Non-Uniform Distributions
use moosicbox_random::{Rng, non_uniform_distribute_f64, non_uniform_distribute_i32};
fn main() {
let rng = Rng::new();
let base_value = 0.5;
let power = 2.0;
let distributed = non_uniform_distribute_f64(base_value, power, &rng);
println!("Base value: {}", base_value);
println!("Distributed value: {}", distributed);
let int_distributed = non_uniform_distribute_i32(base_value, 3, &rng);
println!("Integer distributed: {}", int_distributed);
}
Custom Range Generation with Distribution
use moosicbox_random::{Rng, F64Convertible};
impl F64Convertible for f32 {
fn from_f64(f: f64) -> Self {
f as f32
}
fn into_f64(self) -> f64 {
self as f64
}
}
fn main() {
let rng = Rng::new();
let value: f32 = rng.gen_range_dist(0.0..1.0, 2.0);
let int_value: i32 = rng.gen_range_disti(1..100, 2);
println!("Distributed float: {}", value);
println!("Distributed int: {}", int_value);
}
Architecture
Core Traits
GenericRng
: Main trait defining random number generation interface
F64Convertible
: Trait for types that can convert to/from f64 for distributions
Thread Safety
The RngWrapper
provides thread-safe access to random number generators using Arc<Mutex<R>>
, allowing safe concurrent usage across multiple threads.
Optional Features
rand
: Enables integration with the rand
crate ecosystem
simulator
: Enables simulation-specific random number generation
Error Handling
The library provides basic error handling for random number generation failures:
fill_bytes
: Will panic if the underlying RNG fails
try_fill_bytes
: Returns Result<(), rand::Error>
for graceful error handling
Performance
The wrapper adds minimal overhead while providing thread safety. For high-performance scenarios where thread safety isn't required, consider using the underlying RNG directly.