Skip to main content

scirs2_core/random/
quick.rs

1//! Quick and easy random generation for rapid prototyping
2//!
3//! This module provides the simplest possible interface for common random generation tasks.
4//! Perfect for quick scripts, prototypes, and when you just need "some random numbers fast".
5//!
6//! # Examples
7//!
8//! ```rust
9//! use scirs2_core::random::quick::*;
10//!
11//! // Generate random numbers with minimal setup
12//! let x = random_f64();              // Random number [0, 1)
13//! let n = random_int(1, 100);        // Random integer [1, 100]
14//! let b = random_bool();             // Random boolean
15//!
16//! // Quick arrays
17//! let data = random_vector(1000);    // 1000 random f64s
18//! let matrix = random_matrix(10, 10); // 10x10 random matrix
19//!
20//! // Quick sampling
21//! let items = vec!["A", "B", "C", "D"];
22//! let choice = pick_one(&items);      // Pick random item
23//! let sample = pick_many(&items, 2);  // Pick 2 random items
24//! ```
25
26use crate::random::{random_normal_array, random_uniform_array, thread_rng};
27use ::ndarray::{Array2, Ix2};
28use rand_distr::{Normal, Uniform};
29
30/// Generate a random f64 in [0, 1)
31pub fn random_f64() -> f64 {
32    crate::random::convenience::uniform()
33}
34
35/// Generate a random f32 in [0, 1)
36pub fn random_f32() -> f32 {
37    random_f64() as f32
38}
39
40/// Generate a random integer in the given range (inclusive)
41pub fn random_int(min: i64, max: i64) -> i64 {
42    crate::random::convenience::integer(min, max)
43}
44
45/// Generate a random usize in the given range (inclusive)
46pub fn random_usize(min: usize, max: usize) -> usize {
47    random_int(min as i64, max as i64) as usize
48}
49
50/// Generate a random boolean
51pub fn random_bool() -> bool {
52    crate::random::convenience::boolean()
53}
54
55/// Generate a random boolean with given probability of true
56pub fn random_bool_with_prob(prob: f64) -> bool {
57    random_f64() < prob
58}
59
60/// Generate a vector of random f64s in [0, 1)
61pub fn random_vector(size: usize) -> Vec<f64> {
62    let mut rng = thread_rng();
63    (0..size)
64        .map(|_| rng.sample(Uniform::new(0.0, 1.0).expect("Operation failed")))
65        .collect()
66}
67
68/// Generate a vector of random integers in the given range
69pub fn random_int_vector(size: usize, min: i64, max: i64) -> Vec<i64> {
70    (0..size).map(|_| random_int(min, max)).collect()
71}
72
73/// Generate a 2D matrix of random f64s in [0, 1)
74pub fn random_matrix(rows: usize, cols: usize) -> Array2<f64> {
75    let mut rng = thread_rng();
76    random_uniform_array(Ix2(rows, cols), &mut rng)
77}
78
79/// Generate a 2D matrix of random normal values
80pub fn random_normal_matrix(rows: usize, cols: usize, mean: f64, std: f64) -> Array2<f64> {
81    let mut rng = thread_rng();
82    random_normal_array(Ix2(rows, cols), mean, std, &mut rng)
83}
84
85/// Pick a random element from a slice
86pub fn pick_one<T>(items: &[T]) -> Option<&T> {
87    if items.is_empty() {
88        None
89    } else {
90        let index = random_usize(0, items.len() - 1);
91        Some(&items[index])
92    }
93}
94
95/// Pick multiple random elements from a slice (with replacement)
96pub fn pick_many<T: Clone>(items: &[T], count: usize) -> Vec<T> {
97    (0..count)
98        .filter_map(|_| pick_one(items))
99        .cloned()
100        .collect()
101}
102
103/// Shuffle a vector in place
104pub fn shuffle<T>(items: &mut Vec<T>) {
105    use crate::random::seq::SliceRandom;
106    let mut rng = crate::random::thread_rng();
107    items.shuffle(&mut rng);
108}
109
110/// Create a shuffled copy of a vector
111pub fn shuffled<T: Clone>(items: &[T]) -> Vec<T> {
112    let mut result = items.to_vec();
113    shuffle(&mut result);
114    result
115}
116
117/// Generate random text of given length (alphanumeric)
118pub fn random_text(length: usize) -> String {
119    const CHARS: &[u8] = b"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
120    (0..length)
121        .map(|_| {
122            let idx = random_usize(0, CHARS.len() - 1);
123            CHARS[idx] as char
124        })
125        .collect()
126}
127
128/// Generate a random hex string of given byte length
129pub fn random_hex(byte_length: usize) -> String {
130    (0..byte_length)
131        .map(|_| format!("{:02x}", random_usize(0, 255)))
132        .collect()
133}
134
135/// Coin flip - returns true or false with 50% probability
136pub fn coin_flip() -> bool {
137    random_bool()
138}
139
140/// Dice roll - returns 1-6
141pub fn dice_roll() -> i64 {
142    random_int(1, 6)
143}
144
145/// Roll multiple dice and return the sum
146pub fn dice_roll_sum(count: usize) -> i64 {
147    (0..count).map(|_| dice_roll()).sum()
148}
149
150/// Generate a random percentage (0.0 to 100.0)
151pub fn random_percentage() -> f64 {
152    random_f64() * 100.0
153}
154
155/// Random choice with weights (simplified interface)
156pub fn weighted_choice<T: Clone>(items: &[T], weights: &[f64]) -> Option<T> {
157    if items.len() != weights.len() || items.is_empty() {
158        return None;
159    }
160
161    let total: f64 = weights.iter().sum();
162    if total <= 0.0 {
163        return None;
164    }
165
166    let mut cumulative = 0.0;
167    let target = random_f64() * total;
168
169    for (item, &weight) in items.iter().zip(weights.iter()) {
170        cumulative += weight;
171        if target <= cumulative {
172            return Some(item.clone());
173        }
174    }
175
176    // Fallback to last item
177    items.last().cloned()
178}