(index<- ) ./librand/lib.rs
git branch: * master 5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
modified: Fri May 9 13:02:28 2014
1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 /*!
12 Utilities for random number generation
13
14 The key functions are `random()` and `Rng::gen()`. These are polymorphic
15 and so can be used to generate any type that implements `Rand`. Type inference
16 means that often a simple call to `rand::random()` or `rng.gen()` will
17 suffice, but sometimes an annotation is required, e.g. `rand::random::<f64>()`.
18
19 See the `distributions` submodule for sampling random numbers from
20 distributions like normal and exponential.
21
22 # Task-local RNG
23
24 There is built-in support for a RNG associated with each task stored
25 in task-local storage. This RNG can be accessed via `task_rng`, or
26 used implicitly via `random`. This RNG is normally randomly seeded
27 from an operating-system source of randomness, e.g. `/dev/urandom` on
28 Unix systems, and will automatically reseed itself from this source
29 after generating 32 KiB of random data.
30
31 # Cryptographic security
32
33 An application that requires random numbers for cryptographic purposes
34 should prefer `OSRng`, which reads randomness from one of the source
35 that the operating system provides (e.g. `/dev/urandom` on
36 Unixes). The other random number generators provided by this module
37 are either known to be insecure (`XorShiftRng`), or are not verified
38 to be secure (`IsaacRng`, `Isaac64Rng` and `StdRng`).
39
40 *Note*: on Linux, `/dev/random` is more secure than `/dev/urandom`,
41 but it is a blocking RNG, and will wait until it has determined that
42 it has collected enough entropy to fulfill a request for random
43 data. It can be used with the `Rng` trait provided by this module by
44 opening the file and passing it to `reader::ReaderRng`. Since it
45 blocks, `/dev/random` should only be used to retrieve small amounts of
46 randomness.
47
48 # Examples
49
50 ```rust
51 use rand::Rng;
52
53 let mut rng = rand::task_rng();
54 if rng.gen() { // bool
55 println!("int: {}, uint: {}", rng.gen::<int>(), rng.gen::<uint>())
56 }
57 ```
58
59 ```rust
60 let tuple_ptr = rand::random::<Box<(f64, char)>>();
61 println!("{:?}", tuple_ptr)
62 ```
63 */
64
65 #![crate_id = "rand#0.11-pre"]
66 #![license = "MIT/ASL2"]
67 #![crate_type = "dylib"]
68 #![crate_type = "rlib"]
69 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
70 html_favicon_url = "http://www.rust-lang.org/favicon.ico",
71 html_root_url = "http://static.rust-lang.org/doc/master")]
72
73 #![feature(macro_rules, managed_boxes, phase)]
74 #![deny(deprecated_owned_vector)]
75
76 #[cfg(test)]
77 #[phase(syntax, link)] extern crate log;
78
79 use std::cast;
80 use std::io::IoResult;
81 use std::kinds::marker;
82 use std::strbuf::StrBuf;
83
84 pub use isaac::{IsaacRng, Isaac64Rng};
85 pub use os::OSRng;
86
87 use distributions::{Range, IndependentSample};
88 use distributions::range::SampleRange;
89
90 pub mod distributions;
91 pub mod isaac;
92 pub mod os;
93 pub mod reader;
94 pub mod reseeding;
95 mod rand_impls;
96
97 /// A type that can be randomly generated using an `Rng`.
98 pub trait Rand {
99 /// Generates a random instance of this type using the specified source of
100 /// randomness.
101 fn rand<R: Rng>(rng: &mut R) -> Self;
102 }
103
104 /// A random number generator.
105 pub trait Rng {
106 /// Return the next random u32.
107 ///
108 /// This rarely needs to be called directly, prefer `r.gen()` to
109 /// `r.next_u32()`.
110 // FIXME #7771: Should be implemented in terms of next_u64
111 fn next_u32(&mut self) -> u32;
112
113 /// Return the next random u64.
114 ///
115 /// By default this is implemented in terms of `next_u32`. An
116 /// implementation of this trait must provide at least one of
117 /// these two methods. Similarly to `next_u32`, this rarely needs
118 /// to be called directly, prefer `r.gen()` to `r.next_u64()`.
119 fn next_u64(&mut self) -> u64 {
120 (self.next_u32() as u64 << 32) | (self.next_u32() as u64)
121 }
122
123 /// Fill `dest` with random data.
124 ///
125 /// This has a default implementation in terms of `next_u64` and
126 /// `next_u32`, but should be overridden by implementations that
127 /// offer a more efficient solution than just calling those
128 /// methods repeatedly.
129 ///
130 /// This method does *not* have a requirement to bear any fixed
131 /// relationship to the other methods, for example, it does *not*
132 /// have to result in the same output as progressively filling
133 /// `dest` with `self.gen::<u8>()`, and any such behaviour should
134 /// not be relied upon.
135 ///
136 /// This method should guarantee that `dest` is entirely filled
137 /// with new data, and may fail if this is impossible
138 /// (e.g. reading past the end of a file that is being used as the
139 /// source of randomness).
140 ///
141 /// # Example
142 ///
143 /// ```rust
144 /// use rand::{task_rng, Rng};
145 ///
146 /// let mut v = [0u8, .. 13579];
147 /// task_rng().fill_bytes(v);
148 /// println!("{:?}", v);
149 /// ```
150 fn fill_bytes(&mut self, dest: &mut [u8]) {
151 // this could, in theory, be done by transmuting dest to a
152 // [u64], but this is (1) likely to be undefined behaviour for
153 // LLVM, (2) has to be very careful about alignment concerns,
154 // (3) adds more `unsafe` that needs to be checked, (4)
155 // probably doesn't give much performance gain if
156 // optimisations are on.
157 let mut count = 0;
158 let mut num = 0;
159 for byte in dest.mut_iter() {
160 if count == 0 {
161 // we could micro-optimise here by generating a u32 if
162 // we only need a few more bytes to fill the vector
163 // (i.e. at most 4).
164 num = self.next_u64();
165 count = 8;
166 }
167
168 *byte = (num & 0xff) as u8;
169 num >>= 8;
170 count -= 1;
171 }
172 }
173
174 /// Return a random value of a `Rand` type.
175 ///
176 /// # Example
177 ///
178 /// ```rust
179 /// use rand::{task_rng, Rng};
180 ///
181 /// let mut rng = task_rng();
182 /// let x: uint = rng.gen();
183 /// println!("{}", x);
184 /// println!("{:?}", rng.gen::<(f64, bool)>());
185 /// ```
186 #[inline(always)]
187 fn gen<T: Rand>(&mut self) -> T {
188 Rand::rand(self)
189 }
190
191 /// Return a random vector of the specified length.
192 ///
193 /// # Example
194 ///
195 /// ```rust
196 /// use rand::{task_rng, Rng};
197 ///
198 /// let mut rng = task_rng();
199 /// let x: Vec<uint> = rng.gen_vec(10);
200 /// println!("{}", x);
201 /// println!("{}", rng.gen_vec::<(f64, bool)>(5));
202 /// ```
203 fn gen_vec<T: Rand>(&mut self, len: uint) -> Vec<T> {
204 Vec::from_fn(len, |_| self.gen())
205 }
206
207 /// Generate a random value in the range [`low`, `high`). Fails if
208 /// `low >= high`.
209 ///
210 /// This is a convenience wrapper around
211 /// `distributions::Range`. If this function will be called
212 /// repeatedly with the same arguments, one should use `Range`, as
213 /// that will amortize the computations that allow for perfect
214 /// uniformity, as they only happen on initialization.
215 ///
216 /// # Example
217 ///
218 /// ```rust
219 /// use rand::{task_rng, Rng};
220 ///
221 /// let mut rng = task_rng();
222 /// let n: uint = rng.gen_range(0u, 10);
223 /// println!("{}", n);
224 /// let m: f64 = rng.gen_range(-40.0, 1.3e5);
225 /// println!("{}", m);
226 /// ```
227 fn gen_range<T: Ord + SampleRange>(&mut self, low: T, high: T) -> T {
228 assert!(low < high, "Rng.gen_range called with low >= high");
229 Range::new(low, high).ind_sample(self)
230 }
231
232 /// Return a bool with a 1 in n chance of true
233 ///
234 /// # Example
235 ///
236 /// ```rust
237 /// use rand::{task_rng, Rng};
238 ///
239 /// let mut rng = task_rng();
240 /// println!("{:b}", rng.gen_weighted_bool(3));
241 /// ```
242 fn gen_weighted_bool(&mut self, n: uint) -> bool {
243 n == 0 || self.gen_range(0, n) == 0
244 }
245
246 /// Return a random string of the specified length composed of
247 /// A-Z,a-z,0-9.
248 ///
249 /// # Example
250 ///
251 /// ```rust
252 /// use rand::{task_rng, Rng};
253 ///
254 /// println!("{}", task_rng().gen_ascii_str(10));
255 /// ```
256 fn gen_ascii_str(&mut self, len: uint) -> ~str {
257 static GEN_ASCII_STR_CHARSET: &'static [u8] = bytes!("ABCDEFGHIJKLMNOPQRSTUVWXYZ\
258 abcdefghijklmnopqrstuvwxyz\
259 0123456789");
260 let mut s = StrBuf::with_capacity(len);
261 for _ in range(0, len) {
262 s.push_char(self.choose(GEN_ASCII_STR_CHARSET) as char)
263 }
264 s.into_owned()
265 }
266
267 /// Choose an item randomly, failing if `values` is empty.
268 fn choose<T: Clone>(&mut self, values: &[T]) -> T {
269 self.choose_option(values).expect("Rng.choose: `values` is empty").clone()
270 }
271
272 /// Choose `Some(&item)` randomly, returning `None` if values is
273 /// empty.
274 ///
275 /// # Example
276 ///
277 /// ```rust
278 /// use rand::{task_rng, Rng};
279 ///
280 /// let choices = [1, 2, 4, 8, 16, 32];
281 /// let mut rng = task_rng();
282 /// println!("{:?}", rng.choose_option(choices));
283 /// println!("{:?}", rng.choose_option(choices.slice_to(0)));
284 /// ```
285 fn choose_option<'a, T>(&mut self, values: &'a [T]) -> Option<&'a T> {
286 if values.is_empty() {
287 None
288 } else {
289 Some(&values[self.gen_range(0u, values.len())])
290 }
291 }
292
293 /// Shuffle a mutable slice in place.
294 ///
295 /// # Example
296 ///
297 /// ```rust
298 /// use rand::{task_rng, Rng};
299 ///
300 /// let mut rng = task_rng();
301 /// let mut y = [1,2,3];
302 /// rng.shuffle(y);
303 /// println!("{}", y.as_slice());
304 /// rng.shuffle(y);
305 /// println!("{}", y.as_slice());
306 /// ```
307 fn shuffle<T>(&mut self, values: &mut [T]) {
308 let mut i = values.len();
309 while i >= 2u {
310 // invariant: elements with index >= i have been locked in place.
311 i -= 1u;
312 // lock element i in place.
313 values.swap(i, self.gen_range(0u, i + 1u));
314 }
315 }
316
317 /// Shuffle a mutable slice in place.
318 #[deprecated="renamed to `.shuffle`"]
319 fn shuffle_mut<T>(&mut self, values: &mut [T]) {
320 self.shuffle(values)
321 }
322
323 /// Randomly sample up to `n` elements from an iterator.
324 ///
325 /// # Example
326 ///
327 /// ```rust
328 /// use rand::{task_rng, Rng};
329 ///
330 /// let mut rng = task_rng();
331 /// let sample = rng.sample(range(1, 100), 5);
332 /// println!("{}", sample);
333 /// ```
334 fn sample<A, T: Iterator<A>>(&mut self, iter: T, n: uint) -> Vec<A> {
335 let mut reservoir = Vec::with_capacity(n);
336 for (i, elem) in iter.enumerate() {
337 if i < n {
338 reservoir.push(elem);
339 continue
340 }
341
342 let k = self.gen_range(0, i + 1);
343 if k < reservoir.len() {
344 *reservoir.get_mut(k) = elem
345 }
346 }
347 reservoir
348 }
349 }
350
351 /// A random number generator that can be explicitly seeded to produce
352 /// the same stream of randomness multiple times.
353 pub trait SeedableRng<Seed>: Rng {
354 /// Reseed an RNG with the given seed.
355 ///
356 /// # Example
357 ///
358 /// ```rust
359 /// use rand::{Rng, SeedableRng, StdRng};
360 ///
361 /// let mut rng: StdRng = SeedableRng::from_seed(&[1, 2, 3, 4]);
362 /// println!("{}", rng.gen::<f64>());
363 /// rng.reseed([5, 6, 7, 8]);
364 /// println!("{}", rng.gen::<f64>());
365 /// ```
366 fn reseed(&mut self, Seed);
367
368 /// Create a new RNG with the given seed.
369 ///
370 /// # Example
371 ///
372 /// ```rust
373 /// use rand::{Rng, SeedableRng, StdRng};
374 ///
375 /// let mut rng: StdRng = SeedableRng::from_seed(&[1, 2, 3, 4]);
376 /// println!("{}", rng.gen::<f64>());
377 /// ```
378 fn from_seed(seed: Seed) -> Self;
379 }
380
381 /// Create a random number generator with a default algorithm and seed.
382 ///
383 /// It returns the strongest `Rng` algorithm currently implemented in
384 /// pure Rust. If you require a specifically seeded `Rng` for
385 /// consistency over time you should pick one algorithm and create the
386 /// `Rng` yourself.
387 ///
388 /// This is a very expensive operation as it has to read randomness
389 /// from the operating system and use this in an expensive seeding
390 /// operation. If one does not require high performance generation of
391 /// random numbers, `task_rng` and/or `random` may be more
392 /// appropriate.
393 #[deprecated="use `task_rng` or `StdRng::new`"]
394 pub fn rng() -> StdRng {
395 StdRng::new().unwrap()
396 }
397
398 /// The standard RNG. This is designed to be efficient on the current
399 /// platform.
400 #[cfg(not(target_word_size="64"))]
401 pub struct StdRng { rng: IsaacRng }
402
403 /// The standard RNG. This is designed to be efficient on the current
404 /// platform.
405 #[cfg(target_word_size="64")]
406 pub struct StdRng { rng: Isaac64Rng }
407
408 impl StdRng {
409 /// Create a randomly seeded instance of `StdRng`.
410 ///
411 /// This is a very expensive operation as it has to read
412 /// randomness from the operating system and use this in an
413 /// expensive seeding operation. If one is only generating a small
414 /// number of random numbers, or doesn't need the utmost speed for
415 /// generating each number, `task_rng` and/or `random` may be more
416 /// appropriate.
417 ///
418 /// Reading the randomness from the OS may fail, and any error is
419 /// propagated via the `IoResult` return value.
420 #[cfg(not(target_word_size="64"))]
421 pub fn new() -> IoResult<StdRng> {
422 IsaacRng::new().map(|r| StdRng { rng: r })
423 }
424 /// Create a randomly seeded instance of `StdRng`.
425 ///
426 /// This is a very expensive operation as it has to read
427 /// randomness from the operating system and use this in an
428 /// expensive seeding operation. If one is only generating a small
429 /// number of random numbers, or doesn't need the utmost speed for
430 /// generating each number, `task_rng` and/or `random` may be more
431 /// appropriate.
432 ///
433 /// Reading the randomness from the OS may fail, and any error is
434 /// propagated via the `IoResult` return value.
435 #[cfg(target_word_size="64")]
436 pub fn new() -> IoResult<StdRng> {
437 Isaac64Rng::new().map(|r| StdRng { rng: r })
438 }
439 }
440
441 impl Rng for StdRng {
442 #[inline]
443 fn next_u32(&mut self) -> u32 {
444 self.rng.next_u32()
445 }
446
447 #[inline]
448 fn next_u64(&mut self) -> u64 {
449 self.rng.next_u64()
450 }
451 }
452
453 impl<'a> SeedableRng<&'a [uint]> for StdRng {
454 fn reseed(&mut self, seed: &'a [uint]) {
455 // the internal RNG can just be seeded from the above
456 // randomness.
457 self.rng.reseed(unsafe {cast::transmute(seed)})
458 }
459
460 fn from_seed(seed: &'a [uint]) -> StdRng {
461 StdRng { rng: SeedableRng::from_seed(unsafe {cast::transmute(seed)}) }
462 }
463 }
464
465 /// Create a weak random number generator with a default algorithm and seed.
466 ///
467 /// It returns the fastest `Rng` algorithm currently available in Rust without
468 /// consideration for cryptography or security. If you require a specifically
469 /// seeded `Rng` for consistency over time you should pick one algorithm and
470 /// create the `Rng` yourself.
471 ///
472 /// This will read randomness from the operating system to seed the
473 /// generator.
474 pub fn weak_rng() -> XorShiftRng {
475 match XorShiftRng::new() {
476 Ok(r) => r,
477 Err(e) => fail!("weak_rng: failed to create seeded RNG: {}", e)
478 }
479 }
480
481 /// An Xorshift[1] random number
482 /// generator.
483 ///
484 /// The Xorshift algorithm is not suitable for cryptographic purposes
485 /// but is very fast. If you do not know for sure that it fits your
486 /// requirements, use a more secure one such as `IsaacRng` or `OSRng`.
487 ///
488 /// [1]: Marsaglia, George (July 2003). ["Xorshift
489 /// RNGs"](http://www.jstatsoft.org/v08/i14/paper). *Journal of
490 /// Statistical Software*. Vol. 8 (Issue 14).
491 pub struct XorShiftRng {
492 x: u32,
493 y: u32,
494 z: u32,
495 w: u32,
496 }
497
498 impl Rng for XorShiftRng {
499 #[inline]
500 fn next_u32(&mut self) -> u32 {
501 let x = self.x;
502 let t = x ^ (x << 11);
503 self.x = self.y;
504 self.y = self.z;
505 self.z = self.w;
506 let w = self.w;
507 self.w = w ^ (w >> 19) ^ (t ^ (t >> 8));
508 self.w
509 }
510 }
511
512 impl SeedableRng<[u32, .. 4]> for XorShiftRng {
513 /// Reseed an XorShiftRng. This will fail if `seed` is entirely 0.
514 fn reseed(&mut self, seed: [u32, .. 4]) {
515 assert!(!seed.iter().all(|&x| x == 0),
516 "XorShiftRng.reseed called with an all zero seed.");
517
518 self.x = seed[0];
519 self.y = seed[1];
520 self.z = seed[2];
521 self.w = seed[3];
522 }
523
524 /// Create a new XorShiftRng. This will fail if `seed` is entirely 0.
525 fn from_seed(seed: [u32, .. 4]) -> XorShiftRng {
526 assert!(!seed.iter().all(|&x| x == 0),
527 "XorShiftRng::from_seed called with an all zero seed.");
528
529 XorShiftRng {
530 x: seed[0],
531 y: seed[1],
532 z: seed[2],
533 w: seed[3]
534 }
535 }
536 }
537
538 impl XorShiftRng {
539 /// Create an xor shift random number generator with a random seed.
540 pub fn new() -> IoResult<XorShiftRng> {
541 let mut s = [0u8, ..16];
542 let mut r = try!(OSRng::new());
543 loop {
544 r.fill_bytes(s);
545
546 if !s.iter().all(|x| *x == 0) {
547 break;
548 }
549 }
550 let s: [u32, ..4] = unsafe { cast::transmute(s) };
551 Ok(SeedableRng::from_seed(s))
552 }
553 }
554
555 /// Controls how the task-local RNG is reseeded.
556 struct TaskRngReseeder;
557
558 impl reseeding::Reseeder<StdRng> for TaskRngReseeder {
559 fn reseed(&mut self, rng: &mut StdRng) {
560 *rng = match StdRng::new() {
561 Ok(r) => r,
562 Err(e) => fail!("could not reseed task_rng: {}", e)
563 }
564 }
565 }
566 static TASK_RNG_RESEED_THRESHOLD: uint = 32_768;
567 type TaskRngInner = reseeding::ReseedingRng<StdRng, TaskRngReseeder>;
568 /// The task-local RNG.
569 pub struct TaskRng {
570 // This points into TLS (specifically, it points to the endpoint
571 // of a Box stored in TLS, to make it robust against TLS moving
572 // things internally) and so this struct cannot be legally
573 // transferred between tasks *and* it's unsafe to deallocate the
574 // RNG other than when a task is finished.
575 //
576 // The use of unsafe code here is OK if the invariants above are
577 // satisfied; and it allows us to avoid (unnecessarily) using a
578 // GC'd or RC'd pointer.
579 rng: *mut TaskRngInner,
580 marker: marker::NoSend,
581 }
582
583 /// Retrieve the lazily-initialized task-local random number
584 /// generator, seeded by the system. Intended to be used in method
585 /// chaining style, e.g. `task_rng().gen::<int>()`.
586 ///
587 /// The RNG provided will reseed itself from the operating system
588 /// after generating a certain amount of randomness.
589 ///
590 /// The internal RNG used is platform and architecture dependent, even
591 /// if the operating system random number generator is rigged to give
592 /// the same sequence always. If absolute consistency is required,
593 /// explicitly select an RNG, e.g. `IsaacRng` or `Isaac64Rng`.
594 pub fn task_rng() -> TaskRng {
595 // used to make space in TLS for a random number generator
596 local_data_key!(TASK_RNG_KEY: Box<TaskRngInner>)
597
598 match TASK_RNG_KEY.get() {
599 None => {
600 let r = match StdRng::new() {
601 Ok(r) => r,
602 Err(e) => fail!("could not initialize task_rng: {}", e)
603 };
604 let mut rng = box reseeding::ReseedingRng::new(r,
605 TASK_RNG_RESEED_THRESHOLD,
606 TaskRngReseeder);
607 let ptr = &mut *rng as *mut TaskRngInner;
608
609 TASK_RNG_KEY.replace(Some(rng));
610
611 TaskRng { rng: ptr, marker: marker::NoSend }
612 }
613 Some(rng) => TaskRng {
614 rng: &**rng as *_ as *mut TaskRngInner,
615 marker: marker::NoSend
616 }
617 }
618 }
619
620 impl Rng for TaskRng {
621 fn next_u32(&mut self) -> u32 {
622 unsafe { (*self.rng).next_u32() }
623 }
624
625 fn next_u64(&mut self) -> u64 {
626 unsafe { (*self.rng).next_u64() }
627 }
628
629 #[inline]
630 fn fill_bytes(&mut self, bytes: &mut [u8]) {
631 unsafe { (*self.rng).fill_bytes(bytes) }
632 }
633 }
634
635 /// Generate a random value using the task-local random number
636 /// generator.
637 ///
638 /// # Example
639 ///
640 /// ```rust
641 /// use rand::random;
642 ///
643 /// if random() {
644 /// let x = random();
645 /// println!("{}", 2u * x);
646 /// } else {
647 /// println!("{}", random::<f64>());
648 /// }
649 /// ```
650 #[inline]
651 pub fn random<T: Rand>() -> T {
652 task_rng().gen()
653 }
654
655 /// A wrapper for generating floating point numbers uniformly in the
656 /// open interval `(0,1)` (not including either endpoint).
657 ///
658 /// Use `Closed01` for the closed interval `[0,1]`, and the default
659 /// `Rand` implementation for `f32` and `f64` for the half-open
660 /// `[0,1)`.
661 ///
662 /// # Example
663 /// ```rust
664 /// use rand::{random, Open01};
665 ///
666 /// let Open01(val) = random::<Open01<f32>>();
667 /// println!("f32 from (0,1): {}", val);
668 /// ```
669 pub struct Open01<F>(pub F);
670
671 /// A wrapper for generating floating point numbers uniformly in the
672 /// closed interval `[0,1]` (including both endpoints).
673 ///
674 /// Use `Open01` for the closed interval `(0,1)`, and the default
675 /// `Rand` implementation of `f32` and `f64` for the half-open
676 /// `[0,1)`.
677 ///
678 /// # Example
679 /// ```rust
680 /// use rand::{random, Closed01};
681 ///
682 /// let Closed01(val) = random::<Closed01<f32>>();
683 /// println!("f32 from [0,1]: {}", val);
684 /// ```
685 pub struct Closed01<F>(pub F);
686
687 #[cfg(test)]
688 mod test {
689 use super::{Rng, task_rng, random, SeedableRng, StdRng};
690
691 struct ConstRng { i: u64 }
692 impl Rng for ConstRng {
693 fn next_u32(&mut self) -> u32 { self.i as u32 }
694 fn next_u64(&mut self) -> u64 { self.i }
695
696 // no fill_bytes on purpose
697 }
698
699 #[test]
700 fn test_fill_bytes_default() {
701 let mut r = ConstRng { i: 0x11_22_33_44_55_66_77_88 };
702
703 // check every remainder mod 8, both in small and big vectors.
704 let lengths = [0, 1, 2, 3, 4, 5, 6, 7,
705 80, 81, 82, 83, 84, 85, 86, 87];
706 for &n in lengths.iter() {
707 let mut v = Vec::from_elem(n, 0u8);
708 r.fill_bytes(v.as_mut_slice());
709
710 // use this to get nicer error messages.
711 for (i, &byte) in v.iter().enumerate() {
712 if byte == 0 {
713 fail!("byte {} of {} is zero", i, n)
714 }
715 }
716 }
717 }
718
719 #[test]
720 fn test_gen_range() {
721 let mut r = task_rng();
722 for _ in range(0, 1000) {
723 let a = r.gen_range(-3i, 42);
724 assert!(a >= -3 && a < 42);
725 assert_eq!(r.gen_range(0, 1), 0);
726 assert_eq!(r.gen_range(-12, -11), -12);
727 }
728
729 for _ in range(0, 1000) {
730 let a = r.gen_range(10, 42);
731 assert!(a >= 10 && a < 42);
732 assert_eq!(r.gen_range(0, 1), 0);
733 assert_eq!(r.gen_range(3_000_000u, 3_000_001), 3_000_000);
734 }
735
736 }
737
738 #[test]
739 #[should_fail]
740 fn test_gen_range_fail_int() {
741 let mut r = task_rng();
742 r.gen_range(5i, -2);
743 }
744
745 #[test]
746 #[should_fail]
747 fn test_gen_range_fail_uint() {
748 let mut r = task_rng();
749 r.gen_range(5u, 2u);
750 }
751
752 #[test]
753 fn test_gen_f64() {
754 let mut r = task_rng();
755 let a = r.gen::<f64>();
756 let b = r.gen::<f64>();
757 debug!("{:?}", (a, b));
758 }
759
760 #[test]
761 fn test_gen_weighted_bool() {
762 let mut r = task_rng();
763 assert_eq!(r.gen_weighted_bool(0u), true);
764 assert_eq!(r.gen_weighted_bool(1u), true);
765 }
766
767 #[test]
768 fn test_gen_ascii_str() {
769 let mut r = task_rng();
770 debug!("{}", r.gen_ascii_str(10u));
771 debug!("{}", r.gen_ascii_str(10u));
772 debug!("{}", r.gen_ascii_str(10u));
773 assert_eq!(r.gen_ascii_str(0u).len(), 0u);
774 assert_eq!(r.gen_ascii_str(10u).len(), 10u);
775 assert_eq!(r.gen_ascii_str(16u).len(), 16u);
776 }
777
778 #[test]
779 fn test_gen_vec() {
780 let mut r = task_rng();
781 assert_eq!(r.gen_vec::<u8>(0u).len(), 0u);
782 assert_eq!(r.gen_vec::<u8>(10u).len(), 10u);
783 assert_eq!(r.gen_vec::<f64>(16u).len(), 16u);
784 }
785
786 #[test]
787 fn test_choose() {
788 let mut r = task_rng();
789 assert_eq!(r.choose([1, 1, 1]), 1);
790 }
791
792 #[test]
793 fn test_choose_option() {
794 let mut r = task_rng();
795 let v: &[int] = &[];
796 assert!(r.choose_option(v).is_none());
797
798 let i = 1;
799 let v = [1,1,1];
800 assert_eq!(r.choose_option(v), Some(&i));
801 }
802
803 #[test]
804 fn test_shuffle() {
805 let mut r = task_rng();
806 let empty: &mut [int] = &mut [];
807 r.shuffle(empty);
808 let mut one = [1];
809 r.shuffle(one);
810 assert_eq!(one.as_slice(), &[1]);
811
812 let mut two = [1, 2];
813 r.shuffle(two);
814 assert!(two == [1, 2] || two == [2, 1]);
815
816 let mut x = [1, 1, 1];
817 r.shuffle(x);
818 assert_eq!(x.as_slice(), &[1, 1, 1]);
819 }
820
821 #[test]
822 fn test_task_rng() {
823 let mut r = task_rng();
824 r.gen::<int>();
825 let mut v = [1, 1, 1];
826 r.shuffle(v);
827 assert_eq!(v.as_slice(), &[1, 1, 1]);
828 assert_eq!(r.gen_range(0u, 1u), 0u);
829 }
830
831 #[test]
832 fn test_random() {
833 // not sure how to test this aside from just getting some values
834 let _n : uint = random();
835 let _f : f32 = random();
836 let _o : Option<Option<i8>> = random();
837 let _many : ((),
838 (Box<uint>,
839 @int,
840 Box<Option<Box<(@u32, Box<(@bool,)>)>>>),
841 (u8, i8, u16, i16, u32, i32, u64, i64),
842 (f32, (f64, (f64,)))) = random();
843 }
844
845 #[test]
846 fn test_sample() {
847 let min_val = 1;
848 let max_val = 100;
849
850 let mut r = task_rng();
851 let vals = range(min_val, max_val).collect::<Vec<int>>();
852 let small_sample = r.sample(vals.iter(), 5);
853 let large_sample = r.sample(vals.iter(), vals.len() + 5);
854
855 assert_eq!(small_sample.len(), 5);
856 assert_eq!(large_sample.len(), vals.len());
857
858 assert!(small_sample.iter().all(|e| {
859 **e >= min_val && **e <= max_val
860 }));
861 }
862
863 #[test]
864 fn test_std_rng_seeded() {
865 let s = task_rng().gen_vec::<uint>(256);
866 let mut ra: StdRng = SeedableRng::from_seed(s.as_slice());
867 let mut rb: StdRng = SeedableRng::from_seed(s.as_slice());
868 assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
869 }
870
871 #[test]
872 fn test_std_rng_reseed() {
873 let s = task_rng().gen_vec::<uint>(256);
874 let mut r: StdRng = SeedableRng::from_seed(s.as_slice());
875 let string1 = r.gen_ascii_str(100);
876
877 r.reseed(s.as_slice());
878
879 let string2 = r.gen_ascii_str(100);
880 assert_eq!(string1, string2);
881 }
882 }
883
884 #[cfg(test)]
885 static RAND_BENCH_N: u64 = 100;
886
887 #[cfg(test)]
888 mod bench {
889 extern crate test;
890 use self::test::Bencher;
891 use {XorShiftRng, StdRng, IsaacRng, Isaac64Rng, Rng, RAND_BENCH_N};
892 use std::mem::size_of;
893
894 #[bench]
895 fn rand_xorshift(b: &mut Bencher) {
896 let mut rng = XorShiftRng::new().unwrap();
897 b.iter(|| {
898 for _ in range(0, RAND_BENCH_N) {
899 rng.gen::<uint>();
900 }
901 });
902 b.bytes = size_of::<uint>() as u64 * RAND_BENCH_N;
903 }
904
905 #[bench]
906 fn rand_isaac(b: &mut Bencher) {
907 let mut rng = IsaacRng::new().unwrap();
908 b.iter(|| {
909 for _ in range(0, RAND_BENCH_N) {
910 rng.gen::<uint>();
911 }
912 });
913 b.bytes = size_of::<uint>() as u64 * RAND_BENCH_N;
914 }
915
916 #[bench]
917 fn rand_isaac64(b: &mut Bencher) {
918 let mut rng = Isaac64Rng::new().unwrap();
919 b.iter(|| {
920 for _ in range(0, RAND_BENCH_N) {
921 rng.gen::<uint>();
922 }
923 });
924 b.bytes = size_of::<uint>() as u64 * RAND_BENCH_N;
925 }
926
927 #[bench]
928 fn rand_std(b: &mut Bencher) {
929 let mut rng = StdRng::new().unwrap();
930 b.iter(|| {
931 for _ in range(0, RAND_BENCH_N) {
932 rng.gen::<uint>();
933 }
934 });
935 b.bytes = size_of::<uint>() as u64 * RAND_BENCH_N;
936 }
937
938 #[bench]
939 fn rand_shuffle_100(b: &mut Bencher) {
940 let mut rng = XorShiftRng::new().unwrap();
941 let x : &mut[uint] = [1,..100];
942 b.iter(|| {
943 rng.shuffle(x);
944 })
945 }
946 }
librand/lib.rs:104:31-104:31 -trait- definition:
/// A random number generator.
pub trait Rng {
/// Return the next random u32.
references:- 89librand/distributions/mod.rs:
librand/distributions/range.rs:
librand/distributions/gamma.rs:
librand/distributions/normal.rs:
librand/distributions/exponential.rs:
librand/isaac.rs:
librand/os.rs:
librand/reader.rs:
librand/reseeding.rs:
librand/rand_impls.rs:
librand/distributions/mod.rs:
librand/lib.rs:566:49-566:49 -NK_AS_STR_TODO- definition:
static TASK_RNG_RESEED_THRESHOLD: uint = 32_768;
type TaskRngInner = reseeding::ReseedingRng<StdRng, TaskRngReseeder>;
/// The task-local RNG.
references:- 4578: // GC'd or RC'd pointer.
579: rng: *mut TaskRngInner,
580: marker: marker::NoSend,
--
613: Some(rng) => TaskRng {
614: rng: &**rng as *_ as *mut TaskRngInner,
615: marker: marker::NoSend
librand/lib.rs:668:8-668:8 -struct- definition:
/// ```
pub struct Open01<F>(pub F);
/// A wrapper for generating floating point numbers uniformly in the
references:- 8librand/distributions/gamma.rs:
162: let v = v_cbrt * v_cbrt * v_cbrt;
163: let Open01(u) = rng.gen::<Open01<f64>>();
librand/distributions/normal.rs:
49: while -2.0 * y < x * x {
50: let Open01(x_) = rng.gen::<Open01<f64>>();
51: let Open01(y_) = rng.gen::<Open01<f64>>();
librand/rand_impls.rs:
118: }
119: impl Rand for Open01<$ty> {
120: #[inline]
121: fn rand<R: Rng>(rng: &mut R) -> Open01<$ty> {
122: // add a small amount (specifically 2 bits below
librand/lib.rs:352:50-352:50 -trait- definition:
/// the same stream of randomness multiple times.
pub trait SeedableRng<Seed>: Rng {
/// Reseed an RNG with the given seed.
references:- 7453: impl<'a> SeedableRng<&'a [uint]> for StdRng {
454: fn reseed(&mut self, seed: &'a [uint]) {
--
512: impl SeedableRng<[u32, .. 4]> for XorShiftRng {
513: /// Reseed an XorShiftRng. This will fail if `seed` is entirely 0.
librand/isaac.rs:
195: impl<'a> SeedableRng<&'a [u32]> for IsaacRng {
196: fn reseed(&mut self, seed: &'a [u32]) {
--
411: impl<'a> SeedableRng<&'a [u64]> for Isaac64Rng {
412: fn reseed(&mut self, seed: &'a [u64]) {
librand/reseeding.rs:
79: impl<S, R: SeedableRng<S>, Rsdr: Reseeder<R>>
80: SeedableRng<(Rsdr, S)> for ReseedingRng<R, Rsdr> {
81: fn reseed(&mut self, (rsdr, seed): (Rsdr, S)) {
librand/lib.rs:490:46-490:46 -struct- definition:
/// Statistical Software*. Vol. 8 (Issue 14).
pub struct XorShiftRng {
x: u32,
references:- 7529: XorShiftRng {
530: x: seed[0],
--
538: impl XorShiftRng {
539: /// Create an xor shift random number generator with a random seed.
540: pub fn new() -> IoResult<XorShiftRng> {
541: let mut s = [0u8, ..16];
librand/lib.rs:555:49-555:49 -struct- definition:
/// Controls how the task-local RNG is reseeded.
struct TaskRngReseeder;
impl reseeding::Reseeder<StdRng> for TaskRngReseeder {
references:- 2558: impl reseeding::Reseeder<StdRng> for TaskRngReseeder {
559: fn reseed(&mut self, rng: &mut StdRng) {
--
566: static TASK_RNG_RESEED_THRESHOLD: uint = 32_768;
567: type TaskRngInner = reseeding::ReseedingRng<StdRng, TaskRngReseeder>;
568: /// The task-local RNG.
librand/lib.rs:684:8-684:8 -struct- definition:
/// ```
pub struct Closed01<F>(pub F);
mod test {
references:- 4librand/rand_impls.rs:
130: #[inline]
131: fn rand<R: Rng>(rng: &mut R) -> Closed01<$ty> {
132: // divide by the maximum value of the numerator to
librand/lib.rs:405:30-405:30 -struct- definition:
pub struct StdRng { rng: Isaac64Rng }
impl StdRng {
/// Create a randomly seeded instance of `StdRng`.
references:- 11460: fn from_seed(seed: &'a [uint]) -> StdRng {
461: StdRng { rng: SeedableRng::from_seed(unsafe {cast::transmute(seed)}) }
462: }
--
566: static TASK_RNG_RESEED_THRESHOLD: uint = 32_768;
567: type TaskRngInner = reseeding::ReseedingRng<StdRng, TaskRngReseeder>;
568: /// The task-local RNG.
librand/lib.rs:97:58-97:58 -trait- definition:
/// A type that can be randomly generated using an `Rng`.
pub trait Rand {
/// Generates a random instance of this type using the specified source of
references:- 98librand/distributions/mod.rs:
librand/distributions/normal.rs:
librand/distributions/exponential.rs:
librand/rand_impls.rs:
librand/lib.rs:568:24-568:24 -struct- definition:
/// The task-local RNG.
pub struct TaskRng {
// This points into TLS (specifically, it points to the endpoint
references:- 4612: }
613: Some(rng) => TaskRng {
614: rng: &**rng as *_ as *mut TaskRngInner,
--
620: impl Rng for TaskRng {
621: fn next_u32(&mut self) -> u32 {