1 // Copyright 2018 Developers of the Rand project.
2 // Copyright 2013-2017 The Rust Project Developers.
3 //
4 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5 // https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6 // <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
7 // option. This file may not be copied, modified, or distributed
8 // except according to those terms.
9 
10 //! Generating random samples from probability distributions.
11 //!
12 //! This module is the home of the [`Distribution`] trait and several of its
13 //! implementations. It is the workhorse behind some of the convenient
14 //! functionality of the [`Rng`] trait, including [`gen`], [`gen_range`] and
15 //! of course [`sample`].
16 //!
17 //! Abstractly, a [probability distribution] describes the probability of
18 //! occurance of each value in its sample space.
19 //!
20 //! More concretely, an implementation of `Distribution<T>` for type `X` is an
21 //! algorithm for choosing values from the sample space (a subset of `T`)
22 //! according to the distribution `X` represents, using an external source of
23 //! randomness (an RNG supplied to the `sample` function).
24 //!
25 //! A type `X` may implement `Distribution<T>` for multiple types `T`.
26 //! Any type implementing [`Distribution`] is stateless (i.e. immutable),
27 //! but it may have internal parameters set at construction time (for example,
28 //! [`Uniform`] allows specification of its sample space as a range within `T`).
29 //!
30 //!
31 //! # The `Standard` distribution
32 //!
33 //! The [`Standard`] distribution is important to mention. This is the
34 //! distribution used by [`Rng::gen()`] and represents the "default" way to
35 //! produce a random value for many different types, including most primitive
36 //! types, tuples, arrays, and a few derived types. See the documentation of
37 //! [`Standard`] for more details.
38 //!
39 //! Implementing `Distribution<T>` for [`Standard`] for user types `T` makes it
40 //! possible to generate type `T` with [`Rng::gen()`], and by extension also
41 //! with the [`random()`] function.
42 //!
43 //!
44 //! # Distribution to sample from a `Uniform` range
45 //!
46 //! The [`Uniform`] distribution is more flexible than [`Standard`], but also
47 //! more specialised: it supports fewer target types, but allows the sample
48 //! space to be specified as an arbitrary range within its target type `T`.
49 //! Both [`Standard`] and [`Uniform`] are in some sense uniform distributions.
50 //!
51 //! Values may be sampled from this distribution using [`Rng::gen_range`] or
52 //! by creating a distribution object with [`Uniform::new`],
53 //! [`Uniform::new_inclusive`] or `From<Range>`. When the range limits are not
54 //! known at compile time it is typically faster to reuse an existing
55 //! distribution object than to call [`Rng::gen_range`].
56 //!
57 //! User types `T` may also implement `Distribution<T>` for [`Uniform`],
58 //! although this is less straightforward than for [`Standard`] (see the
59 //! documentation in the [`uniform`] module. Doing so enables generation of
60 //! values of type `T` with  [`Rng::gen_range`].
61 //!
62 //!
63 //! # Other distributions
64 //!
65 //! There are surprisingly many ways to uniformly generate random floats. A
66 //! range between 0 and 1 is standard, but the exact bounds (open vs closed)
67 //! and accuracy differ. In addition to the [`Standard`] distribution Rand offers
68 //! [`Open01`] and [`OpenClosed01`]. See "Floating point implementation" section of
69 //! [`Standard`] documentation for more details.
70 //!
71 //! [`Alphanumeric`] is a simple distribution to sample random letters and
72 //! numbers of the `char` type; in contrast [`Standard`] may sample any valid
73 //! `char`.
74 //!
75 //! [`WeightedIndex`] can be used to do weighted sampling from a set of items,
76 //! such as from an array.
77 //!
78 //! # Non-uniform probability distributions
79 //!
80 //! Rand currently provides the following probability distributions:
81 //!
82 //! - Related to real-valued quantities that grow linearly
83 //!   (e.g. errors, offsets):
84 //!   - [`Normal`] distribution, and [`StandardNormal`] as a primitive
85 //!   - [`Cauchy`] distribution
86 //! - Related to Bernoulli trials (yes/no events, with a given probability):
87 //!   - [`Binomial`] distribution
88 //!   - [`Bernoulli`] distribution, similar to [`Rng::gen_bool`].
89 //! - Related to positive real-valued quantities that grow exponentially
90 //!   (e.g. prices, incomes, populations):
91 //!   - [`LogNormal`] distribution
92 //! - Related to the occurrence of independent events at a given rate:
93 //!   - [`Pareto`] distribution
94 //!   - [`Poisson`] distribution
95 //!   - [`Exp`]onential distribution, and [`Exp1`] as a primitive
96 //!   - [`Weibull`] distribution
97 //! - Gamma and derived distributions:
98 //!   - [`Gamma`] distribution
99 //!   - [`ChiSquared`] distribution
100 //!   - [`StudentT`] distribution
101 //!   - [`FisherF`] distribution
102 //! - Triangular distribution:
103 //!   - [`Beta`] distribution
104 //!   - [`Triangular`] distribution
105 //! - Multivariate probability distributions
106 //!   - [`Dirichlet`] distribution
107 //!   - [`UnitSphereSurface`] distribution
108 //!   - [`UnitCircle`] distribution
109 //!
110 //! # Examples
111 //!
112 //! Sampling from a distribution:
113 //!
114 //! ```
115 //! use rand::{thread_rng, Rng};
116 //! use rand::distributions::Exp;
117 //!
118 //! let exp = Exp::new(2.0);
119 //! let v = thread_rng().sample(exp);
120 //! println!("{} is from an Exp(2) distribution", v);
121 //! ```
122 //!
123 //! Implementing the [`Standard`] distribution for a user type:
124 //!
125 //! ```
126 //! # #![allow(dead_code)]
127 //! use rand::Rng;
128 //! use rand::distributions::{Distribution, Standard};
129 //!
130 //! struct MyF32 {
131 //!     x: f32,
132 //! }
133 //!
134 //! impl Distribution<MyF32> for Standard {
135 //!     fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> MyF32 {
136 //!         MyF32 { x: rng.gen() }
137 //!     }
138 //! }
139 //! ```
140 //!
141 //!
142 //! [probability distribution]: https://en.wikipedia.org/wiki/Probability_distribution
143 //! [`gen_range`]: Rng::gen_range
144 //! [`gen`]: Rng::gen
145 //! [`sample`]: Rng::sample
146 //! [`new_inclusive`]: Uniform::new_inclusive
147 //! [`Alphanumeric`]: distributions::Alphanumeric
148 //! [`Bernoulli`]: distributions::Bernoulli
149 //! [`Beta`]: distributions::Beta
150 //! [`Binomial`]: distributions::Binomial
151 //! [`Cauchy`]: distributions::Cauchy
152 //! [`ChiSquared`]: distributions::ChiSquared
153 //! [`Dirichlet`]: distributions::Dirichlet
154 //! [`Exp`]: distributions::Exp
155 //! [`Exp1`]: distributions::Exp1
156 //! [`FisherF`]: distributions::FisherF
157 //! [`Gamma`]: distributions::Gamma
158 //! [`LogNormal`]: distributions::LogNormal
159 //! [`Normal`]: distributions::Normal
160 //! [`Open01`]: distributions::Open01
161 //! [`OpenClosed01`]: distributions::OpenClosed01
162 //! [`Pareto`]: distributions::Pareto
163 //! [`Poisson`]: distributions::Poisson
164 //! [`Standard`]: distributions::Standard
165 //! [`StandardNormal`]: distributions::StandardNormal
166 //! [`StudentT`]: distributions::StudentT
167 //! [`Triangular`]: distributions::Triangular
168 //! [`Uniform`]: distributions::Uniform
169 //! [`Uniform::new`]: distributions::Uniform::new
170 //! [`Uniform::new_inclusive`]: distributions::Uniform::new_inclusive
171 //! [`UnitSphereSurface`]: distributions::UnitSphereSurface
172 //! [`UnitCircle`]: distributions::UnitCircle
173 //! [`Weibull`]: distributions::Weibull
174 //! [`WeightedIndex`]: distributions::WeightedIndex
175 
176 #[cfg(any(rustc_1_26, features="nightly"))]
177 use core::iter;
178 use Rng;
179 
180 pub use self::other::Alphanumeric;
181 #[doc(inline)] pub use self::uniform::Uniform;
182 pub use self::float::{OpenClosed01, Open01};
183 pub use self::bernoulli::Bernoulli;
184 #[cfg(feature="alloc")] pub use self::weighted::{WeightedIndex, WeightedError};
185 #[cfg(feature="std")] pub use self::unit_sphere::UnitSphereSurface;
186 #[cfg(feature="std")] pub use self::unit_circle::UnitCircle;
187 #[cfg(feature="std")] pub use self::gamma::{Gamma, ChiSquared, FisherF,
188     StudentT, Beta};
189 #[cfg(feature="std")] pub use self::normal::{Normal, LogNormal, StandardNormal};
190 #[cfg(feature="std")] pub use self::exponential::{Exp, Exp1};
191 #[cfg(feature="std")] pub use self::pareto::Pareto;
192 #[cfg(feature="std")] pub use self::poisson::Poisson;
193 #[cfg(feature="std")] pub use self::binomial::Binomial;
194 #[cfg(feature="std")] pub use self::cauchy::Cauchy;
195 #[cfg(feature="std")] pub use self::dirichlet::Dirichlet;
196 #[cfg(feature="std")] pub use self::triangular::Triangular;
197 #[cfg(feature="std")] pub use self::weibull::Weibull;
198 
199 pub mod uniform;
200 mod bernoulli;
201 #[cfg(feature="alloc")] mod weighted;
202 #[cfg(feature="std")] mod unit_sphere;
203 #[cfg(feature="std")] mod unit_circle;
204 #[cfg(feature="std")] mod gamma;
205 #[cfg(feature="std")] mod normal;
206 #[cfg(feature="std")] mod exponential;
207 #[cfg(feature="std")] mod pareto;
208 #[cfg(feature="std")] mod poisson;
209 #[cfg(feature="std")] mod binomial;
210 #[cfg(feature="std")] mod cauchy;
211 #[cfg(feature="std")] mod dirichlet;
212 #[cfg(feature="std")] mod triangular;
213 #[cfg(feature="std")] mod weibull;
214 
215 mod float;
216 mod integer;
217 mod other;
218 mod utils;
219 #[cfg(feature="std")] mod ziggurat_tables;
220 
221 /// Types (distributions) that can be used to create a random instance of `T`.
222 ///
223 /// It is possible to sample from a distribution through both the
224 /// `Distribution` and [`Rng`] traits, via `distr.sample(&mut rng)` and
225 /// `rng.sample(distr)`. They also both offer the [`sample_iter`] method, which
226 /// produces an iterator that samples from the distribution.
227 ///
228 /// All implementations are expected to be immutable; this has the significant
229 /// advantage of not needing to consider thread safety, and for most
230 /// distributions efficient state-less sampling algorithms are available.
231 ///
232 /// [`sample_iter`]: Distribution::method.sample_iter
233 pub trait Distribution<T> {
234     /// Generate a random value of `T`, using `rng` as the source of randomness.
sample<R: Rng + ?Sized>(&self, rng: &mut R) -> T235     fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> T;
236 
237     /// Create an iterator that generates random values of `T`, using `rng` as
238     /// the source of randomness.
239     ///
240     /// # Example
241     ///
242     /// ```
243     /// use rand::thread_rng;
244     /// use rand::distributions::{Distribution, Alphanumeric, Uniform, Standard};
245     ///
246     /// let mut rng = thread_rng();
247     ///
248     /// // Vec of 16 x f32:
249     /// let v: Vec<f32> = Standard.sample_iter(&mut rng).take(16).collect();
250     ///
251     /// // String:
252     /// let s: String = Alphanumeric.sample_iter(&mut rng).take(7).collect();
253     ///
254     /// // Dice-rolling:
255     /// let die_range = Uniform::new_inclusive(1, 6);
256     /// let mut roll_die = die_range.sample_iter(&mut rng);
257     /// while roll_die.next().unwrap() != 6 {
258     ///     println!("Not a 6; rolling again!");
259     /// }
260     /// ```
sample_iter<'a, R>(&'a self, rng: &'a mut R) -> DistIter<'a, Self, R, T> where Self: Sized, R: Rng261     fn sample_iter<'a, R>(&'a self, rng: &'a mut R) -> DistIter<'a, Self, R, T>
262         where Self: Sized, R: Rng
263     {
264         DistIter {
265             distr: self,
266             rng: rng,
267             phantom: ::core::marker::PhantomData,
268         }
269     }
270 }
271 
272 impl<'a, T, D: Distribution<T>> Distribution<T> for &'a D {
sample<R: Rng + ?Sized>(&self, rng: &mut R) -> T273     fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> T {
274         (*self).sample(rng)
275     }
276 }
277 
278 
279 /// An iterator that generates random values of `T` with distribution `D`,
280 /// using `R` as the source of randomness.
281 ///
282 /// This `struct` is created by the [`sample_iter`] method on [`Distribution`].
283 /// See its documentation for more.
284 ///
285 /// [`sample_iter`]: Distribution::sample_iter
286 #[derive(Debug)]
287 pub struct DistIter<'a, D: 'a, R: 'a, T> {
288     distr: &'a D,
289     rng: &'a mut R,
290     phantom: ::core::marker::PhantomData<T>,
291 }
292 
293 impl<'a, D, R, T> Iterator for DistIter<'a, D, R, T>
294     where D: Distribution<T>, R: Rng + 'a
295 {
296     type Item = T;
297 
298     #[inline(always)]
next(&mut self) -> Option<T>299     fn next(&mut self) -> Option<T> {
300         Some(self.distr.sample(self.rng))
301     }
302 
size_hint(&self) -> (usize, Option<usize>)303     fn size_hint(&self) -> (usize, Option<usize>) {
304         (usize::max_value(), None)
305     }
306 }
307 
308 #[cfg(rustc_1_26)]
309 impl<'a, D, R, T> iter::FusedIterator for DistIter<'a, D, R, T>
310     where D: Distribution<T>, R: Rng + 'a {}
311 
312 #[cfg(features = "nightly")]
313 impl<'a, D, R, T> iter::TrustedLen for DistIter<'a, D, R, T>
314     where D: Distribution<T>, R: Rng + 'a {}
315 
316 
317 /// A generic random value distribution, implemented for many primitive types.
318 /// Usually generates values with a numerically uniform distribution, and with a
319 /// range appropriate to the type.
320 ///
321 /// ## Built-in Implementations
322 ///
323 /// Assuming the provided `Rng` is well-behaved, these implementations
324 /// generate values with the following ranges and distributions:
325 ///
326 /// * Integers (`i32`, `u32`, `isize`, `usize`, etc.): Uniformly distributed
327 ///   over all values of the type.
328 /// * `char`: Uniformly distributed over all Unicode scalar values, i.e. all
329 ///   code points in the range `0...0x10_FFFF`, except for the range
330 ///   `0xD800...0xDFFF` (the surrogate code points). This includes
331 ///   unassigned/reserved code points.
332 /// * `bool`: Generates `false` or `true`, each with probability 0.5.
333 /// * Floating point types (`f32` and `f64`): Uniformly distributed in the
334 ///   half-open range `[0, 1)`. See notes below.
335 /// * Wrapping integers (`Wrapping<T>`), besides the type identical to their
336 ///   normal integer variants.
337 ///
338 /// The following aggregate types also implement the distribution `Standard` as
339 /// long as their component types implement it:
340 ///
341 /// * Tuples and arrays: Each element of the tuple or array is generated
342 ///   independently, using the `Standard` distribution recursively.
343 /// * `Option<T>` where `Standard` is implemented for `T`: Returns `None` with
344 ///   probability 0.5; otherwise generates a random `x: T` and returns `Some(x)`.
345 ///
346 /// # Example
347 /// ```
348 /// use rand::prelude::*;
349 /// use rand::distributions::Standard;
350 ///
351 /// let val: f32 = SmallRng::from_entropy().sample(Standard);
352 /// println!("f32 from [0, 1): {}", val);
353 /// ```
354 ///
355 /// # Floating point implementation
356 /// The floating point implementations for `Standard` generate a random value in
357 /// the half-open interval `[0, 1)`, i.e. including 0 but not 1.
358 ///
359 /// All values that can be generated are of the form `n * ε/2`. For `f32`
360 /// the 23 most significant random bits of a `u32` are used and for `f64` the
361 /// 53 most significant bits of a `u64` are used. The conversion uses the
362 /// multiplicative method: `(rng.gen::<$uty>() >> N) as $ty * (ε/2)`.
363 ///
364 /// See also: [`Open01`] which samples from `(0, 1)`, [`OpenClosed01`] which
365 /// samples from `(0, 1]` and `Rng::gen_range(0, 1)` which also samples from
366 /// `[0, 1)`. Note that `Open01` and `gen_range` (which uses [`Uniform`]) use
367 /// transmute-based methods which yield 1 bit less precision but may perform
368 /// faster on some architectures (on modern Intel CPUs all methods have
369 /// approximately equal performance).
370 ///
371 /// [`Uniform`]: uniform::Uniform
372 #[derive(Clone, Copy, Debug)]
373 pub struct Standard;
374 
375 
376 /// A value with a particular weight for use with `WeightedChoice`.
377 #[deprecated(since="0.6.0", note="use WeightedIndex instead")]
378 #[allow(deprecated)]
379 #[derive(Copy, Clone, Debug)]
380 pub struct Weighted<T> {
381     /// The numerical weight of this item
382     pub weight: u32,
383     /// The actual item which is being weighted
384     pub item: T,
385 }
386 
387 /// A distribution that selects from a finite collection of weighted items.
388 ///
389 /// Deprecated: use [`WeightedIndex`] instead.
390 ///
391 /// [`WeightedIndex`]: WeightedIndex
392 #[deprecated(since="0.6.0", note="use WeightedIndex instead")]
393 #[allow(deprecated)]
394 #[derive(Debug)]
395 pub struct WeightedChoice<'a, T:'a> {
396     items: &'a mut [Weighted<T>],
397     weight_range: Uniform<u32>,
398 }
399 
400 #[deprecated(since="0.6.0", note="use WeightedIndex instead")]
401 #[allow(deprecated)]
402 impl<'a, T: Clone> WeightedChoice<'a, T> {
403     /// Create a new `WeightedChoice`.
404     ///
405     /// Panics if:
406     ///
407     /// - `items` is empty
408     /// - the total weight is 0
409     /// - the total weight is larger than a `u32` can contain.
new(items: &'a mut [Weighted<T>]) -> WeightedChoice<'a, T>410     pub fn new(items: &'a mut [Weighted<T>]) -> WeightedChoice<'a, T> {
411         // strictly speaking, this is subsumed by the total weight == 0 case
412         assert!(!items.is_empty(), "WeightedChoice::new called with no items");
413 
414         let mut running_total: u32 = 0;
415 
416         // we convert the list from individual weights to cumulative
417         // weights so we can binary search. This *could* drop elements
418         // with weight == 0 as an optimisation.
419         for item in items.iter_mut() {
420             running_total = match running_total.checked_add(item.weight) {
421                 Some(n) => n,
422                 None => panic!("WeightedChoice::new called with a total weight \
423                                larger than a u32 can contain")
424             };
425 
426             item.weight = running_total;
427         }
428         assert!(running_total != 0, "WeightedChoice::new called with a total weight of 0");
429 
430         WeightedChoice {
431             items,
432             // we're likely to be generating numbers in this range
433             // relatively often, so might as well cache it
434             weight_range: Uniform::new(0, running_total)
435         }
436     }
437 }
438 
439 #[deprecated(since="0.6.0", note="use WeightedIndex instead")]
440 #[allow(deprecated)]
441 impl<'a, T: Clone> Distribution<T> for WeightedChoice<'a, T> {
sample<R: Rng + ?Sized>(&self, rng: &mut R) -> T442     fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> T {
443         // we want to find the first element that has cumulative
444         // weight > sample_weight, which we do by binary since the
445         // cumulative weights of self.items are sorted.
446 
447         // choose a weight in [0, total_weight)
448         let sample_weight = self.weight_range.sample(rng);
449 
450         // short circuit when it's the first item
451         if sample_weight < self.items[0].weight {
452             return self.items[0].item.clone();
453         }
454 
455         let mut idx = 0;
456         let mut modifier = self.items.len();
457 
458         // now we know that every possibility has an element to the
459         // left, so we can just search for the last element that has
460         // cumulative weight <= sample_weight, then the next one will
461         // be "it". (Note that this greatest element will never be the
462         // last element of the vector, since sample_weight is chosen
463         // in [0, total_weight) and the cumulative weight of the last
464         // one is exactly the total weight.)
465         while modifier > 1 {
466             let i = idx + modifier / 2;
467             if self.items[i].weight <= sample_weight {
468                 // we're small, so look to the right, but allow this
469                 // exact element still.
470                 idx = i;
471                 // we need the `/ 2` to round up otherwise we'll drop
472                 // the trailing elements when `modifier` is odd.
473                 modifier += 1;
474             } else {
475                 // otherwise we're too big, so go left. (i.e. do
476                 // nothing)
477             }
478             modifier /= 2;
479         }
480         self.items[idx + 1].item.clone()
481     }
482 }
483 
484 #[cfg(test)]
485 mod tests {
486     use rngs::mock::StepRng;
487     #[allow(deprecated)]
488     use super::{WeightedChoice, Weighted, Distribution};
489 
490     #[test]
491     #[allow(deprecated)]
test_weighted_choice()492     fn test_weighted_choice() {
493         // this makes assumptions about the internal implementation of
494         // WeightedChoice. It may fail when the implementation in
495         // `distributions::uniform::UniformInt` changes.
496 
497         macro_rules! t {
498             ($items:expr, $expected:expr) => {{
499                 let mut items = $items;
500                 let mut total_weight = 0;
501                 for item in &items { total_weight += item.weight; }
502 
503                 let wc = WeightedChoice::new(&mut items);
504                 let expected = $expected;
505 
506                 // Use extremely large steps between the random numbers, because
507                 // we test with small ranges and `UniformInt` is designed to prefer
508                 // the most significant bits.
509                 let mut rng = StepRng::new(0, !0 / (total_weight as u64));
510 
511                 for &val in expected.iter() {
512                     assert_eq!(wc.sample(&mut rng), val)
513                 }
514             }}
515         }
516 
517         t!([Weighted { weight: 1, item: 10}], [10]);
518 
519         // skip some
520         t!([Weighted { weight: 0, item: 20},
521             Weighted { weight: 2, item: 21},
522             Weighted { weight: 0, item: 22},
523             Weighted { weight: 1, item: 23}],
524            [21, 21, 23]);
525 
526         // different weights
527         t!([Weighted { weight: 4, item: 30},
528             Weighted { weight: 3, item: 31}],
529            [30, 31, 30, 31, 30, 31, 30]);
530 
531         // check that we're binary searching
532         // correctly with some vectors of odd
533         // length.
534         t!([Weighted { weight: 1, item: 40},
535             Weighted { weight: 1, item: 41},
536             Weighted { weight: 1, item: 42},
537             Weighted { weight: 1, item: 43},
538             Weighted { weight: 1, item: 44}],
539            [40, 41, 42, 43, 44]);
540         t!([Weighted { weight: 1, item: 50},
541             Weighted { weight: 1, item: 51},
542             Weighted { weight: 1, item: 52},
543             Weighted { weight: 1, item: 53},
544             Weighted { weight: 1, item: 54},
545             Weighted { weight: 1, item: 55},
546             Weighted { weight: 1, item: 56}],
547            [50, 54, 51, 55, 52, 56, 53]);
548     }
549 
550     #[test]
551     #[allow(deprecated)]
test_weighted_clone_initialization()552     fn test_weighted_clone_initialization() {
553         let initial : Weighted<u32> = Weighted {weight: 1, item: 1};
554         let clone = initial.clone();
555         assert_eq!(initial.weight, clone.weight);
556         assert_eq!(initial.item, clone.item);
557     }
558 
559     #[test] #[should_panic]
560     #[allow(deprecated)]
test_weighted_clone_change_weight()561     fn test_weighted_clone_change_weight() {
562         let initial : Weighted<u32> = Weighted {weight: 1, item: 1};
563         let mut clone = initial.clone();
564         clone.weight = 5;
565         assert_eq!(initial.weight, clone.weight);
566     }
567 
568     #[test] #[should_panic]
569     #[allow(deprecated)]
test_weighted_clone_change_item()570     fn test_weighted_clone_change_item() {
571         let initial : Weighted<u32> = Weighted {weight: 1, item: 1};
572         let mut clone = initial.clone();
573         clone.item = 5;
574         assert_eq!(initial.item, clone.item);
575 
576     }
577 
578     #[test] #[should_panic]
579     #[allow(deprecated)]
test_weighted_choice_no_items()580     fn test_weighted_choice_no_items() {
581         WeightedChoice::<isize>::new(&mut []);
582     }
583     #[test] #[should_panic]
584     #[allow(deprecated)]
test_weighted_choice_zero_weight()585     fn test_weighted_choice_zero_weight() {
586         WeightedChoice::new(&mut [Weighted { weight: 0, item: 0},
587                                   Weighted { weight: 0, item: 1}]);
588     }
589     #[test] #[should_panic]
590     #[allow(deprecated)]
test_weighted_choice_weight_overflows()591     fn test_weighted_choice_weight_overflows() {
592         let x = ::core::u32::MAX / 2; // x + x + 2 is the overflow
593         WeightedChoice::new(&mut [Weighted { weight: x, item: 0 },
594                                   Weighted { weight: 1, item: 1 },
595                                   Weighted { weight: x, item: 2 },
596                                   Weighted { weight: 1, item: 3 }]);
597     }
598 
599     #[cfg(feature="std")]
600     #[test]
test_distributions_iter()601     fn test_distributions_iter() {
602         use distributions::Normal;
603         let mut rng = ::test::rng(210);
604         let distr = Normal::new(10.0, 10.0);
605         let results: Vec<_> = distr.sample_iter(&mut rng).take(100).collect();
606         println!("{:?}", results);
607     }
608 }
609