malachite_base/num/random/mod.rs
1// Copyright © 2026 Mikhail Hogrefe
2//
3// This file is part of Malachite.
4//
5// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
6// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
7// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
8
9use crate::bools::random::{RandomBools, random_bools};
10use crate::iterators::{
11 NonzeroValues, WithSpecialValue, WithSpecialValues, nonzero_values, with_special_value,
12 with_special_values,
13};
14use crate::num::arithmetic::traits::{Parity, PowerOf2, ShrRound};
15use crate::num::basic::floats::PrimitiveFloat;
16use crate::num::basic::integers::{PrimitiveInt, USIZE_IS_U32};
17use crate::num::basic::signeds::PrimitiveSigned;
18use crate::num::basic::unsigneds::PrimitiveUnsigned;
19use crate::num::conversion::traits::WrappingFrom;
20use crate::num::float::NiceFloat;
21use crate::num::iterators::{IteratorToBitChunks, iterator_to_bit_chunks};
22use crate::num::logic::traits::{BitAccess, SignificantBits};
23use crate::num::random::geometric::{
24 GeometricRandomNaturalValues, GeometricRandomSignedRange,
25 geometric_random_signed_inclusive_range, geometric_random_unsigned_inclusive_range,
26 geometric_random_unsigneds,
27};
28use crate::random::{EXAMPLE_SEED, Seed};
29use crate::rounding_modes::RoundingMode::*;
30use crate::vecs::{RandomValuesFromVec, random_values_from_vec};
31use itertools::Itertools;
32use rand::Rng;
33use rand_chacha::ChaCha20Rng;
34use std::collections::HashMap;
35use std::convert::identity;
36use std::fmt::Debug;
37use std::marker::PhantomData;
38
39// Uniformly generates random primitive integers.
40#[doc(hidden)]
41#[derive(Clone, Debug, Eq, Hash, PartialEq)]
42pub struct ThriftyRandomState {
43 x: u32,
44 bits_left: u64,
45}
46
47#[doc(hidden)]
48pub trait HasRandomPrimitiveInts {
49 type State: Clone + Debug;
50
51 fn new_state() -> Self::State;
52
53 fn get_random(rng: &mut ChaCha20Rng, state: &mut Self::State) -> Self;
54}
55
56macro_rules! impl_trivial_random_primitive_ints {
57 ($t: ident) => {
58 impl HasRandomPrimitiveInts for $t {
59 type State = ();
60
61 #[inline]
62 fn new_state() -> () {}
63
64 #[inline]
65 fn get_random(rng: &mut ChaCha20Rng, _state: &mut ()) -> $t {
66 rng.random()
67 }
68 }
69 };
70}
71impl_trivial_random_primitive_ints!(u32);
72impl_trivial_random_primitive_ints!(u64);
73impl_trivial_random_primitive_ints!(u128);
74impl_trivial_random_primitive_ints!(i32);
75impl_trivial_random_primitive_ints!(i64);
76impl_trivial_random_primitive_ints!(i128);
77
78impl HasRandomPrimitiveInts for usize {
79 type State = ();
80
81 #[inline]
82 fn new_state() {}
83
84 #[inline]
85 fn get_random(rng: &mut ChaCha20Rng, _state: &mut ()) -> Self {
86 if USIZE_IS_U32 {
87 let x: u32 = rng.random();
88 x as Self
89 } else {
90 let x: u64 = rng.random();
91 x as Self
92 }
93 }
94}
95
96impl HasRandomPrimitiveInts for isize {
97 type State = ();
98
99 #[inline]
100 fn new_state() {}
101
102 #[inline]
103 fn get_random(rng: &mut ChaCha20Rng, _state: &mut ()) -> Self {
104 if USIZE_IS_U32 {
105 let x: i32 = rng.random();
106 x as Self
107 } else {
108 let x: i64 = rng.random();
109 x as Self
110 }
111 }
112}
113
114fn get_random<T: PrimitiveInt>(rng: &mut ChaCha20Rng, state: &mut ThriftyRandomState) -> T {
115 if state.bits_left == 0 {
116 state.x = rng.random();
117 state.bits_left = u32::WIDTH - T::WIDTH;
118 } else {
119 state.x >>= T::WIDTH;
120 state.bits_left -= T::WIDTH;
121 }
122 T::wrapping_from(state.x)
123}
124
125macro_rules! impl_thrifty_random_primitive_ints {
126 ($t: ident) => {
127 impl HasRandomPrimitiveInts for $t {
128 type State = ThriftyRandomState;
129
130 #[inline]
131 fn new_state() -> ThriftyRandomState {
132 ThriftyRandomState { x: 0, bits_left: 0 }
133 }
134
135 #[inline]
136 fn get_random(rng: &mut ChaCha20Rng, state: &mut ThriftyRandomState) -> $t {
137 get_random(rng, state)
138 }
139 }
140 };
141}
142impl_thrifty_random_primitive_ints!(u8);
143impl_thrifty_random_primitive_ints!(u16);
144impl_thrifty_random_primitive_ints!(i8);
145impl_thrifty_random_primitive_ints!(i16);
146
147/// Uniformly generates random primitive integers.
148///
149/// This `struct` is created by [`random_primitive_ints`]; see its documentation for more.
150#[derive(Clone, Debug)]
151pub struct RandomPrimitiveInts<T: HasRandomPrimitiveInts> {
152 pub(crate) rng: ChaCha20Rng,
153 pub(crate) state: T::State,
154}
155
156impl<T: HasRandomPrimitiveInts> Iterator for RandomPrimitiveInts<T> {
157 type Item = T;
158
159 #[inline]
160 fn next(&mut self) -> Option<T> {
161 Some(T::get_random(&mut self.rng, &mut self.state))
162 }
163}
164
165/// Uniformly generates random unsigned integers less than a positive limit.
166///
167/// This `enum` is created by [`random_unsigneds_less_than`]; see its documentation for more.
168#[allow(clippy::large_enum_variant)]
169#[derive(Clone, Debug)]
170pub enum RandomUnsignedsLessThan<T: PrimitiveUnsigned> {
171 One,
172 AtLeastTwo(RandomUnsignedBitChunks<T>, T),
173}
174
175impl<T: PrimitiveUnsigned> Iterator for RandomUnsignedsLessThan<T> {
176 type Item = T;
177
178 #[inline]
179 fn next(&mut self) -> Option<T> {
180 match self {
181 Self::One => Some(T::ZERO),
182 Self::AtLeastTwo(xs, limit) => loop {
183 let x = xs.next();
184 if x.unwrap() < *limit {
185 return x;
186 }
187 },
188 }
189 }
190}
191
192/// Uniformly generates random unsigned integers in the half-open interval $[a, b)$.
193///
194/// This `struct` is created by [`random_unsigned_range`]; see its documentation for more.
195#[derive(Clone, Debug)]
196pub struct RandomUnsignedRange<T: PrimitiveUnsigned> {
197 pub(crate) xs: RandomUnsignedsLessThan<T>,
198 pub(crate) a: T,
199}
200
201impl<T: PrimitiveUnsigned> Iterator for RandomUnsignedRange<T> {
202 type Item = T;
203
204 #[inline]
205 fn next(&mut self) -> Option<T> {
206 self.xs.next().map(|x| x + self.a)
207 }
208}
209
210/// Uniformly generates random unsigned integers in the closed interval $[a, b]$.
211///
212/// This `struct` is created by [`random_unsigned_inclusive_range`]; see its documentation for more.
213#[derive(Clone, Debug)]
214pub enum RandomUnsignedInclusiveRange<T: PrimitiveUnsigned> {
215 NotAll(RandomUnsignedsLessThan<T>, T),
216 All(RandomPrimitiveInts<T>),
217}
218
219impl<T: PrimitiveUnsigned> Iterator for RandomUnsignedInclusiveRange<T> {
220 type Item = T;
221
222 #[inline]
223 fn next(&mut self) -> Option<T> {
224 match self {
225 Self::NotAll(xs, a) => xs.next().map(|x| x + *a),
226 Self::All(xs) => xs.next(),
227 }
228 }
229}
230
231#[doc(hidden)]
232pub trait HasRandomSignedRange: Sized {
233 type UnsignedValue: PrimitiveUnsigned;
234
235 fn new_unsigned_range(seed: Seed, a: Self, b: Self)
236 -> RandomUnsignedRange<Self::UnsignedValue>;
237
238 fn new_unsigned_inclusive_range(
239 seed: Seed,
240 a: Self,
241 b: Self,
242 ) -> RandomUnsignedInclusiveRange<Self::UnsignedValue>;
243
244 fn from_unsigned_value(x: Self::UnsignedValue) -> Self;
245}
246
247macro_rules! impl_has_random_signed_range {
248 ($u: ident, $s: ident) => {
249 impl HasRandomSignedRange for $s {
250 type UnsignedValue = $u;
251
252 fn new_unsigned_range(seed: Seed, mut a: $s, mut b: $s) -> RandomUnsignedRange<$u> {
253 a.flip_bit($u::WIDTH - 1);
254 b.flip_bit($u::WIDTH - 1);
255 random_unsigned_range(seed, $u::wrapping_from(a), $u::wrapping_from(b))
256 }
257
258 fn new_unsigned_inclusive_range(
259 seed: Seed,
260 mut a: $s,
261 mut b: $s,
262 ) -> RandomUnsignedInclusiveRange<$u> {
263 a.flip_bit($u::WIDTH - 1);
264 b.flip_bit($u::WIDTH - 1);
265 random_unsigned_inclusive_range(seed, $u::wrapping_from(a), $u::wrapping_from(b))
266 }
267
268 fn from_unsigned_value(mut u: $u) -> $s {
269 u.flip_bit($u::WIDTH - 1);
270 $s::wrapping_from(u)
271 }
272 }
273 };
274}
275apply_to_unsigned_signed_pairs!(impl_has_random_signed_range);
276
277/// Uniformly generates random signed integers in the half-open interval $[a, b)$.
278///
279/// This `struct` is created by [`random_signed_range`]; see its documentation for more.
280#[derive(Clone, Debug)]
281pub struct RandomSignedRange<T: HasRandomSignedRange> {
282 pub(crate) xs: RandomUnsignedRange<T::UnsignedValue>,
283}
284
285impl<T: HasRandomSignedRange> Iterator for RandomSignedRange<T> {
286 type Item = T;
287
288 #[inline]
289 fn next(&mut self) -> Option<T> {
290 self.xs.next().map(T::from_unsigned_value)
291 }
292}
293
294/// Uniformly generates random signed integers in the closed interval $[a, b]$.
295///
296/// This `struct` is created by [`random_signed_inclusive_range`]; see its documentation for more.
297#[derive(Clone, Debug)]
298pub struct RandomSignedInclusiveRange<T: HasRandomSignedRange> {
299 pub(crate) xs: RandomUnsignedInclusiveRange<T::UnsignedValue>,
300}
301
302impl<T: HasRandomSignedRange> Iterator for RandomSignedInclusiveRange<T> {
303 type Item = T;
304
305 #[inline]
306 fn next(&mut self) -> Option<T> {
307 self.xs.next().map(T::from_unsigned_value)
308 }
309}
310
311/// Uniformly generates unsigned integers with up to some number of bits.
312///
313/// This `struct` is created by [`random_unsigned_bit_chunks`]; see its documentation for more.
314#[derive(Clone, Debug)]
315pub struct RandomUnsignedBitChunks<T: PrimitiveUnsigned> {
316 xs: IteratorToBitChunks<RandomPrimitiveInts<T>, T, T>,
317}
318
319impl<T: PrimitiveUnsigned> Iterator for RandomUnsignedBitChunks<T> {
320 type Item = T;
321
322 #[inline]
323 fn next(&mut self) -> Option<T> {
324 self.xs.next_with_wrapping(identity).map(Option::unwrap)
325 }
326}
327
328#[doc(hidden)]
329pub trait RandomSignedChunkable: Sized {
330 type AbsoluteChunks: Clone + Debug;
331
332 fn new_absolute_chunks(seed: Seed, chunk_size: u64) -> Self::AbsoluteChunks;
333
334 fn next_chunk(xs: &mut Self::AbsoluteChunks) -> Option<Self>;
335}
336
337macro_rules! impl_random_signed_chunkable {
338 ($u: ident, $s: ident) => {
339 impl RandomSignedChunkable for $s {
340 type AbsoluteChunks = RandomUnsignedBitChunks<$u>;
341
342 fn new_absolute_chunks(seed: Seed, chunk_size: u64) -> RandomUnsignedBitChunks<$u> {
343 random_unsigned_bit_chunks(seed, chunk_size)
344 }
345
346 fn next_chunk(xs: &mut Self::AbsoluteChunks) -> Option<$s> {
347 xs.next().map(WrappingFrom::wrapping_from)
348 }
349 }
350 };
351}
352apply_to_unsigned_signed_pairs!(impl_random_signed_chunkable);
353
354/// Uniformly generates signed integers with up to some number of bits.
355///
356/// This `struct` is created by [`random_signed_bit_chunks`]; see its documentation for more.
357#[derive(Clone, Debug)]
358pub struct RandomSignedBitChunks<T: RandomSignedChunkable> {
359 pub(crate) xs: T::AbsoluteChunks,
360}
361
362impl<T: RandomSignedChunkable> Iterator for RandomSignedBitChunks<T> {
363 type Item = T;
364
365 #[inline]
366 fn next(&mut self) -> Option<T> {
367 T::next_chunk(&mut self.xs)
368 }
369}
370
371/// Modifies the output values of an iterator by setting their highest bit.
372#[derive(Clone, Debug)]
373pub struct RandomHighestBitSetValues<I: Iterator>
374where
375 I::Item: PrimitiveInt,
376{
377 pub(crate) xs: I,
378 pub(crate) mask: I::Item,
379}
380
381impl<I: Iterator> Iterator for RandomHighestBitSetValues<I>
382where
383 I::Item: PrimitiveInt,
384{
385 type Item = I::Item;
386
387 #[inline]
388 fn next(&mut self) -> Option<I::Item> {
389 self.xs.next().map(|x| x | self.mask)
390 }
391}
392
393/// Uniformly generates random primitive integers.
394///
395/// $P(x) = 2^{-W}$, where $W$ is the width of the type.
396///
397/// The output length is infinite.
398///
399/// # Complexity per iteration
400/// Constant time and additional memory.
401///
402/// # Worst-case complexity per iteration
403/// Constant time and additional memory.
404///
405/// # Examples
406/// ```
407/// use malachite_base::iterators::prefix_to_string;
408/// use malachite_base::num::random::random_primitive_ints;
409/// use malachite_base::random::EXAMPLE_SEED;
410///
411/// assert_eq!(
412/// prefix_to_string(random_primitive_ints::<u8>(EXAMPLE_SEED), 10),
413/// "[113, 239, 69, 108, 228, 210, 168, 161, 87, 32, ...]"
414/// )
415/// ```
416#[inline]
417pub fn random_primitive_ints<T: PrimitiveInt>(seed: Seed) -> RandomPrimitiveInts<T> {
418 RandomPrimitiveInts {
419 rng: seed.get_rng(),
420 state: T::new_state(),
421 }
422}
423
424/// Uniformly generates random positive unsigned integers.
425///
426/// $$
427/// P(x) = \\begin{cases}
428/// \\frac{1}{2^W-1} & \text{if} \\quad x > 0, \\\\
429/// 0 & \\text{otherwise},
430/// \\end{cases}
431/// $$
432/// where $W$ is the width of the type.
433///
434/// The output length is infinite.
435///
436/// # Expected complexity per iteration
437/// Constant time and additional memory.
438///
439/// # Examples
440/// ```
441/// use malachite_base::iterators::prefix_to_string;
442/// use malachite_base::num::random::random_positive_unsigneds;
443/// use malachite_base::random::EXAMPLE_SEED;
444///
445/// assert_eq!(
446/// prefix_to_string(random_positive_unsigneds::<u8>(EXAMPLE_SEED), 10),
447/// "[113, 239, 69, 108, 228, 210, 168, 161, 87, 32, ...]"
448/// )
449/// ```
450#[inline]
451pub fn random_positive_unsigneds<T: PrimitiveUnsigned>(
452 seed: Seed,
453) -> NonzeroValues<RandomPrimitiveInts<T>> {
454 nonzero_values(random_primitive_ints(seed))
455}
456
457/// Uniformly generates random positive signed integers.
458///
459/// $$
460/// P(x) = \\begin{cases}
461/// \\frac{1}{2^{W-1}-1} & \text{if} \\quad x > 0, \\\\
462/// 0 & \\text{otherwise},
463/// \\end{cases}
464/// $$
465/// where $W$ is the width of the type.
466///
467/// The output length is infinite.
468///
469/// # Expected complexity per iteration
470/// Constant time and additional memory.
471///
472/// # Examples
473/// ```
474/// use malachite_base::iterators::prefix_to_string;
475/// use malachite_base::num::random::random_positive_signeds;
476/// use malachite_base::random::EXAMPLE_SEED;
477///
478/// assert_eq!(
479/// prefix_to_string(random_positive_signeds::<i8>(EXAMPLE_SEED), 10),
480/// "[113, 94, 23, 98, 70, 92, 52, 84, 33, 47, ...]"
481/// )
482/// ```
483#[inline]
484pub fn random_positive_signeds<T: PrimitiveSigned>(
485 seed: Seed,
486) -> NonzeroValues<RandomSignedBitChunks<T>> {
487 nonzero_values(random_natural_signeds(seed))
488}
489
490/// Uniformly generates random negative signed integers.
491///
492/// $$
493/// P(x) = \\begin{cases}
494/// 2^{1-W} & \text{if} \\quad x < 0, \\\\
495/// 0 & \\text{otherwise},
496/// \\end{cases}
497/// $$
498/// where $W$ is the width of the type.
499///
500/// The output length is infinite.
501///
502/// # Complexity per iteration
503/// Constant time and additional memory.
504///
505/// # Worst-case complexity per iteration
506/// Constant time and additional memory.
507///
508/// # Examples
509/// ```
510/// use malachite_base::iterators::prefix_to_string;
511/// use malachite_base::num::random::random_negative_signeds;
512/// use malachite_base::random::EXAMPLE_SEED;
513///
514/// assert_eq!(
515/// prefix_to_string(random_negative_signeds::<i8>(EXAMPLE_SEED), 10),
516/// "[-15, -34, -105, -30, -58, -36, -76, -44, -95, -81, ...]"
517/// )
518/// ```
519#[inline]
520pub fn random_negative_signeds<T: PrimitiveSigned>(
521 seed: Seed,
522) -> RandomHighestBitSetValues<RandomSignedBitChunks<T>> {
523 RandomHighestBitSetValues {
524 xs: random_signed_bit_chunks(seed, T::WIDTH - 1),
525 mask: T::MIN,
526 }
527}
528
529/// Uniformly generates random natural (non-negative) signed integers.
530///
531/// $$
532/// P(x) = \\begin{cases}
533/// 2^{1-W} & \text{if} \\quad x \geq 0, \\\\
534/// 0 & \\text{otherwise},
535/// \\end{cases}
536/// $$
537/// where $W$ is the width of the type.
538///
539/// The output length is infinite.
540///
541/// # Complexity per iteration
542/// Constant time and additional memory.
543///
544/// # Worst-case complexity per iteration
545/// Constant time and additional memory.
546///
547/// # Examples
548/// ```
549/// use malachite_base::iterators::prefix_to_string;
550/// use malachite_base::num::random::random_natural_signeds;
551/// use malachite_base::random::EXAMPLE_SEED;
552///
553/// assert_eq!(
554/// prefix_to_string(random_natural_signeds::<i8>(EXAMPLE_SEED), 10),
555/// "[113, 94, 23, 98, 70, 92, 52, 84, 33, 47, ...]"
556/// )
557/// ```
558#[inline]
559pub fn random_natural_signeds<T: PrimitiveSigned>(seed: Seed) -> RandomSignedBitChunks<T> {
560 random_signed_bit_chunks(seed, T::WIDTH - 1)
561}
562
563/// Uniformly generates random nonzero signed integers.
564///
565/// $$
566/// P(x) = \\begin{cases}
567/// \\frac{1}{2^W-1} & \text{if} \\quad x \\neq 0, \\\\
568/// 0 & \\text{otherwise},
569/// \\end{cases}
570/// $$
571/// where $W$ is the width of the type.
572///
573/// The output length is infinite.
574///
575/// # Complexity per iteration
576/// Constant time and additional memory.
577///
578/// # Worst-case complexity per iteration
579/// Constant time and additional memory.
580///
581/// # Examples
582/// ```
583/// use malachite_base::iterators::prefix_to_string;
584/// use malachite_base::num::random::random_nonzero_signeds;
585/// use malachite_base::random::EXAMPLE_SEED;
586///
587/// assert_eq!(
588/// prefix_to_string(random_nonzero_signeds::<i8>(EXAMPLE_SEED), 10),
589/// "[113, -17, 69, 108, -28, -46, -88, -95, 87, 32, ...]"
590/// )
591/// ```
592#[inline]
593pub fn random_nonzero_signeds<T: PrimitiveSigned>(
594 seed: Seed,
595) -> NonzeroValues<RandomPrimitiveInts<T>> {
596 nonzero_values(random_primitive_ints(seed))
597}
598
599/// Uniformly generates random unsigned integers less than a positive limit.
600///
601/// $$
602/// P(x) = \\begin{cases}
603/// \frac{1}{\\ell} & \text{if} \\quad x < \\ell, \\\\
604/// 0 & \\text{otherwise,}
605/// \\end{cases}
606/// $$
607/// where $\ell$ is `limit`.
608///
609/// The output length is infinite.
610///
611/// # Expected complexity per iteration
612/// Constant time and additional memory.
613///
614/// # Panics
615/// Panics if `limit` is 0.
616///
617/// # Examples
618/// ```
619/// use malachite_base::iterators::prefix_to_string;
620/// use malachite_base::num::random::random_unsigneds_less_than;
621/// use malachite_base::random::EXAMPLE_SEED;
622///
623/// assert_eq!(
624/// prefix_to_string(random_unsigneds_less_than::<u8>(EXAMPLE_SEED, 10), 10),
625/// "[1, 7, 5, 4, 6, 4, 2, 8, 1, 7, ...]"
626/// )
627/// ```
628pub fn random_unsigneds_less_than<T: PrimitiveUnsigned>(
629 seed: Seed,
630 limit: T,
631) -> RandomUnsignedsLessThan<T> {
632 if limit == T::ZERO {
633 panic!("limit cannot be 0.");
634 } else if limit == T::ONE {
635 RandomUnsignedsLessThan::One
636 } else {
637 RandomUnsignedsLessThan::AtLeastTwo(
638 random_unsigned_bit_chunks(seed, limit.ceiling_log_base_2()),
639 limit,
640 )
641 }
642}
643
644/// Uniformly generates random unsigned integers in the half-open interval $[a, b)$.
645///
646/// $a$ must be less than $b$. This function cannot create a range that includes `T::MAX`; for that,
647/// use [`random_unsigned_inclusive_range`].
648///
649/// $$
650/// P(x) = \\begin{cases}
651/// \frac{1}{b-a} & \text{if} \\quad a \leq x < b, \\\\
652/// 0 & \\text{otherwise.}
653/// \\end{cases}
654/// $$
655///
656/// The output length is infinite.
657///
658/// # Expected complexity per iteration
659/// Constant time and additional memory.
660///
661/// # Panics
662/// Panics if $a \geq b$.
663///
664/// # Examples
665/// ```
666/// use malachite_base::iterators::prefix_to_string;
667/// use malachite_base::num::random::random_unsigned_range;
668/// use malachite_base::random::EXAMPLE_SEED;
669///
670/// assert_eq!(
671/// prefix_to_string(random_unsigned_range::<u8>(EXAMPLE_SEED, 10, 20), 10),
672/// "[11, 17, 15, 14, 16, 14, 12, 18, 11, 17, ...]"
673/// )
674/// ```
675pub fn random_unsigned_range<T: PrimitiveUnsigned>(
676 seed: Seed,
677 a: T,
678 b: T,
679) -> RandomUnsignedRange<T> {
680 assert!(a < b, "a must be less than b. a: {a}, b: {b}");
681 RandomUnsignedRange {
682 xs: random_unsigneds_less_than(seed, b - a),
683 a,
684 }
685}
686
687/// Uniformly generates random unsigned integers in the closed interval $[a, b]$.
688///
689/// $a$ must be less than or equal to $b$.
690///
691/// $$
692/// P(x) = \\begin{cases}
693/// \frac{1}{b-a+1} & \text{if} \\quad a \leq x \leq b, \\\\
694/// 0 & \\text{otherwise.}
695/// \\end{cases}
696/// $$
697///
698/// The output length is infinite.
699///
700/// # Expected complexity per iteration
701/// Constant time and additional memory.
702///
703/// # Panics
704/// Panics if $a > b$.
705///
706/// # Examples
707/// ```
708/// use malachite_base::iterators::prefix_to_string;
709/// use malachite_base::num::random::random_unsigned_inclusive_range;
710/// use malachite_base::random::EXAMPLE_SEED;
711///
712/// assert_eq!(
713/// prefix_to_string(
714/// random_unsigned_inclusive_range::<u8>(EXAMPLE_SEED, 10, 19),
715/// 10
716/// ),
717/// "[11, 17, 15, 14, 16, 14, 12, 18, 11, 17, ...]"
718/// )
719/// ```
720pub fn random_unsigned_inclusive_range<T: PrimitiveUnsigned>(
721 seed: Seed,
722 a: T,
723 b: T,
724) -> RandomUnsignedInclusiveRange<T> {
725 assert!(a <= b, "a must be less than or equal to b. a: {a}, b: {b}");
726 if a == T::ZERO && b == T::MAX {
727 RandomUnsignedInclusiveRange::All(random_primitive_ints(seed))
728 } else {
729 RandomUnsignedInclusiveRange::NotAll(random_unsigneds_less_than(seed, b - a + T::ONE), a)
730 }
731}
732
733/// Uniformly generates random signed integers in the half-open interval $[a, b)$.
734///
735/// $a$ must be less than $b$. This function cannot create a range that includes `T::MAX`; for that,
736/// use [`random_signed_inclusive_range`].
737///
738/// $$
739/// P(x) = \\begin{cases}
740/// \frac{1}{b-a} & \text{if} \\quad a \leq x < b, \\\\
741/// 0 & \\text{otherwise.}
742/// \\end{cases}
743/// $$
744///
745/// The output length is infinite.
746///
747/// # Expected complexity per iteration
748/// Constant time and additional memory.
749///
750/// # Panics
751/// Panics if $a \geq b$.
752///
753/// # Examples
754/// ```
755/// use malachite_base::iterators::prefix_to_string;
756/// use malachite_base::num::random::random_signed_range;
757/// use malachite_base::random::EXAMPLE_SEED;
758///
759/// assert_eq!(
760/// prefix_to_string(random_signed_range::<i8>(EXAMPLE_SEED, -100, 100), 10),
761/// "[13, -31, 8, 68, 61, -13, -68, 10, -17, 88, ...]"
762/// )
763/// ```
764#[inline]
765pub fn random_signed_range<T: PrimitiveSigned>(seed: Seed, a: T, b: T) -> RandomSignedRange<T> {
766 assert!(a < b, "a must be less than b. a: {a}, b: {b}");
767 RandomSignedRange {
768 xs: T::new_unsigned_range(seed, a, b),
769 }
770}
771
772/// Uniformly generates random signed integers in the closed interval $[a, b]$.
773///
774/// $a$ must be less than or equal to $b$.
775///
776/// $$
777/// P(x) = \\begin{cases}
778/// \frac{1}{b-a+1} & \text{if} \\quad a \leq x \leq b, \\\\
779/// 0 & \\text{otherwise.}
780/// \\end{cases}
781/// $$
782///
783/// The output length is infinite.
784///
785/// # Expected complexity per iteration
786/// Constant time and additional memory.
787///
788/// # Panics
789/// Panics if $a > b$.
790///
791/// # Examples
792/// ```
793/// use malachite_base::iterators::prefix_to_string;
794/// use malachite_base::num::random::random_signed_inclusive_range;
795/// use malachite_base::random::EXAMPLE_SEED;
796///
797/// assert_eq!(
798/// prefix_to_string(
799/// random_signed_inclusive_range::<i8>(EXAMPLE_SEED, -100, 99),
800/// 10
801/// ),
802/// "[13, -31, 8, 68, 61, -13, -68, 10, -17, 88, ...]"
803/// )
804/// ```
805#[inline]
806pub fn random_signed_inclusive_range<T: PrimitiveSigned>(
807 seed: Seed,
808 a: T,
809 b: T,
810) -> RandomSignedInclusiveRange<T> {
811 assert!(a <= b, "a must be less than or equal to b. a: {a}, b: {b}");
812 RandomSignedInclusiveRange {
813 xs: T::new_unsigned_inclusive_range(seed, a, b),
814 }
815}
816
817/// Uniformly generates unsigned integers containing some maximum number of bits.
818///
819/// $$
820/// P(x) = \\begin{cases}
821/// 2^{-c} & \text{if} \\quad 0 \\leq x < 2^c, \\\\
822/// 0 & \\text{otherwise,}
823/// \\end{cases}
824/// $$
825/// where $c$ is `chunk_size`.
826///
827/// The output length is infinite.
828///
829/// # Complexity per iteration
830/// Constant time and additional memory.
831///
832/// # Worst-case complexity per iteration
833/// Constant time and additional memory.
834///
835/// # Panics
836/// Panics if `chunk_size` is zero or greater than the width of the type.
837///
838/// # Examples
839/// ```
840/// use malachite_base::iterators::prefix_to_string;
841/// use malachite_base::num::random::random_unsigned_bit_chunks;
842/// use malachite_base::random::EXAMPLE_SEED;
843///
844/// assert_eq!(
845/// prefix_to_string(random_unsigned_bit_chunks::<u8>(EXAMPLE_SEED, 3), 10),
846/// "[1, 6, 5, 7, 6, 3, 1, 2, 4, 5, ...]"
847/// )
848/// ```
849pub fn random_unsigned_bit_chunks<T: PrimitiveUnsigned>(
850 seed: Seed,
851 chunk_size: u64,
852) -> RandomUnsignedBitChunks<T> {
853 RandomUnsignedBitChunks {
854 xs: iterator_to_bit_chunks(random_primitive_ints(seed), T::WIDTH, chunk_size),
855 }
856}
857
858/// Uniformly generates signed integers containing some maximum number of bits.
859///
860/// The generated values will all be non-negative unless `chunk_size` is equal to the width of the
861/// type.
862///
863/// $$
864/// P(x) = \\begin{cases}
865/// 2^{-c} & \text{if} \\quad c = W \\ \\text{or}
866/// \\ (c < W \\ \\text{and} \\ 0 \\leq x < 2^c), \\\\
867/// 0 & \\text{otherwise,}
868/// \\end{cases}
869/// $$
870/// where $c$ is `chunk_size` and $W$ is the width of the type.
871///
872/// The output length is infinite.
873///
874/// # Complexity per iteration
875/// Constant time and additional memory.
876///
877/// # Worst-case complexity per iteration
878/// Constant time and additional memory.
879///
880/// # Panics
881/// Panics if `chunk_size` is zero or greater than the width of the type.
882///
883/// # Examples
884/// ```
885/// use malachite_base::iterators::prefix_to_string;
886/// use malachite_base::num::random::random_signed_bit_chunks;
887/// use malachite_base::random::EXAMPLE_SEED;
888///
889/// assert_eq!(
890/// prefix_to_string(random_signed_bit_chunks::<i8>(EXAMPLE_SEED, 3), 10),
891/// "[1, 6, 5, 7, 6, 3, 1, 2, 4, 5, ...]"
892/// )
893/// ```
894pub fn random_signed_bit_chunks<T: PrimitiveSigned>(
895 seed: Seed,
896 chunk_size: u64,
897) -> RandomSignedBitChunks<T> {
898 assert!(chunk_size <= T::WIDTH);
899 RandomSignedBitChunks {
900 xs: T::new_absolute_chunks(seed, chunk_size),
901 }
902}
903
904/// Uniformly generates unsigned integers whose highest bit is set.
905///
906/// $$
907/// P(x) = \\begin{cases}
908/// 2^{1-W} & \text{if} \\quad 2^{W-1} \\leq x < 2^W ,\\\\
909/// 0 & \\text{otherwise},
910/// \\end{cases}
911/// $$
912/// where $W$ is the width of the type.
913///
914/// The output length is infinite.
915///
916/// # Complexity per iteration
917/// Constant time and additional memory.
918///
919/// # Worst-case complexity per iteration
920/// Constant time and additional memory.
921///
922/// # Examples
923/// ```
924/// use malachite_base::iterators::prefix_to_string;
925/// use malachite_base::num::random::random_highest_bit_set_unsigneds;
926/// use malachite_base::random::EXAMPLE_SEED;
927///
928/// assert_eq!(
929/// prefix_to_string(random_highest_bit_set_unsigneds::<u8>(EXAMPLE_SEED), 10),
930/// "[241, 222, 151, 226, 198, 220, 180, 212, 161, 175, ...]"
931/// )
932/// ```
933#[inline]
934pub fn random_highest_bit_set_unsigneds<T: PrimitiveUnsigned>(
935 seed: Seed,
936) -> RandomHighestBitSetValues<RandomUnsignedBitChunks<T>> {
937 RandomHighestBitSetValues {
938 xs: random_unsigned_bit_chunks(seed, T::WIDTH - 1),
939 mask: T::power_of_2(T::WIDTH - 1),
940 }
941}
942
943/// Generates random primitive floats in the half-open interval $[a, b)$.
944///
945/// This `struct` is created by [`random_primitive_float_range`]; see its documentation for more.
946#[derive(Clone, Debug)]
947pub struct RandomPrimitiveFloatRange<T: PrimitiveFloat> {
948 phantom: PhantomData<*const T>,
949 xs: RandomUnsignedRange<u64>,
950}
951
952impl<T: PrimitiveFloat> Iterator for RandomPrimitiveFloatRange<T> {
953 type Item = T;
954
955 #[inline]
956 fn next(&mut self) -> Option<T> {
957 self.xs.next().map(T::from_ordered_representation)
958 }
959}
960
961/// Generates random primitive floats in the closed interval $[a, b]$.
962///
963/// This `struct` is created by [`random_primitive_float_inclusive_range`]; see its documentation
964/// for more.
965#[derive(Clone, Debug)]
966pub struct RandomPrimitiveFloatInclusiveRange<T: PrimitiveFloat> {
967 phantom: PhantomData<*const T>,
968 xs: RandomUnsignedInclusiveRange<u64>,
969}
970
971impl<T: PrimitiveFloat> Iterator for RandomPrimitiveFloatInclusiveRange<T> {
972 type Item = T;
973
974 #[inline]
975 fn next(&mut self) -> Option<T> {
976 self.xs.next().map(T::from_ordered_representation)
977 }
978}
979
980/// Generates random primitive floats in the half-open interval $[a, b)$.
981///
982/// Every float within the range has an equal probability of being chosen. This does not mean that
983/// the distribution approximates a uniform distribution over the reals. For example, if the range
984/// is $[0, 2)$, a float in $[1/4, 1/2)$ is as likely to be chosen as a float in $[1, 2)$, since
985/// these subranges contain an equal number of floats.
986///
987/// Positive and negative zero are treated as two distinct values, with negative zero being smaller
988/// than zero.
989///
990/// `NaN` is never generated.
991///
992/// $a$ must be less than $b$. This function cannot create a range that includes `T::INFINITY`; for
993/// that, use [`random_primitive_float_inclusive_range`].
994///
995/// The output length is infinite.
996///
997/// # Expected complexity per iteration
998/// Constant time and additional memory.
999///
1000/// # Panics
1001/// Panics if $a \geq b$.
1002///
1003/// # Examples
1004/// ```
1005/// use malachite_base::iterators::prefix_to_string;
1006/// use malachite_base::num::float::NiceFloat;
1007/// use malachite_base::num::random::random_primitive_float_range;
1008/// use malachite_base::random::EXAMPLE_SEED;
1009///
1010/// assert_eq!(
1011/// prefix_to_string(
1012/// random_primitive_float_range::<f32>(EXAMPLE_SEED, -0.1, 0.1).map(NiceFloat),
1013/// 10
1014/// ),
1015/// "[5.664681e-11, 1.2492925e-35, 2.3242339e-29, 4.699183e-7, -2.8244436e-36, -2.264039e-37, \
1016/// -0.0000017299129, 1.40616e-23, 2.7418007e-27, 1.5418819e-16, ...]"
1017/// );
1018/// ```
1019#[inline]
1020pub fn random_primitive_float_range<T: PrimitiveFloat>(
1021 seed: Seed,
1022 a: T,
1023 b: T,
1024) -> RandomPrimitiveFloatRange<T> {
1025 assert!(!a.is_nan());
1026 assert!(!b.is_nan());
1027 assert!(
1028 NiceFloat(a) < NiceFloat(b),
1029 "a must be less than b. a: {}, b: {}",
1030 NiceFloat(a),
1031 NiceFloat(b)
1032 );
1033 RandomPrimitiveFloatRange {
1034 phantom: PhantomData,
1035 xs: random_unsigned_range(
1036 seed,
1037 a.to_ordered_representation(),
1038 b.to_ordered_representation(),
1039 ),
1040 }
1041}
1042
1043/// Generates random primitive floats in the closed interval $[a, b]$.
1044///
1045/// Every float within the range has an equal probability of being chosen. This does not mean that
1046/// the distribution approximates a uniform distribution over the reals. For example, if the range
1047/// is $[0, 2]$, a float in $[1/4, 1/2)$ is as likely to be chosen as a float in $[1, 2)$, since
1048/// these subranges contain an equal number of floats.
1049///
1050/// Positive and negative zero are treated as two distinct values, with negative zero being smaller
1051/// than zero.
1052///
1053/// $a$ must be less than or equal to $b$.
1054///
1055/// `NaN` is never generated.
1056///
1057/// The output length is infinite.
1058///
1059/// # Expected complexity per iteration
1060/// Constant time and additional memory.
1061///
1062/// # Panics
1063/// Panics if $a > b$.
1064///
1065/// # Examples
1066/// ```
1067/// use malachite_base::iterators::prefix_to_string;
1068/// use malachite_base::num::float::NiceFloat;
1069/// use malachite_base::num::random::random_primitive_float_inclusive_range;
1070/// use malachite_base::random::EXAMPLE_SEED;
1071///
1072/// assert_eq!(
1073/// prefix_to_string(
1074/// random_primitive_float_inclusive_range::<f32>(EXAMPLE_SEED, -0.1, 0.1).map(NiceFloat),
1075/// 10
1076/// ),
1077/// "[5.664681e-11, 1.2492925e-35, 2.3242339e-29, 4.699183e-7, -2.8244436e-36, -2.264039e-37, \
1078/// -0.0000017299129, 1.40616e-23, 2.7418007e-27, 1.5418819e-16, ...]"
1079/// );
1080/// ```
1081#[inline]
1082pub fn random_primitive_float_inclusive_range<T: PrimitiveFloat>(
1083 seed: Seed,
1084 a: T,
1085 b: T,
1086) -> RandomPrimitiveFloatInclusiveRange<T> {
1087 assert!(!a.is_nan());
1088 assert!(!b.is_nan());
1089 assert!(
1090 NiceFloat(a) <= NiceFloat(b),
1091 "a must be less than or equal to b. a: {}, b: {}",
1092 NiceFloat(a),
1093 NiceFloat(b)
1094 );
1095 RandomPrimitiveFloatInclusiveRange {
1096 phantom: PhantomData,
1097 xs: random_unsigned_inclusive_range(
1098 seed,
1099 a.to_ordered_representation(),
1100 b.to_ordered_representation(),
1101 ),
1102 }
1103}
1104
1105/// Generates random finite positive primitive floats.
1106///
1107/// Every float within the range has an equal probability of being chosen. This does not mean that
1108/// the distribution approximates a uniform distribution over the reals. For example, a float in
1109/// $[1/4, 1/2)$ is as likely to be chosen as a float in $[1, 2)$, since these subranges contain an
1110/// equal number of floats.
1111///
1112/// Positive zero is generated; negative zero is not. `NaN` is not generated either.
1113///
1114/// The output length is infinite.
1115///
1116/// # Expected complexity per iteration
1117/// Constant time and additional memory.
1118///
1119/// # Examples
1120/// ```
1121/// use malachite_base::iterators::prefix_to_string;
1122/// use malachite_base::num::float::NiceFloat;
1123/// use malachite_base::num::random::random_positive_finite_primitive_floats;
1124/// use malachite_base::random::EXAMPLE_SEED;
1125///
1126/// assert_eq!(
1127/// prefix_to_string(
1128/// random_positive_finite_primitive_floats::<f32>(EXAMPLE_SEED).map(NiceFloat),
1129/// 10
1130/// ),
1131/// "[9.5715654e26, 209.6476, 386935780.0, 7.965817e30, 0.00021030706, 0.0027270128, \
1132/// 3.4398167e-34, 2.3397111e14, 44567765000.0, 2.3479653e21, ...]"
1133/// );
1134/// ```
1135#[inline]
1136pub fn random_positive_finite_primitive_floats<T: PrimitiveFloat>(
1137 seed: Seed,
1138) -> RandomPrimitiveFloatInclusiveRange<T> {
1139 random_primitive_float_inclusive_range(seed, T::MIN_POSITIVE_SUBNORMAL, T::MAX_FINITE)
1140}
1141
1142/// Generates random finite negative primitive floats.
1143///
1144/// Every float within the range has an equal probability of being chosen. This does not mean that
1145/// the distribution approximates a uniform distribution over the reals. For example, a float in
1146/// $(-1/2, 1/4]$ is as likely to be chosen as a float in $(-2, -1]$, since these subranges contain
1147/// an equal number of floats.
1148///
1149/// Negative zero is generated; positive zero is not. `NaN` is not generated either.
1150///
1151/// The output length is infinite.
1152///
1153/// # Expected complexity per iteration
1154/// Constant time and additional memory.
1155///
1156/// # Examples
1157/// ```
1158/// use malachite_base::iterators::prefix_to_string;
1159/// use malachite_base::num::float::NiceFloat;
1160/// use malachite_base::num::random::random_negative_finite_primitive_floats;
1161/// use malachite_base::random::EXAMPLE_SEED;
1162///
1163/// assert_eq!(
1164/// prefix_to_string(
1165/// random_negative_finite_primitive_floats::<f32>(EXAMPLE_SEED).map(NiceFloat),
1166/// 10
1167/// ),
1168/// "[-2.3484663e-27, -0.010641626, -5.8060583e-9, -2.8182442e-31, -10462.532, -821.12994, \
1169/// -6.303163e33, -9.50376e-15, -4.9561126e-11, -8.565163e-22, ...]"
1170/// );
1171/// ```
1172#[inline]
1173pub fn random_negative_finite_primitive_floats<T: PrimitiveFloat>(
1174 seed: Seed,
1175) -> RandomPrimitiveFloatInclusiveRange<T> {
1176 random_primitive_float_inclusive_range(seed, -T::MAX_FINITE, -T::MIN_POSITIVE_SUBNORMAL)
1177}
1178
1179/// Generates random finite nonzero primitive floats.
1180///
1181/// Every float within the range has an equal probability of being chosen. This does not mean that
1182/// the distribution approximates a uniform distribution over the reals. For example, a float in
1183/// $[1/4, 1/2)$ is as likely to be chosen as a float in $[1, 2)$, since these subranges contain an
1184/// equal number of floats.
1185///
1186/// Neither positive nor negative zero are generated. `NaN` is not generated either.
1187///
1188/// The output length is infinite.
1189///
1190/// # Expected complexity per iteration
1191/// Constant time and additional memory.
1192///
1193/// # Examples
1194/// ```
1195/// use malachite_base::iterators::prefix_to_string;
1196/// use malachite_base::num::float::NiceFloat;
1197/// use malachite_base::num::random::random_nonzero_finite_primitive_floats;
1198/// use malachite_base::random::EXAMPLE_SEED;
1199///
1200/// assert_eq!(
1201/// prefix_to_string(
1202/// random_nonzero_finite_primitive_floats::<f32>(EXAMPLE_SEED).map(NiceFloat),
1203/// 10
1204/// ),
1205/// "[-2.3484663e-27, 2.287989e-18, -2.0729893e-12, 3.360012e28, -9.021723e-32, 3564911.2, \
1206/// -0.0000133769445, -1.8855448e18, 8.2494555e-29, 2.2178014e-38, ...]"
1207/// );
1208/// ```
1209#[inline]
1210pub fn random_nonzero_finite_primitive_floats<T: PrimitiveFloat>(
1211 seed: Seed,
1212) -> NonzeroValues<RandomPrimitiveFloatInclusiveRange<T>> {
1213 nonzero_values(random_finite_primitive_floats(seed))
1214}
1215
1216/// Generates random finite primitive floats.
1217///
1218/// Every float within the range has an equal probability of being chosen. This does not mean that
1219/// the distribution approximates a uniform distribution over the reals. For example, a float in
1220/// $[1/4, 1/2)$ is as likely to be chosen as a float in $[1, 2)$, since these subranges contain an
1221/// equal number of floats.
1222///
1223/// Positive zero and negative zero are both generated. `NaN` is not.
1224///
1225/// The output length is infinite.
1226///
1227/// # Expected complexity per iteration
1228/// Constant time and additional memory.
1229///
1230/// # Examples
1231/// ```
1232/// use malachite_base::iterators::prefix_to_string;
1233/// use malachite_base::num::float::NiceFloat;
1234/// use malachite_base::num::random::random_finite_primitive_floats;
1235/// use malachite_base::random::EXAMPLE_SEED;
1236///
1237/// assert_eq!(
1238/// prefix_to_string(
1239/// random_finite_primitive_floats::<f32>(EXAMPLE_SEED).map(NiceFloat),
1240/// 10
1241/// ),
1242/// "[-2.3484663e-27, 2.287989e-18, -2.0729893e-12, 3.360012e28, -9.021723e-32, 3564911.2, \
1243/// -0.0000133769445, -1.8855448e18, 8.2494555e-29, 2.2178014e-38, ...]"
1244/// );
1245/// ```
1246#[inline]
1247pub fn random_finite_primitive_floats<T: PrimitiveFloat>(
1248 seed: Seed,
1249) -> RandomPrimitiveFloatInclusiveRange<T> {
1250 random_primitive_float_inclusive_range(seed, -T::MAX_FINITE, T::MAX_FINITE)
1251}
1252
1253/// Generates random positive primitive floats.
1254///
1255/// Every float within the range has an equal probability of being chosen. This does not mean that
1256/// the distribution approximates a uniform distribution over the reals. For example, a float in
1257/// $[1/4, 1/2)$ is as likely to be chosen as a float in $[1, 2)$, since these subranges contain an
1258/// equal number of floats.
1259///
1260/// Positive zero is generated; negative zero is not. `NaN` is not generated either.
1261///
1262/// The output length is infinite.
1263///
1264/// # Expected complexity per iteration
1265/// Constant time and additional memory.
1266///
1267/// # Examples
1268/// ```
1269/// use malachite_base::iterators::prefix_to_string;
1270/// use malachite_base::num::float::NiceFloat;
1271/// use malachite_base::num::random::random_positive_primitive_floats;
1272/// use malachite_base::random::EXAMPLE_SEED;
1273///
1274/// assert_eq!(
1275/// prefix_to_string(
1276/// random_positive_primitive_floats::<f32>(EXAMPLE_SEED).map(NiceFloat),
1277/// 10
1278/// ),
1279/// "[9.5715654e26, 209.6476, 386935780.0, 7.965817e30, 0.00021030706, 0.0027270128, \
1280/// 3.4398167e-34, 2.3397111e14, 44567765000.0, 2.3479653e21, ...]"
1281/// );
1282/// ```
1283#[inline]
1284pub fn random_positive_primitive_floats<T: PrimitiveFloat>(
1285 seed: Seed,
1286) -> RandomPrimitiveFloatInclusiveRange<T> {
1287 random_primitive_float_inclusive_range(seed, T::MIN_POSITIVE_SUBNORMAL, T::INFINITY)
1288}
1289
1290/// Generates random negative primitive floats.
1291///
1292/// Every float within the range has an equal probability of being chosen. This does not mean that
1293/// the distribution approximates a uniform distribution over the reals. For example, a float in
1294/// $(-1/2, -1/4]$ is as likely to be chosen as a float in $(-2, -1]$, since these subranges contain
1295/// an equal number of floats.
1296///
1297/// Negative zero is generated; positive zero is not. `NaN` is not generated either.
1298///
1299/// The output length is infinite.
1300///
1301/// # Expected complexity per iteration
1302/// Constant time and additional memory.
1303///
1304/// # Examples
1305/// ```
1306/// use malachite_base::iterators::prefix_to_string;
1307/// use malachite_base::num::float::NiceFloat;
1308/// use malachite_base::num::random::random_negative_primitive_floats;
1309/// use malachite_base::random::EXAMPLE_SEED;
1310///
1311/// assert_eq!(
1312/// prefix_to_string(
1313/// random_negative_primitive_floats::<f32>(EXAMPLE_SEED).map(NiceFloat),
1314/// 10
1315/// ),
1316/// "[-2.3484665e-27, -0.010641627, -5.8060587e-9, -2.8182444e-31, -10462.533, -821.13, \
1317/// -6.3031636e33, -9.5037605e-15, -4.956113e-11, -8.565164e-22, ...]"
1318/// );
1319/// ```
1320#[inline]
1321pub fn random_negative_primitive_floats<T: PrimitiveFloat>(
1322 seed: Seed,
1323) -> RandomPrimitiveFloatInclusiveRange<T> {
1324 random_primitive_float_inclusive_range(seed, T::NEGATIVE_INFINITY, -T::MIN_POSITIVE_SUBNORMAL)
1325}
1326
1327/// Generates random nonzero primitive floats.
1328///
1329/// Every float within the range has an equal probability of being chosen. This does not mean that
1330/// the distribution approximates a uniform distribution over the reals. For example, a float in
1331/// $[1/4, 1/2)$ is as likely to be chosen as a float in $[1, 2)$, since these subranges contain an
1332/// equal number of floats.
1333///
1334/// Neither positive nor negative zero are generated. `NaN` is not generated either.
1335///
1336/// The output length is infinite.
1337///
1338/// # Expected complexity per iteration
1339/// Constant time and additional memory.
1340///
1341/// # Examples
1342/// ```
1343/// use malachite_base::iterators::prefix_to_string;
1344/// use malachite_base::num::float::NiceFloat;
1345/// use malachite_base::num::random::random_nonzero_primitive_floats;
1346/// use malachite_base::random::EXAMPLE_SEED;
1347///
1348/// assert_eq!(
1349/// prefix_to_string(
1350/// random_nonzero_primitive_floats::<f32>(EXAMPLE_SEED).map(NiceFloat),
1351/// 10
1352/// ),
1353/// "[-2.3484665e-27, 2.2879888e-18, -2.0729896e-12, 3.3600117e28, -9.0217234e-32, 3564911.0, \
1354/// -0.000013376945, -1.885545e18, 8.249455e-29, 2.2178013e-38, ...]",
1355/// );
1356/// ```
1357#[inline]
1358pub fn random_nonzero_primitive_floats<T: PrimitiveFloat>(
1359 seed: Seed,
1360) -> NonzeroValues<RandomPrimitiveFloats<T>> {
1361 nonzero_values(random_primitive_floats(seed))
1362}
1363
1364/// Generates random primitive floats.
1365///
1366/// This `struct` is created by [`random_primitive_floats`]; see its documentation for more.
1367#[derive(Clone, Debug)]
1368pub struct RandomPrimitiveFloats<T: PrimitiveFloat> {
1369 phantom: PhantomData<*const T>,
1370 pub(crate) xs: RandomUnsignedInclusiveRange<u64>,
1371 nan: u64,
1372}
1373
1374impl<T: PrimitiveFloat> Iterator for RandomPrimitiveFloats<T> {
1375 type Item = T;
1376
1377 #[inline]
1378 fn next(&mut self) -> Option<T> {
1379 self.xs.next().map(|x| {
1380 if x == self.nan {
1381 T::NAN
1382 } else {
1383 T::from_ordered_representation(x)
1384 }
1385 })
1386 }
1387}
1388
1389/// Generates random finite primitive floats.
1390///
1391/// Every float has an equal probability of being chosen. This does not mean that the distribution
1392/// approximates a uniform distribution over the reals. For example, a float in $[1/4, 1/2)$ is as
1393/// likely to be chosen as a float in $[1, 2)$, since these subranges contain an equal number of
1394/// floats.
1395///
1396/// Positive zero, negative zero, and `NaN` are all generated.
1397///
1398/// The output length is infinite.
1399///
1400/// # Expected complexity per iteration
1401/// Constant time and additional memory.
1402///
1403/// # Examples
1404/// ```
1405/// use malachite_base::iterators::prefix_to_string;
1406/// use malachite_base::num::float::NiceFloat;
1407/// use malachite_base::num::random::random_primitive_floats;
1408/// use malachite_base::random::EXAMPLE_SEED;
1409///
1410/// assert_eq!(
1411/// prefix_to_string(
1412/// random_primitive_floats::<f32>(EXAMPLE_SEED).map(NiceFloat),
1413/// 10
1414/// ),
1415/// "[-2.3484665e-27, 2.2879888e-18, -2.0729896e-12, 3.3600117e28, -9.0217234e-32, 3564911.0, \
1416/// -0.000013376945, -1.885545e18, 8.249455e-29, 2.2178013e-38, ...]"
1417/// );
1418/// ```
1419#[inline]
1420pub fn random_primitive_floats<T: PrimitiveFloat>(seed: Seed) -> RandomPrimitiveFloats<T> {
1421 let nan = T::INFINITY.to_ordered_representation() + 1;
1422 RandomPrimitiveFloats {
1423 phantom: PhantomData,
1424 xs: random_unsigned_inclusive_range(seed, 0, nan),
1425 nan,
1426 }
1427}
1428
1429/// Generates positive finite primitive floats.
1430///
1431/// This `struct` is created by [`special_random_positive_finite_primitive_floats`]; see its
1432/// documentation for more.
1433#[derive(Clone, Debug)]
1434pub struct SpecialRandomPositiveFiniteFloats<T: PrimitiveFloat> {
1435 seed: Seed,
1436 sci_exponents: GeometricRandomSignedRange<i64>,
1437 range_map: HashMap<i64, GeometricRandomNaturalValues<u64>>,
1438 ranges: VariableRangeGenerator,
1439 mean_precision_n: u64,
1440 mean_precision_d: u64,
1441 phantom: PhantomData<*const T>,
1442}
1443
1444impl<T: PrimitiveFloat> Iterator for SpecialRandomPositiveFiniteFloats<T> {
1445 type Item = T;
1446
1447 fn next(&mut self) -> Option<T> {
1448 let sci_exponent = self.sci_exponents.next().unwrap();
1449 let mean_precision_n = self.mean_precision_n;
1450 let mean_precision_d = self.mean_precision_d;
1451 let seed = self.seed;
1452 let precisions = self.range_map.entry(sci_exponent).or_insert_with(move || {
1453 geometric_random_unsigned_inclusive_range(
1454 seed.fork(&sci_exponent.to_string()),
1455 1,
1456 T::max_precision_for_sci_exponent(sci_exponent),
1457 mean_precision_n,
1458 mean_precision_d,
1459 )
1460 });
1461 let precision = precisions.next().unwrap();
1462 let mantissa = if precision == 1 {
1463 1
1464 } else {
1465 // e.g. if precision is 4, generate odd values from 1001 through 1111, inclusive
1466 let x = self.ranges.next_in_range(
1467 u64::power_of_2(precision - 2),
1468 u64::power_of_2(precision - 1),
1469 );
1470 (x << 1) | 1
1471 };
1472 T::from_integer_mantissa_and_exponent(
1473 mantissa,
1474 sci_exponent - i64::wrapping_from(precision) + 1,
1475 )
1476 }
1477}
1478
1479/// Generates positive finite primitive floats.
1480///
1481/// Simpler floats (those with a lower absolute sci-exponent or precision) are more likely to be
1482/// chosen. You can specify the mean absolute sci-exponent and precision by passing the numerators
1483/// and denominators of their means.
1484///
1485/// But note that the specified means are only approximate, since the distributions we are sampling
1486/// are truncated geometric, and their exact means are somewhat annoying to deal with. The practical
1487/// implications are that
1488/// - The actual means are slightly lower than the specified means.
1489/// - However, increasing the specified means increases the actual means, so this still works as a
1490/// mechanism for controlling the sci-exponent and precision.
1491/// - The specified sci-exponent mean must be greater than 0 and the precision mean greater than 2,
1492/// but they may be as high as you like.
1493///
1494/// Positive zero is generated; negative zero is not. `NaN` is not generated either. TODO: don't
1495/// generate any zeros!
1496///
1497/// The output length is infinite.
1498///
1499/// # Expected complexity per iteration
1500/// Constant time and additional memory.
1501///
1502/// # Examples
1503/// ```
1504/// use malachite_base::iterators::prefix_to_string;
1505/// use malachite_base::num::float::NiceFloat;
1506/// use malachite_base::num::random::special_random_positive_finite_primitive_floats;
1507/// use malachite_base::random::EXAMPLE_SEED;
1508///
1509/// assert_eq!(
1510/// prefix_to_string(
1511/// special_random_positive_finite_primitive_floats::<f32>(EXAMPLE_SEED, 10, 1, 10, 1)
1512/// .map(NiceFloat),
1513/// 20
1514/// ),
1515/// "[0.80126953, 0.0000013709068, 0.015609741, 0.98552704, 65536.0, 0.008257866, \
1516/// 0.017333984, 2.25, 7.7089844, 0.00004425831, 0.40625, 24576.0, 37249.0, 1.1991882, \
1517/// 32.085938, 0.4375, 0.0012359619, 1536.0, 0.22912993, 0.0015716553, ...]"
1518/// );
1519/// ```
1520pub fn special_random_positive_finite_primitive_floats<T: PrimitiveFloat>(
1521 seed: Seed,
1522 mean_sci_exponent_numerator: u64,
1523 mean_sci_exponent_denominator: u64,
1524 mean_precision_numerator: u64,
1525 mean_precision_denominator: u64,
1526) -> SpecialRandomPositiveFiniteFloats<T> {
1527 assert_ne!(mean_precision_denominator, 0);
1528 assert!(mean_precision_numerator > mean_precision_denominator);
1529 SpecialRandomPositiveFiniteFloats {
1530 seed: seed.fork("precisions"),
1531 sci_exponents: geometric_random_signed_inclusive_range(
1532 EXAMPLE_SEED.fork("exponents"),
1533 T::MIN_EXPONENT,
1534 T::MAX_EXPONENT,
1535 mean_sci_exponent_numerator,
1536 mean_sci_exponent_denominator,
1537 ),
1538 range_map: HashMap::new(),
1539 ranges: VariableRangeGenerator::new(seed.fork("ranges")),
1540 mean_precision_n: mean_precision_numerator,
1541 mean_precision_d: mean_precision_denominator,
1542 phantom: PhantomData,
1543 }
1544}
1545
1546/// Generates negative finite primitive floats.
1547///
1548/// This `struct` is created by [`special_random_negative_finite_primitive_floats`]; see its
1549/// documentation for more.
1550#[derive(Clone, Debug)]
1551pub struct SpecialRandomNegativeFiniteFloats<T: PrimitiveFloat>(
1552 SpecialRandomPositiveFiniteFloats<T>,
1553);
1554
1555impl<T: PrimitiveFloat> Iterator for SpecialRandomNegativeFiniteFloats<T> {
1556 type Item = T;
1557
1558 #[inline]
1559 fn next(&mut self) -> Option<T> {
1560 self.0.next().map(|f| -f)
1561 }
1562}
1563
1564/// Generates negative finite primitive floats.
1565///
1566/// Simpler floats (those with a lower absolute sci-exponent or precision) are more likely to be
1567/// chosen. You can specify the mean absolute sci-exponent and precision by passing the numerators
1568/// and denominators of their means.
1569///
1570/// But note that the specified means are only approximate, since the distributions we are sampling
1571/// are truncated geometric, and their exact means are somewhat annoying to deal with. The practical
1572/// implications are that
1573/// - The actual means are slightly lower than the specified means.
1574/// - However, increasing the specified means increases the actual means, so this still works as a
1575/// mechanism for controlling the sci-exponent and precision.
1576/// - The specified sci-exponent mean must be greater than 0 and the precision mean greater than 2,
1577/// but they may be as high as you like.
1578///
1579/// Negative zero is generated; positive zero is not. `NaN` is not generated either.
1580///
1581/// The output length is infinite.
1582///
1583/// # Expected complexity per iteration
1584/// Constant time and additional memory.
1585///
1586/// # Examples
1587/// ```
1588/// use malachite_base::iterators::prefix_to_string;
1589/// use malachite_base::num::float::NiceFloat;
1590/// use malachite_base::num::random::special_random_negative_finite_primitive_floats;
1591/// use malachite_base::random::EXAMPLE_SEED;
1592///
1593/// assert_eq!(
1594/// prefix_to_string(
1595/// special_random_negative_finite_primitive_floats::<f32>(EXAMPLE_SEED, 10, 1, 10, 1)
1596/// .map(NiceFloat),
1597/// 20
1598/// ),
1599/// "[-0.80126953, -0.0000013709068, -0.015609741, -0.98552704, -65536.0, -0.008257866, \
1600/// -0.017333984, -2.25, -7.7089844, -0.00004425831, -0.40625, -24576.0, -37249.0, \
1601/// -1.1991882, -32.085938, -0.4375, -0.0012359619, -1536.0, -0.22912993, -0.0015716553, ...]"
1602/// );
1603/// ```
1604#[inline]
1605pub fn special_random_negative_finite_primitive_floats<T: PrimitiveFloat>(
1606 seed: Seed,
1607 mean_sci_exponent_numerator: u64,
1608 mean_sci_exponent_denominator: u64,
1609 mean_precision_numerator: u64,
1610 mean_precision_denominator: u64,
1611) -> SpecialRandomNegativeFiniteFloats<T> {
1612 SpecialRandomNegativeFiniteFloats(special_random_positive_finite_primitive_floats(
1613 seed,
1614 mean_sci_exponent_numerator,
1615 mean_sci_exponent_denominator,
1616 mean_precision_numerator,
1617 mean_precision_denominator,
1618 ))
1619}
1620
1621/// Generates nonzero finite primitive floats.
1622///
1623/// This `struct` is created by [`special_random_nonzero_finite_primitive_floats`]; see its
1624/// documentation for more.
1625#[derive(Clone, Debug)]
1626pub struct SpecialRandomNonzeroFiniteFloats<T: PrimitiveFloat> {
1627 bs: RandomBools,
1628 xs: SpecialRandomPositiveFiniteFloats<T>,
1629}
1630
1631impl<T: PrimitiveFloat> Iterator for SpecialRandomNonzeroFiniteFloats<T> {
1632 type Item = T;
1633
1634 #[inline]
1635 fn next(&mut self) -> Option<T> {
1636 let x = self.xs.next().unwrap();
1637 Some(if self.bs.next().unwrap() { x } else { -x })
1638 }
1639}
1640
1641/// Generates finite nonzero primitive floats.
1642///
1643/// Simpler floats (those with a lower absolute sci-exponent or precision) are more likely to be
1644/// chosen. You can specify the mean absolute sci-exponent and precision by passing the numerators
1645/// and denominators of their means.
1646///
1647/// But note that the specified means are only approximate, since the distributions we are sampling
1648/// are truncated geometric, and their exact means are somewhat annoying to deal with. The practical
1649/// implications are that
1650/// - The actual means are slightly lower than the specified means.
1651/// - However, increasing the specified means increases the actual means, so this still works as a
1652/// mechanism for controlling the sci-exponent and precision.
1653/// - The specified sci-exponent mean must be greater than 0 and the precision mean greater than 2,
1654/// but they may be as high as you like.
1655///
1656/// Neither positive not negative zero is generated. `NaN` is not generated either.
1657///
1658/// The output length is infinite.
1659///
1660/// # Expected complexity per iteration
1661/// Constant time and additional memory.
1662///
1663/// # Examples
1664/// ```
1665/// use malachite_base::iterators::prefix_to_string;
1666/// use malachite_base::num::float::NiceFloat;
1667/// use malachite_base::num::random::special_random_nonzero_finite_primitive_floats;
1668/// use malachite_base::random::EXAMPLE_SEED;
1669///
1670/// assert_eq!(
1671/// prefix_to_string(
1672/// special_random_nonzero_finite_primitive_floats::<f32>(EXAMPLE_SEED, 10, 1, 10, 1)
1673/// .map(NiceFloat),
1674/// 20
1675/// ),
1676/// "[-0.6328125, -9.536743e-7, -0.013671875, 0.6875, -70208.0, 0.01550293, -0.028625488, \
1677/// -3.3095703, -5.775879, 0.000034958124, 0.4375, 31678.0, -49152.0, -1.0, 49.885254, \
1678/// -0.40625, -0.0015869141, -1889.5625, -0.14140439, -0.001449585, ...]"
1679/// );
1680/// ```
1681#[inline]
1682pub fn special_random_nonzero_finite_primitive_floats<T: PrimitiveFloat>(
1683 seed: Seed,
1684 mean_sci_exponent_numerator: u64,
1685 mean_sci_exponent_denominator: u64,
1686 mean_precision_numerator: u64,
1687 mean_precision_denominator: u64,
1688) -> SpecialRandomNonzeroFiniteFloats<T> {
1689 SpecialRandomNonzeroFiniteFloats {
1690 bs: random_bools(seed.fork("bs")),
1691 xs: special_random_positive_finite_primitive_floats(
1692 seed.fork("xs"),
1693 mean_sci_exponent_numerator,
1694 mean_sci_exponent_denominator,
1695 mean_precision_numerator,
1696 mean_precision_denominator,
1697 ),
1698 }
1699}
1700
1701/// Generates finite primitive floats.
1702///
1703/// Simpler floats (those with a lower absolute sci-exponent or precision) are more likely to be
1704/// chosen. You can specify the numerator and denominator of the probability that a zero will be
1705/// generated. You can also specify the mean absolute sci-exponent and precision by passing the
1706/// numerators and denominators of their means of the nonzero floats.
1707///
1708/// But note that the specified means are only approximate, since the distributions we are sampling
1709/// are truncated geometric, and their exact means are somewhat annoying to deal with. The practical
1710/// implications are that
1711/// - The actual means are slightly lower than the specified means.
1712/// - However, increasing the specified means increases the actual means, so this still works as a
1713/// mechanism for controlling the sci-exponent and precision.
1714/// - The specified sci-exponent mean must be greater than 0 and the precision mean greater than 2,
1715/// but they may be as high as you like.
1716///
1717/// Positive and negative zero are both generated. `NaN` is not.
1718///
1719/// The output length is infinite.
1720///
1721/// # Expected complexity per iteration
1722/// Constant time and additional memory.
1723///
1724/// # Examples
1725/// ```
1726/// use malachite_base::iterators::prefix_to_string;
1727/// use malachite_base::num::float::NiceFloat;
1728/// use malachite_base::num::random::special_random_finite_primitive_floats;
1729/// use malachite_base::random::EXAMPLE_SEED;
1730///
1731/// assert_eq!(
1732/// prefix_to_string(
1733/// special_random_finite_primitive_floats::<f32>(EXAMPLE_SEED, 10, 1, 10, 1, 1, 10)
1734/// .map(NiceFloat),
1735/// 20
1736/// ),
1737/// "[0.65625, 0.0000014255784, 0.013183594, 0.0, -0.8125, -74240.0, -0.0078125, -0.03060913, \
1738/// 3.331552, 4.75, -0.000038146973, -0.3125, -27136.0, -0.0, -59392.0, -1.75, -41.1875, 0.0, \
1739/// 0.30940247, -0.0009765625, ...]"
1740/// );
1741/// ```
1742#[inline]
1743pub fn special_random_finite_primitive_floats<T: PrimitiveFloat>(
1744 seed: Seed,
1745 mean_sci_exponent_numerator: u64,
1746 mean_sci_exponent_denominator: u64,
1747 mean_precision_numerator: u64,
1748 mean_precision_denominator: u64,
1749 mean_zero_p_numerator: u64,
1750 mean_zero_p_denominator: u64,
1751) -> WithSpecialValues<SpecialRandomNonzeroFiniteFloats<T>> {
1752 with_special_values(
1753 seed,
1754 vec![T::ZERO, T::NEGATIVE_ZERO],
1755 mean_zero_p_numerator,
1756 mean_zero_p_denominator,
1757 &|seed_2| {
1758 special_random_nonzero_finite_primitive_floats(
1759 seed_2,
1760 mean_sci_exponent_numerator,
1761 mean_sci_exponent_denominator,
1762 mean_precision_numerator,
1763 mean_precision_denominator,
1764 )
1765 },
1766 )
1767}
1768
1769/// Generates positive primitive floats.
1770///
1771/// Simpler floats (those with a lower absolute sci-exponent or precision) are more likely to be
1772/// chosen. You can specify the numerator and denominator of the probability that positive infinity
1773/// will be generated. You can also specify the mean absolute sci-exponent and precision by passing
1774/// the numerators and denominators of their means of the finite floats.
1775///
1776/// But note that the specified means are only approximate, since the distributions we are sampling
1777/// are truncated geometric, and their exact means are somewhat annoying to deal with. The practical
1778/// implications are that
1779/// - The actual means are slightly lower than the specified means.
1780/// - However, increasing the specified means increases the actual means, so this still works as a
1781/// mechanism for controlling the sci-exponent and precision.
1782/// - The specified sci-exponent mean must be greater than 0 and the precision mean greater than 2,
1783/// but they may be as high as you like.
1784///
1785/// Positive zero is generated; negative zero is not. `NaN` is not generated either.
1786///
1787/// The output length is infinite.
1788///
1789/// # Expected complexity per iteration
1790/// Constant time and additional memory.
1791///
1792/// # Examples
1793/// ```
1794/// use malachite_base::iterators::prefix_to_string;
1795/// use malachite_base::num::float::NiceFloat;
1796/// use malachite_base::num::random::special_random_positive_primitive_floats;
1797/// use malachite_base::random::EXAMPLE_SEED;
1798///
1799/// assert_eq!(
1800/// prefix_to_string(
1801/// special_random_positive_primitive_floats::<f32>(EXAMPLE_SEED, 10, 1, 10, 1, 1, 10)
1802/// .map(NiceFloat),
1803/// 20
1804/// ),
1805/// "[0.6328125, 9.536743e-7, 0.013671875, Infinity, 0.6875, 70208.0, 0.01550293, \
1806/// 0.028625488, 3.3095703, 5.775879, 0.000034958124, 0.4375, 31678.0, Infinity, 49152.0, \
1807/// 1.0, 49.885254, Infinity, 0.40625, 0.0015869141, ...]"
1808/// );
1809/// ```
1810#[inline]
1811pub fn special_random_positive_primitive_floats<T: PrimitiveFloat>(
1812 seed: Seed,
1813 mean_sci_exponent_numerator: u64,
1814 mean_sci_exponent_denominator: u64,
1815 mean_precision_numerator: u64,
1816 mean_precision_denominator: u64,
1817 mean_special_p_numerator: u64,
1818 mean_special_p_denominator: u64,
1819) -> WithSpecialValue<SpecialRandomPositiveFiniteFloats<T>> {
1820 with_special_value(
1821 seed,
1822 T::INFINITY,
1823 mean_special_p_numerator,
1824 mean_special_p_denominator,
1825 &|seed_2| {
1826 special_random_positive_finite_primitive_floats(
1827 seed_2,
1828 mean_sci_exponent_numerator,
1829 mean_sci_exponent_denominator,
1830 mean_precision_numerator,
1831 mean_precision_denominator,
1832 )
1833 },
1834 )
1835}
1836
1837/// Generates negative primitive floats.
1838///
1839/// Simpler floats (those with a lower absolute sci-exponent or precision) are more likely to be
1840/// chosen. You can specify the numerator and denominator of the probability that negative infinity
1841/// will be generated. You can also specify the mean absolute sci-exponent and precision by passing
1842/// the numerators and denominators of their means of the finite floats.
1843///
1844/// But note that the specified means are only approximate, since the distributions we are sampling
1845/// are truncated geometric, and their exact means are somewhat annoying to deal with. The practical
1846/// implications are that
1847/// - The actual means are slightly lower than the specified means.
1848/// - However, increasing the specified means increases the actual means, so this still works as a
1849/// mechanism for controlling the sci-exponent and precision.
1850/// - The specified sci-exponent mean must be greater than 0 and the precision mean greater than 2,
1851/// but they may be as high as you like.
1852///
1853/// Negative zero is generated; positive zero is not. `NaN` is not generated either.
1854///
1855/// The output length is infinite.
1856///
1857/// # Expected complexity per iteration
1858/// Constant time and additional memory.
1859///
1860/// # Examples
1861/// ```
1862/// use malachite_base::iterators::prefix_to_string;
1863/// use malachite_base::num::float::NiceFloat;
1864/// use malachite_base::num::random::special_random_negative_primitive_floats;
1865/// use malachite_base::random::EXAMPLE_SEED;
1866///
1867/// assert_eq!(
1868/// prefix_to_string(
1869/// special_random_negative_primitive_floats::<f32>(EXAMPLE_SEED, 10, 1, 10, 1, 1, 10)
1870/// .map(NiceFloat),
1871/// 20
1872/// ),
1873/// "[-0.6328125, -9.536743e-7, -0.013671875, -Infinity, -0.6875, -70208.0, -0.01550293, \
1874/// -0.028625488, -3.3095703, -5.775879, -0.000034958124, -0.4375, -31678.0, -Infinity, \
1875/// -49152.0, -1.0, -49.885254, -Infinity, -0.40625, -0.0015869141, ...]"
1876/// );
1877/// ```
1878#[inline]
1879pub fn special_random_negative_primitive_floats<T: PrimitiveFloat>(
1880 seed: Seed,
1881 mean_sci_exponent_numerator: u64,
1882 mean_sci_exponent_denominator: u64,
1883 mean_precision_numerator: u64,
1884 mean_precision_denominator: u64,
1885 mean_special_p_numerator: u64,
1886 mean_special_p_denominator: u64,
1887) -> WithSpecialValue<SpecialRandomNegativeFiniteFloats<T>> {
1888 with_special_value(
1889 seed,
1890 T::NEGATIVE_INFINITY,
1891 mean_special_p_numerator,
1892 mean_special_p_denominator,
1893 &|seed_2| {
1894 special_random_negative_finite_primitive_floats(
1895 seed_2,
1896 mean_sci_exponent_numerator,
1897 mean_sci_exponent_denominator,
1898 mean_precision_numerator,
1899 mean_precision_denominator,
1900 )
1901 },
1902 )
1903}
1904
1905/// Generates nonzero primitive floats.
1906///
1907/// Simpler floats (those with a lower absolute sci-exponent or precision) are more likely to be
1908/// chosen. You can specify the numerator and denominator of the probability that an infinity will
1909/// be generated. You can also specify the mean absolute sci-exponent and precision by passing the
1910/// numerators and denominators of their means of the finite floats.
1911///
1912/// But note that the specified means are only approximate, since the distributions we are sampling
1913/// are truncated geometric, and their exact means are somewhat annoying to deal with. The practical
1914/// implications are that
1915/// - The actual means are slightly lower than the specified means.
1916/// - However, increasing the specified means increases the actual means, so this still works as a
1917/// mechanism for controlling the sci-exponent and precision.
1918/// - The specified sci-exponent mean must be greater than 0 and the precision mean greater than 2,
1919/// but they may be as high as you like.
1920///
1921/// Neither negative not positive zero is generated. `NaN` is not generated either.
1922///
1923/// The output length is infinite.
1924///
1925/// # Expected complexity per iteration
1926/// Constant time and additional memory.
1927///
1928/// # Examples
1929/// ```
1930/// use malachite_base::iterators::prefix_to_string;
1931/// use malachite_base::num::float::NiceFloat;
1932/// use malachite_base::num::random::special_random_nonzero_primitive_floats;
1933/// use malachite_base::random::EXAMPLE_SEED;
1934///
1935/// assert_eq!(
1936/// prefix_to_string(
1937/// special_random_nonzero_primitive_floats::<f32>(EXAMPLE_SEED, 10, 1, 10, 1, 1, 10)
1938/// .map(NiceFloat),
1939/// 20
1940/// ),
1941/// "[0.65625, 0.0000014255784, 0.013183594, Infinity, -0.8125, -74240.0, -0.0078125, \
1942/// -0.03060913, 3.331552, 4.75, -0.000038146973, -0.3125, -27136.0, -Infinity, -59392.0, \
1943/// -1.75, -41.1875, Infinity, 0.30940247, -0.0009765625, ...]"
1944/// );
1945/// ```
1946#[inline]
1947pub fn special_random_nonzero_primitive_floats<T: PrimitiveFloat>(
1948 seed: Seed,
1949 mean_sci_exponent_numerator: u64,
1950 mean_sci_exponent_denominator: u64,
1951 mean_precision_numerator: u64,
1952 mean_precision_denominator: u64,
1953 mean_special_p_numerator: u64,
1954 mean_special_p_denominator: u64,
1955) -> WithSpecialValues<SpecialRandomNonzeroFiniteFloats<T>> {
1956 with_special_values(
1957 seed,
1958 vec![T::INFINITY, T::NEGATIVE_INFINITY],
1959 mean_special_p_numerator,
1960 mean_special_p_denominator,
1961 &|seed_2| {
1962 special_random_nonzero_finite_primitive_floats(
1963 seed_2,
1964 mean_sci_exponent_numerator,
1965 mean_sci_exponent_denominator,
1966 mean_precision_numerator,
1967 mean_precision_denominator,
1968 )
1969 },
1970 )
1971}
1972
1973/// Generates primitive floats.
1974///
1975/// Simpler floats (those with a lower absolute sci-exponent or precision) are more likely to be
1976/// chosen. You can specify the numerator and denominator of the probability that zero, infinity, or
1977/// NaN will be generated. You can also specify the mean absolute sci-exponent and precision by
1978/// passing the numerators and denominators of their means of the finite floats.
1979///
1980/// But note that the specified means are only approximate, since the distributions we are sampling
1981/// are truncated geometric, and their exact means are somewhat annoying to deal with. The practical
1982/// implications are that
1983/// - The actual means are slightly lower than the specified means.
1984/// - However, increasing the specified means increases the actual means, so this still works as a
1985/// mechanism for controlling the sci-exponent and precision.
1986/// - The specified sci-exponent mean must be greater than 0 and the precision mean greater than 2,
1987/// but they may be as high as you like.
1988///
1989/// The output length is infinite.
1990///
1991/// # Expected complexity per iteration
1992/// Constant time and additional memory.
1993///
1994/// # Examples
1995/// ```
1996/// use malachite_base::iterators::prefix_to_string;
1997/// use malachite_base::num::float::NiceFloat;
1998/// use malachite_base::num::random::special_random_primitive_floats;
1999/// use malachite_base::random::EXAMPLE_SEED;
2000///
2001/// assert_eq!(
2002/// prefix_to_string(
2003/// special_random_primitive_floats::<f32>(EXAMPLE_SEED, 10, 1, 10, 1, 1, 10)
2004/// .map(NiceFloat),
2005/// 20
2006/// ),
2007/// "[0.65625, 0.0000014255784, 0.013183594, Infinity, -0.8125, -74240.0, -0.0078125, \
2008/// -0.03060913, 3.331552, 4.75, -0.000038146973, -0.3125, -27136.0, Infinity, -59392.0, \
2009/// -1.75, -41.1875, Infinity, 0.30940247, -0.0009765625, ...]"
2010/// );
2011/// ```
2012#[inline]
2013pub fn special_random_primitive_floats<T: PrimitiveFloat>(
2014 seed: Seed,
2015 mean_sci_exponent_numerator: u64,
2016 mean_sci_exponent_denominator: u64,
2017 mean_precision_numerator: u64,
2018 mean_precision_denominator: u64,
2019 mean_special_p_numerator: u64,
2020 mean_special_p_denominator: u64,
2021) -> WithSpecialValues<SpecialRandomNonzeroFiniteFloats<T>> {
2022 with_special_values(
2023 seed,
2024 vec![T::ZERO, T::NEGATIVE_ZERO, T::INFINITY, T::NEGATIVE_INFINITY, T::NAN],
2025 mean_special_p_numerator,
2026 mean_special_p_denominator,
2027 &|seed_2| {
2028 special_random_nonzero_finite_primitive_floats(
2029 seed_2,
2030 mean_sci_exponent_numerator,
2031 mean_sci_exponent_denominator,
2032 mean_precision_numerator,
2033 mean_precision_denominator,
2034 )
2035 },
2036 )
2037}
2038
2039// normalized sci_exponent and raw mantissas in input, adjusted sci_exponent and mantissas in output
2040fn mantissas_inclusive<T: PrimitiveFloat>(
2041 mut sci_exponent: i64,
2042 mut am: u64,
2043 mut bm: u64,
2044 precision: u64,
2045) -> Option<(i64, u64, u64)> {
2046 assert_ne!(precision, 0);
2047 let p: u64 = if sci_exponent < T::MIN_NORMAL_EXPONENT {
2048 let ab = am.significant_bits();
2049 let bb = bm.significant_bits();
2050 assert_eq!(ab, bb);
2051 ab - precision
2052 } else {
2053 am.set_bit(T::MANTISSA_WIDTH);
2054 bm.set_bit(T::MANTISSA_WIDTH);
2055 T::MANTISSA_WIDTH + 1 - precision
2056 };
2057 let mut lo = am.shr_round(p, Up).0;
2058 if lo.even() {
2059 lo += 1;
2060 }
2061 let mut hi = bm.shr_round(p, Down).0;
2062 if hi == 0 {
2063 return None;
2064 } else if hi.even() {
2065 hi -= 1;
2066 }
2067 if sci_exponent >= T::MIN_NORMAL_EXPONENT {
2068 sci_exponent -= i64::wrapping_from(T::MANTISSA_WIDTH);
2069 }
2070 sci_exponent += i64::wrapping_from(p);
2071 if lo > hi {
2072 None
2073 } else {
2074 Some((sci_exponent, lo >> 1, hi >> 1))
2075 }
2076}
2077
2078#[doc(hidden)]
2079#[derive(Clone, Debug)]
2080pub struct SpecialRandomPositiveFiniteFloatInclusiveRange<T: PrimitiveFloat> {
2081 phantom: PhantomData<*const T>,
2082 am: u64, // raw mantissa
2083 bm: u64,
2084 ae: i64, // sci_exponent
2085 be: i64,
2086 sci_exponents: GeometricRandomSignedRange<i64>,
2087 precision_range_map: HashMap<i64, Vec<(i64, u64, u64)>>,
2088 precision_indices: GeometricRandomNaturalValues<usize>,
2089 ranges: VariableRangeGenerator,
2090}
2091
2092impl<T: PrimitiveFloat> Iterator for SpecialRandomPositiveFiniteFloatInclusiveRange<T> {
2093 type Item = T;
2094
2095 fn next(&mut self) -> Option<T> {
2096 let sci_exponent = self.sci_exponents.next().unwrap();
2097 let ae = self.ae;
2098 let be = self.be;
2099 let am = self.am;
2100 let bm = self.bm;
2101 let precision_ranges = self
2102 .precision_range_map
2103 .entry(sci_exponent)
2104 .or_insert_with(|| {
2105 let am = if sci_exponent == ae {
2106 am
2107 } else {
2108 T::from_integer_mantissa_and_exponent(1, sci_exponent)
2109 .unwrap()
2110 .raw_mantissa()
2111 };
2112 let bm = if sci_exponent == be {
2113 bm
2114 } else {
2115 T::from_integer_mantissa_and_exponent(1, sci_exponent + 1)
2116 .unwrap()
2117 .next_lower()
2118 .raw_mantissa()
2119 };
2120 (1..=T::max_precision_for_sci_exponent(sci_exponent))
2121 .filter_map(|p| mantissas_inclusive::<T>(sci_exponent, am, bm, p))
2122 .collect_vec()
2123 });
2124 assert!(!precision_ranges.is_empty());
2125 let i = self.precision_indices.next().unwrap() % precision_ranges.len();
2126 let t = precision_ranges[i];
2127 let mantissa = (self.ranges.next_in_inclusive_range(t.1, t.2) << 1) | 1;
2128 Some(T::from_integer_mantissa_and_exponent(mantissa, t.0).unwrap())
2129 }
2130}
2131
2132fn special_random_positive_finite_float_inclusive_range<T: PrimitiveFloat>(
2133 seed: Seed,
2134 a: T,
2135 b: T,
2136 mean_sci_exponent_numerator: u64,
2137 mean_sci_exponent_denominator: u64,
2138 mean_precision_numerator: u64,
2139 mean_precision_denominator: u64,
2140) -> SpecialRandomPositiveFiniteFloatInclusiveRange<T> {
2141 assert!(a.is_finite());
2142 assert!(b.is_finite());
2143 assert!(a > T::ZERO);
2144 assert!(a <= b);
2145 let (am, ae) = a.raw_mantissa_and_exponent();
2146 let (bm, be) = b.raw_mantissa_and_exponent();
2147 let ae = if ae == 0 {
2148 i64::wrapping_from(am.significant_bits()) + T::MIN_EXPONENT - 1
2149 } else {
2150 i64::wrapping_from(ae) - T::MAX_EXPONENT
2151 };
2152 let be = if be == 0 {
2153 i64::wrapping_from(bm.significant_bits()) + T::MIN_EXPONENT - 1
2154 } else {
2155 i64::wrapping_from(be) - T::MAX_EXPONENT
2156 };
2157 SpecialRandomPositiveFiniteFloatInclusiveRange {
2158 phantom: PhantomData,
2159 am,
2160 bm,
2161 ae,
2162 be,
2163 sci_exponents: geometric_random_signed_inclusive_range(
2164 seed.fork("exponents"),
2165 ae,
2166 be,
2167 mean_sci_exponent_numerator,
2168 mean_sci_exponent_denominator,
2169 ),
2170 precision_range_map: HashMap::new(),
2171 precision_indices: geometric_random_unsigneds(
2172 seed.fork("precisions"),
2173 mean_precision_numerator,
2174 mean_precision_denominator,
2175 ),
2176 ranges: VariableRangeGenerator::new(seed.fork("ranges")),
2177 }
2178}
2179
2180#[allow(clippy::large_enum_variant)]
2181#[doc(hidden)]
2182#[derive(Clone, Debug)]
2183pub enum SpecialRandomFiniteFloatInclusiveRange<T: PrimitiveFloat> {
2184 AllPositive(SpecialRandomPositiveFiniteFloatInclusiveRange<T>),
2185 AllNegative(SpecialRandomPositiveFiniteFloatInclusiveRange<T>),
2186 PositiveAndNegative(
2187 RandomBools,
2188 SpecialRandomPositiveFiniteFloatInclusiveRange<T>,
2189 SpecialRandomPositiveFiniteFloatInclusiveRange<T>,
2190 ),
2191}
2192
2193impl<T: PrimitiveFloat> Iterator for SpecialRandomFiniteFloatInclusiveRange<T> {
2194 type Item = T;
2195
2196 fn next(&mut self) -> Option<T> {
2197 match self {
2198 Self::AllPositive(xs) => xs.next(),
2199 Self::AllNegative(xs) => xs.next().map(|x| -x),
2200 Self::PositiveAndNegative(bs, xs, ys) => {
2201 if bs.next().unwrap() {
2202 xs.next()
2203 } else {
2204 ys.next().map(|x| -x)
2205 }
2206 }
2207 }
2208 }
2209}
2210
2211fn special_random_finite_float_inclusive_range<T: PrimitiveFloat>(
2212 seed: Seed,
2213 a: T,
2214 b: T,
2215 mean_sci_exponent_numerator: u64,
2216 mean_sci_exponent_denominator: u64,
2217 mean_precision_numerator: u64,
2218 mean_precision_denominator: u64,
2219) -> SpecialRandomFiniteFloatInclusiveRange<T> {
2220 assert!(a.is_finite());
2221 assert!(b.is_finite());
2222 assert_ne!(a, T::ZERO);
2223 assert_ne!(b, T::ZERO);
2224 assert!(a <= b);
2225 if a > T::ZERO {
2226 SpecialRandomFiniteFloatInclusiveRange::AllPositive(
2227 special_random_positive_finite_float_inclusive_range(
2228 seed,
2229 a,
2230 b,
2231 mean_sci_exponent_numerator,
2232 mean_sci_exponent_denominator,
2233 mean_precision_numerator,
2234 mean_precision_denominator,
2235 ),
2236 )
2237 } else if b < T::ZERO {
2238 SpecialRandomFiniteFloatInclusiveRange::AllNegative(
2239 special_random_positive_finite_float_inclusive_range(
2240 seed,
2241 -b,
2242 -a,
2243 mean_sci_exponent_numerator,
2244 mean_sci_exponent_denominator,
2245 mean_precision_numerator,
2246 mean_precision_denominator,
2247 ),
2248 )
2249 } else {
2250 SpecialRandomFiniteFloatInclusiveRange::PositiveAndNegative(
2251 random_bools(seed.fork("bs")),
2252 special_random_positive_finite_float_inclusive_range(
2253 seed,
2254 T::MIN_POSITIVE_SUBNORMAL,
2255 b,
2256 mean_sci_exponent_numerator,
2257 mean_sci_exponent_denominator,
2258 mean_precision_numerator,
2259 mean_precision_denominator,
2260 ),
2261 special_random_positive_finite_float_inclusive_range(
2262 seed,
2263 T::MIN_POSITIVE_SUBNORMAL,
2264 -a,
2265 mean_sci_exponent_numerator,
2266 mean_sci_exponent_denominator,
2267 mean_precision_numerator,
2268 mean_precision_denominator,
2269 ),
2270 )
2271 }
2272}
2273
2274/// Generates random primitive floats in a range.
2275///
2276/// This `enum` is created by [`special_random_primitive_float_range`]; see its documentation for
2277/// more.
2278#[allow(clippy::large_enum_variant)]
2279#[derive(Clone, Debug)]
2280pub enum SpecialRandomFloatInclusiveRange<T: PrimitiveFloat> {
2281 OnlySpecial(RandomValuesFromVec<T>),
2282 NoSpecial(Box<SpecialRandomFiniteFloatInclusiveRange<T>>),
2283 Special(Box<WithSpecialValues<SpecialRandomFiniteFloatInclusiveRange<T>>>),
2284}
2285
2286impl<T: PrimitiveFloat> Iterator for SpecialRandomFloatInclusiveRange<T> {
2287 type Item = T;
2288
2289 fn next(&mut self) -> Option<T> {
2290 match self {
2291 Self::OnlySpecial(xs) => xs.next(),
2292 Self::NoSpecial(xs) => xs.next(),
2293 Self::Special(xs) => xs.next(),
2294 }
2295 }
2296}
2297
2298/// Generates random primitive floats in the half-open interval $[a, b)$.
2299///
2300/// Simpler floats (those with a lower absolute sci-exponent or precision) are more likely to be
2301/// chosen. You can specify the numerator and denominator of the probability that any special values
2302/// (positive or negative zero or infinity) are generated, provided that they are in the range. You
2303/// can also specify the mean absolute sci-exponent and precision by passing the numerators and
2304/// denominators of their means of the finite floats.
2305///
2306/// But note that the means are only approximate, since the distributions we are sampling are
2307/// truncated geometric, and their exact means are somewhat annoying to deal with. The practical
2308/// implications are that
2309/// - The actual mean is lower than the specified means.
2310/// - However, increasing the approximate mean increases the actual means, so this still works as a
2311/// mechanism for controlling the sci-exponent and precision.
2312/// - The specified sci-exponent mean must be greater the smallest absolute of any sci-exponent of a
2313/// float in the range, and the precision mean greater than 2, but they may be as high as you
2314/// like.
2315///
2316/// But note that the specified means are only approximate, since the distributions we are sampling
2317/// are truncated geometric, and their exact means are somewhat annoying to deal with. The practical
2318/// implications are that
2319/// - The actual means are slightly lower than the specified means.
2320/// - However, increasing the specified means increases the actual means, so this still works as a
2321/// mechanism for controlling the sci-exponent and precision.
2322/// - The specified sci-exponent mean must be greater the smallest absolute value of any
2323/// sci-exponent of a float in the range, and the precision mean greater than 2, but they may be
2324/// as high as you like.
2325///
2326/// `NaN` is never generated.
2327///
2328/// The output length is infinite.
2329///
2330/// # Expected complexity per iteration
2331/// Constant time and additional memory.
2332///
2333/// # Panics
2334/// Panics if $a$ or $b$ are `NaN`, if $a$ is greater than or equal to $b$ in the `NiceFloat`
2335/// ordering, if any of the denominators are zero, if the special probability is greater than 1, if
2336/// the mean precision is less than 2, or if the mean sci-exponent is less than or equal to the
2337/// minimum absolute value of any sci-exponent in the range.
2338///
2339/// # Examples
2340/// ```
2341/// use malachite_base::iterators::prefix_to_string;
2342/// use malachite_base::num::float::NiceFloat;
2343/// use malachite_base::num::random::special_random_primitive_float_range;
2344/// use malachite_base::random::EXAMPLE_SEED;
2345///
2346/// assert_eq!(
2347/// prefix_to_string(
2348/// special_random_primitive_float_range::<f32>(
2349/// EXAMPLE_SEED,
2350/// core::f32::consts::E,
2351/// core::f32::consts::PI,
2352/// 10,
2353/// 1,
2354/// 10,
2355/// 1,
2356/// 1,
2357/// 100
2358/// )
2359/// .map(NiceFloat),
2360/// 20
2361/// ),
2362/// "[2.9238281, 2.953125, 3.0, 2.8671875, 2.8125, 3.125, 3.015625, 2.8462658, 3.140625, \
2363/// 2.875, 3.0, 2.75, 3.0, 2.71875, 2.75, 3.0214844, 2.970642, 3.0179443, 2.968872, 2.75, ...]"
2364/// );
2365/// ```
2366pub fn special_random_primitive_float_range<T: PrimitiveFloat>(
2367 seed: Seed,
2368 a: T,
2369 b: T,
2370 mean_sci_exponent_numerator: u64,
2371 mean_sci_exponent_denominator: u64,
2372 mean_precision_numerator: u64,
2373 mean_precision_denominator: u64,
2374 mean_special_p_numerator: u64,
2375 mean_special_p_denominator: u64,
2376) -> SpecialRandomFloatInclusiveRange<T> {
2377 assert!(!a.is_nan());
2378 assert!(!b.is_nan());
2379 assert!(NiceFloat(a) < NiceFloat(b));
2380 special_random_primitive_float_inclusive_range(
2381 seed,
2382 a,
2383 b.next_lower(),
2384 mean_sci_exponent_numerator,
2385 mean_sci_exponent_denominator,
2386 mean_precision_numerator,
2387 mean_precision_denominator,
2388 mean_special_p_numerator,
2389 mean_special_p_denominator,
2390 )
2391}
2392
2393/// Generates random primitive floats in the closed interval $[a, b]$.
2394///
2395/// Simpler floats (those with a lower absolute sci-exponent or precision) are more likely to be
2396/// chosen. You can specify the numerator and denominator of the probability that any special values
2397/// (positive or negative zero or infinity) are generated, provided that they are in the range. You
2398/// can also specify the mean absolute sci-exponent and precision by passing the numerators and
2399/// denominators of their means of the finite floats.
2400///
2401/// But note that the specified means are only approximate, since the distributions we are sampling
2402/// are truncated geometric, and their exact means are somewhat annoying to deal with. The practical
2403/// implications are that
2404/// - The actual means are slightly lower than the specified means.
2405/// - However, increasing the specified means increases the actual means, so this still works as a
2406/// mechanism for controlling the sci-exponent and precision.
2407/// - The specified sci-exponent mean must be greater the smallest absolute value of any
2408/// sci-exponent of a float in the range, and the precision mean greater than 2, but they may be
2409/// as high as you like.
2410///
2411/// `NaN` is never generated.
2412///
2413/// The output length is infinite.
2414///
2415/// # Expected complexity per iteration
2416/// Constant time and additional memory.
2417///
2418/// # Panics
2419/// Panics if $a$ or $b$ are `NaN`, if $a$ is greater than $b$ in the `NiceFloat` ordering, if any
2420/// of the denominators are zero, if the special probability is greater than 1, if the mean
2421/// precision is less than 2, or if the mean sci-exponent is less than or equal to the minimum
2422/// absolute value of any sci-exponent in the range.
2423///
2424/// # Examples
2425/// ```
2426/// use malachite_base::iterators::prefix_to_string;
2427/// use malachite_base::num::float::NiceFloat;
2428/// use malachite_base::num::random::special_random_primitive_float_inclusive_range;
2429/// use malachite_base::random::EXAMPLE_SEED;
2430///
2431/// assert_eq!(
2432/// prefix_to_string(
2433/// special_random_primitive_float_inclusive_range::<f32>(
2434/// EXAMPLE_SEED,
2435/// core::f32::consts::E,
2436/// core::f32::consts::PI,
2437/// 10,
2438/// 1,
2439/// 10,
2440/// 1,
2441/// 1,
2442/// 100
2443/// )
2444/// .map(NiceFloat),
2445/// 20
2446/// ),
2447/// "[2.9238281, 2.953125, 3.0, 2.8671875, 2.8125, 3.125, 3.015625, 2.8462658, 3.140625, \
2448/// 2.875, 3.0, 2.75, 3.0, 2.71875, 2.75, 3.0214844, 2.970642, 3.0179443, 2.968872, 2.75, ...]"
2449/// );
2450/// ```
2451pub fn special_random_primitive_float_inclusive_range<T: PrimitiveFloat>(
2452 seed: Seed,
2453 mut a: T,
2454 mut b: T,
2455 mean_sci_exponent_numerator: u64,
2456 mean_sci_exponent_denominator: u64,
2457 mean_precision_numerator: u64,
2458 mean_precision_denominator: u64,
2459 mean_special_p_numerator: u64,
2460 mean_special_p_denominator: u64,
2461) -> SpecialRandomFloatInclusiveRange<T> {
2462 assert!(!a.is_nan());
2463 assert!(!b.is_nan());
2464 assert!(NiceFloat(a) <= NiceFloat(b));
2465 assert_ne!(mean_special_p_denominator, 0);
2466 assert!(mean_special_p_numerator <= mean_special_p_denominator);
2467 assert_ne!(mean_precision_denominator, 0);
2468 assert!(mean_precision_numerator > mean_precision_denominator);
2469 let only_special =
2470 a == T::INFINITY || b == T::NEGATIVE_INFINITY || a == T::ZERO && b == T::ZERO;
2471 let mut special_values = Vec::new();
2472 if a == T::NEGATIVE_INFINITY {
2473 special_values.push(a);
2474 a = -T::MAX_FINITE;
2475 }
2476 if b == T::INFINITY {
2477 special_values.push(b);
2478 b = T::MAX_FINITE;
2479 }
2480 if NiceFloat(a) <= NiceFloat(T::NEGATIVE_ZERO) && NiceFloat(b) >= NiceFloat(T::NEGATIVE_ZERO) {
2481 special_values.push(T::NEGATIVE_ZERO);
2482 }
2483 if NiceFloat(a) <= NiceFloat(T::ZERO) && NiceFloat(b) >= NiceFloat(T::ZERO) {
2484 special_values.push(T::ZERO);
2485 }
2486 if a == T::ZERO {
2487 a = T::MIN_POSITIVE_SUBNORMAL;
2488 }
2489 if b == T::ZERO {
2490 b = -T::MIN_POSITIVE_SUBNORMAL;
2491 }
2492 if only_special {
2493 SpecialRandomFloatInclusiveRange::OnlySpecial(random_values_from_vec(seed, special_values))
2494 } else if special_values.is_empty() {
2495 SpecialRandomFloatInclusiveRange::NoSpecial(Box::new(
2496 special_random_finite_float_inclusive_range(
2497 seed,
2498 a,
2499 b,
2500 mean_sci_exponent_numerator,
2501 mean_sci_exponent_denominator,
2502 mean_precision_numerator,
2503 mean_precision_denominator,
2504 ),
2505 ))
2506 } else {
2507 SpecialRandomFloatInclusiveRange::Special(Box::new(with_special_values(
2508 seed,
2509 special_values,
2510 mean_special_p_numerator,
2511 mean_special_p_denominator,
2512 &|seed| {
2513 special_random_finite_float_inclusive_range(
2514 seed,
2515 a,
2516 b,
2517 mean_sci_exponent_numerator,
2518 mean_sci_exponent_denominator,
2519 mean_precision_numerator,
2520 mean_precision_denominator,
2521 )
2522 },
2523 )))
2524 }
2525}
2526
2527/// Generates unsigneds sampled from ranges. A single generator can sample from different ranges of
2528/// different types.
2529///
2530/// This `struct` is created by [`VariableRangeGenerator::new`]; see its documentation for more.
2531#[derive(Clone, Debug)]
2532pub struct VariableRangeGenerator {
2533 xs: RandomPrimitiveInts<u32>,
2534 x: u32,
2535 in_inner_loop: bool,
2536 remaining_x_bits: u64,
2537}
2538
2539impl VariableRangeGenerator {
2540 /// Generates unsigneds sampled from ranges. A single generator can sample from different ranges
2541 /// of different types.
2542 ///
2543 /// If you only need to generate values from a single range, it is slightly more efficient to
2544 /// use [`random_unsigned_bit_chunks`], [`random_unsigneds_less_than`],
2545 /// [`random_unsigned_range`], or [`random_unsigned_inclusive_range`].
2546 ///
2547 /// # Worst-case complexity
2548 /// Constant time and additional memory.
2549 ///
2550 /// # Examples
2551 /// ```
2552 /// use malachite_base::num::random::VariableRangeGenerator;
2553 /// use malachite_base::random::EXAMPLE_SEED;
2554 ///
2555 /// let mut generator = VariableRangeGenerator::new(EXAMPLE_SEED);
2556 /// assert_eq!(generator.next_bit_chunk::<u16>(10), 881);
2557 /// assert_eq!(generator.next_less_than::<u8>(100), 34);
2558 /// assert_eq!(generator.next_in_range::<u32>(10, 20), 16);
2559 /// assert_eq!(generator.next_in_inclusive_range::<u64>(10, 20), 14);
2560 /// ```
2561 pub fn new(seed: Seed) -> Self {
2562 Self {
2563 xs: random_primitive_ints(seed),
2564 x: 0,
2565 in_inner_loop: false,
2566 remaining_x_bits: 0,
2567 }
2568 }
2569
2570 /// Uniformly generates a `bool`.
2571 ///
2572 /// $$
2573 /// $P(\text{false}) = P(\text{true}) = \frac{1}{2}$.
2574 /// $$
2575 ///
2576 /// # Worst-case complexity
2577 /// Constant time and additional memory.
2578 ///
2579 /// # Examples
2580 /// ```
2581 /// use malachite_base::num::random::VariableRangeGenerator;
2582 /// use malachite_base::random::EXAMPLE_SEED;
2583 ///
2584 /// let mut xs = Vec::with_capacity(10);
2585 /// let mut generator = VariableRangeGenerator::new(EXAMPLE_SEED);
2586 /// for _ in 0..10 {
2587 /// xs.push(generator.next_bool());
2588 /// }
2589 /// assert_eq!(
2590 /// xs,
2591 /// &[true, false, true, false, true, true, true, true, true, false]
2592 /// );
2593 /// ```
2594 #[inline]
2595 pub fn next_bool(&mut self) -> bool {
2596 self.xs.next().unwrap().odd()
2597 }
2598
2599 /// Uniformly generates an unsigned integer with up to some number of bits.
2600 ///
2601 /// $$
2602 /// P(x) = \\begin{cases}
2603 /// 2^{-c} & \text{if} \\quad 0 \\leq x < 2^c, \\\\
2604 /// 0 & \text{if} \\quad \\text{otherwise,}
2605 /// \\end{cases}
2606 /// $$
2607 /// where $c$ is `chunk_size`.
2608 ///
2609 /// # Worst-case complexity
2610 /// $T(n) = O(n)$
2611 ///
2612 /// $M(n) = O(1)$
2613 ///
2614 /// where $T$ is time, $M$ is additional memory, and $n$ is `chunk_size`.
2615 ///
2616 /// # Panics
2617 /// Panics if `chunk_size` is zero or greater than the width of the type.
2618 ///
2619 /// # Examples
2620 /// ```
2621 /// use malachite_base::num::random::VariableRangeGenerator;
2622 /// use malachite_base::random::EXAMPLE_SEED;
2623 ///
2624 /// let mut xs = Vec::with_capacity(10);
2625 /// let mut generator = VariableRangeGenerator::new(EXAMPLE_SEED);
2626 /// for _ in 0..10 {
2627 /// xs.push(generator.next_bit_chunk::<u8>(3));
2628 /// }
2629 /// assert_eq!(xs, &[1, 6, 5, 7, 6, 3, 1, 2, 4, 5]);
2630 /// ```
2631 pub fn next_bit_chunk<T: PrimitiveUnsigned>(&mut self, chunk_size: u64) -> T {
2632 assert_ne!(chunk_size, 0);
2633 assert!(chunk_size <= T::WIDTH);
2634 let mut y = T::ZERO;
2635 let mut remaining_y_bits = chunk_size;
2636 loop {
2637 if !self.in_inner_loop {
2638 self.x = self.xs.next().unwrap();
2639 self.remaining_x_bits = u32::WIDTH;
2640 self.in_inner_loop = true;
2641 }
2642 while self.remaining_x_bits != 0 {
2643 let y_index = chunk_size - remaining_y_bits;
2644 if self.remaining_x_bits <= remaining_y_bits {
2645 y |= T::wrapping_from(self.x) << y_index;
2646 remaining_y_bits -= self.remaining_x_bits;
2647 self.remaining_x_bits = 0;
2648 } else {
2649 y |= T::wrapping_from(self.x).mod_power_of_2(remaining_y_bits) << y_index;
2650 self.x >>= remaining_y_bits;
2651 self.remaining_x_bits -= remaining_y_bits;
2652 remaining_y_bits = 0;
2653 }
2654 if remaining_y_bits == 0 {
2655 return y;
2656 }
2657 }
2658 self.in_inner_loop = false;
2659 }
2660 }
2661
2662 /// Uniformly generates a random unsigned integer less than a positive limit.
2663 ///
2664 /// $$
2665 /// P(x) = \\begin{cases}
2666 /// \frac{1}{\\ell} & \text{if} \\quad x < \\ell \\\\
2667 /// 0 & \\text{otherwise}
2668 /// \\end{cases}
2669 /// $$
2670 /// where $\ell$ is `limit`.
2671 ///
2672 /// # Expected complexity
2673 /// $T(n) = O(n)$
2674 ///
2675 /// $M(n) = O(1)$
2676 ///
2677 /// where $T$ is time, $M$ is additional memory, and $n$ is `limit.significant_bits()`. Each
2678 /// rejection-sampling trial rejects with probability less than $1/2$, so the expected number of
2679 /// trials is $O(1)$, but the worst case is unbounded.
2680 ///
2681 /// # Panics
2682 /// Panics if `limit` is 0.
2683 ///
2684 /// # Examples
2685 /// ```
2686 /// use malachite_base::num::random::VariableRangeGenerator;
2687 /// use malachite_base::random::EXAMPLE_SEED;
2688 ///
2689 /// let mut xs = Vec::with_capacity(10);
2690 /// let mut generator = VariableRangeGenerator::new(EXAMPLE_SEED);
2691 /// for _ in 0..10 {
2692 /// xs.push(generator.next_less_than(10u8));
2693 /// }
2694 /// assert_eq!(xs, &[1, 7, 5, 4, 6, 4, 2, 8, 1, 7]);
2695 /// ```
2696 pub fn next_less_than<T: PrimitiveUnsigned>(&mut self, limit: T) -> T {
2697 assert_ne!(limit, T::ZERO);
2698 if limit == T::ONE {
2699 T::ZERO
2700 } else {
2701 let chunk_size = limit.ceiling_log_base_2();
2702 loop {
2703 let x = self.next_bit_chunk(chunk_size);
2704 if x < limit {
2705 return x;
2706 }
2707 }
2708 }
2709 }
2710
2711 /// Uniformly generates a random unsigned integer in the half-open interval $[a, b)$.
2712 ///
2713 /// $a$ must be less than $b$. This function cannot create a range that includes `T::MAX`; for
2714 /// that, use [`next_in_inclusive_range`](Self::next_in_inclusive_range).
2715 ///
2716 /// $$
2717 /// P(x) = \\begin{cases}
2718 /// \frac{1}{b-a} & \text{if} \\quad a \leq x < b, \\\\
2719 /// 0 & \\text{otherwise.}
2720 /// \\end{cases}
2721 /// $$
2722 ///
2723 /// # Expected complexity
2724 /// $T(n) = O(n)$
2725 ///
2726 /// $M(n) = O(1)$
2727 ///
2728 /// where $T$ is time, $M$ is additional memory, and $n$ is `(b - a).significant_bits()`; the
2729 /// worst case is unbounded, as with [`next_less_than`](Self::next_less_than).
2730 ///
2731 /// # Panics
2732 /// Panics if $a \geq b$.
2733 ///
2734 /// # Examples
2735 /// ```
2736 /// use malachite_base::num::random::VariableRangeGenerator;
2737 /// use malachite_base::random::EXAMPLE_SEED;
2738 ///
2739 /// let mut xs = Vec::with_capacity(10);
2740 /// let mut generator = VariableRangeGenerator::new(EXAMPLE_SEED);
2741 /// for _ in 0..10 {
2742 /// xs.push(generator.next_in_range(10u8, 20));
2743 /// }
2744 /// assert_eq!(xs, &[11, 17, 15, 14, 16, 14, 12, 18, 11, 17]);
2745 /// ```
2746 pub fn next_in_range<T: PrimitiveUnsigned>(&mut self, a: T, b: T) -> T {
2747 self.next_less_than(b - a) + a
2748 }
2749
2750 /// Uniformly generates a random unsigned integer in the closed interval $[a, b]$.
2751 ///
2752 /// $a$ must be less than or equal to $b$.
2753 ///
2754 /// $$
2755 /// P(x) = \\begin{cases}
2756 /// \frac{1}{b-a+1} & \text{if} \\quad a \leq x \leq b, \\\\
2757 /// 0 & \\text{otherwise.}
2758 /// \\end{cases}
2759 /// $$
2760 ///
2761 /// # Expected complexity
2762 /// $T(n) = O(n)$
2763 ///
2764 /// $M(n) = O(1)$
2765 ///
2766 /// where $T$ is time, $M$ is additional memory, and $n$ is the number of significant bits of
2767 /// the range's width; the worst case is unbounded, as with
2768 /// [`next_less_than`](Self::next_less_than).
2769 ///
2770 /// # Panics
2771 /// Panics if $a > b$.
2772 ///
2773 /// # Examples
2774 /// ```
2775 /// use malachite_base::num::random::VariableRangeGenerator;
2776 /// use malachite_base::random::EXAMPLE_SEED;
2777 ///
2778 /// let mut xs = Vec::with_capacity(10);
2779 /// let mut generator = VariableRangeGenerator::new(EXAMPLE_SEED);
2780 /// for _ in 0..10 {
2781 /// xs.push(generator.next_in_inclusive_range(10u8, 19));
2782 /// }
2783 /// assert_eq!(xs, &[11, 17, 15, 14, 16, 14, 12, 18, 11, 17]);
2784 /// ```
2785 pub fn next_in_inclusive_range<T: PrimitiveUnsigned>(&mut self, a: T, b: T) -> T {
2786 if a == T::ZERO && b == T::MAX {
2787 self.next_bit_chunk(T::WIDTH)
2788 } else {
2789 self.next_less_than(b - a + T::ONE) + a
2790 }
2791 }
2792}
2793
2794/// Iterators that generate primitive integers from geometric-like distributions.
2795pub mod geometric;
2796
2797/// Iterators that generate primitive integers that tend to have long runs of binary 0s and 1s.
2798///
2799/// Integers with long runs of 0s and 1s are good for testing; they're more likely to result in
2800/// carries and borrows than uniformly random integers. This idea was inspired by GMP's
2801/// `mpz_rrandomb` function, although striped integer generators are more general: they can also
2802/// produce integers with runs that are shorter than average, so that they tend to contain
2803/// alternating bits like $1010101$.
2804///
2805/// Let the average length of a run of 0s and 1s be $m$. The functions in this module allow the user
2806/// to specify a rational $m$ through the parameters `m_numerator` and `m_denominator`. Since any
2807/// binary sequence has an average run length of at least 1, $m$ must be at least 1; but if it is
2808/// exactly 1 then the sequence is strictly alternating and no longer random, so 1 is not allowed
2809/// either. if $m$ is between 1 and 2, the sequence is less likely to have two equal adjacent bits
2810/// than a uniformly random sequence. If $m$ is 2, the sequence is uniformly random. If $m$ is
2811/// greater than 2 (the most useful case), the sequence tends to have long runs of 0s and 1s.
2812///
2813/// # Details
2814///
2815/// A random striped sequence with parameter $m \geq 1$ is an infinite sequence of bits, defined as
2816/// follows. The first bit is 0 or 1 with equal probability. Every subsequent bit has a $1/m$
2817/// probability of being different than the preceding bit. Notice that every sequence has an equal
2818/// probability as its negation. Also, if $m > 1$, any sequence has a nonzero probability of
2819/// occurring.
2820///
2821/// * $m=1$ is disallowed. If it were allowed, the sequence would be either
2822/// $01010101010101010101\ldots$ or $10101010101010101010\ldots$.
2823/// * If $1<m<2$, the sequence tends to alternate between 0 and 1 more often than a uniformly random
2824/// sequence. A sample sequence with $m=33/32$ is
2825/// $1010101010101010101010110101010101010101\ldots$.
2826/// * If $m=2$, the sequence is uniformly random. A sample sequence with $m=2$ is
2827/// $1100110001101010100101101001000001100001\ldots$.
2828/// * If $m>2$, the sequence tends to have longer runs of 0s and 1s than a uniformly random
2829/// sequence. A sample sequence with $m=32$ is $1111111111111111110000000011111111111111\ldots$.
2830///
2831/// An alternative way to generate a striped sequence is to start with 0 or 1 with equal probability
2832/// and then determine the length of each block of equal bits using a geometric distribution with
2833/// mean $m$. In practice, this isn't any more efficient than the naive algorithm.
2834///
2835/// We can generate a random striped unsigned integer of type `T` by taking the first $W$ bits of a
2836/// striped sequence. Fixing the parameter $m$ defines a distribution over `T`s. A few things can be
2837/// said about the probability $P_m(n)$ of an unsigned integer $n$ of width $W$ being generated:
2838/// * $P_m(n) = P_m(\lnot n)$
2839/// * $P_m(0) = P_m(2^W-1) = \frac{1}{2} \left ( 1-\frac{1}{m} \right )^{W-1}$. If $m>2$, this is
2840/// the maximum probability achieved; if $m<2$, the minimum.
2841/// * $P_m(\lfloor 2^W/3 \rfloor) = P_m(\lfloor 2^{W+1}/3 \rfloor) = 1/(2m^{W-1})$. If $m>2$, this
2842/// is the minimum probability achieved; if $m<2$, the maximum.
2843/// * Because of these distributions' symmetry, their mean is $(2^W-1)/2$ and their skewness is 0.
2844/// It's hard to say anything about their standard deviations or excess kurtoses, although these
2845/// can be computed quickly for specific values of $m$ when $W$ is 8 or 16.
2846///
2847/// We can similarly generate random striped signed integers of width $W$. The sign bit is chosen
2848/// uniformly, and the remaining $W-1$ are taken from a striped sequence.
2849///
2850/// To generate striped integers from a range, the integers are constructed one bit at a time. Some
2851/// bits are forced; they must be 0 or 1 in order for the final integer to be within the specified
2852/// range. If a bit is _not_ forced, it is different from the preceding bit with probability $1/m$.
2853pub mod striped;