malachite_float/float/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::Float;
10use crate::InnerFloat::Finite;
11use malachite_base::bools::random::{
12 RandomBools, WeightedRandomBools, random_bools, weighted_random_bools,
13};
14use malachite_base::iterators::{WithSpecialValues, with_special_values};
15use malachite_base::num::arithmetic::traits::{
16 DivRound, IsPowerOf2, ModPowerOf2, NegAssign, NegModPowerOf2, PowerOf2,
17};
18use malachite_base::num::basic::integers::PrimitiveInt;
19use malachite_base::num::basic::traits::{
20 Infinity, NaN, NegativeInfinity, NegativeZero, One, Zero,
21};
22use malachite_base::num::conversion::traits::ExactFrom;
23use malachite_base::num::logic::traits::{BitAccess, LowMask, NotAssign, SignificantBits};
24use malachite_base::num::random::geometric::{
25 GeometricRandomNaturalValues, GeometricRandomSignedRange,
26 geometric_random_signed_inclusive_range,
27};
28use malachite_base::num::random::{RandomPrimitiveInts, random_primitive_ints};
29use malachite_base::random::Seed;
30use malachite_base::rounding_modes::RoundingMode::{self, *};
31use malachite_nz::natural::Natural;
32use malachite_nz::natural::random::{
33 RandomNaturals, StripedRandomNaturalInclusiveRange, StripedRandomNaturals,
34 UniformRandomNaturalRange, get_random_natural_with_up_to_bits, random_positive_naturals,
35 striped_random_natural_inclusive_range, striped_random_positive_naturals,
36 uniform_random_natural_inclusive_range,
37};
38use malachite_nz::platform::Limb;
39
40/// Generates random positive finite [`Float`]s.
41///
42/// This `struct` is created by [`random_positive_finite_floats`]; see its documentation for more.
43#[derive(Clone, Debug)]
44pub struct RandomPositiveFiniteFloats<I: Iterator<Item = Natural>> {
45 exponents: GeometricRandomSignedRange<i32>,
46 xs: I,
47}
48
49impl<I: Iterator<Item = Natural>> Iterator for RandomPositiveFiniteFloats<I> {
50 type Item = Float;
51
52 fn next(&mut self) -> Option<Float> {
53 let x = self.xs.next().unwrap();
54 let precision = x.significant_bits();
55 assert_ne!(precision, 0);
56 Some(Float(Finite {
57 sign: true,
58 exponent: self.exponents.next().unwrap() + 1,
59 precision,
60 significand: x << precision.neg_mod_power_of_2(Limb::LOG_WIDTH),
61 }))
62 }
63}
64
65/// Generates random positive finite [`Float`]s.
66///
67/// Simpler [`Float`]s (those with a lower absolute sci-exponent or precision) are more likely to be
68/// chosen. You can specify the mean absolute sci-exponent and precision by passing the numerators
69/// and denominators of their means.
70///
71/// But note that the specified means are only approximate, since the distributions we are sampling
72/// are truncated geometric, and their exact means are somewhat annoying to deal with. The practical
73/// implications are that
74/// - The actual means are slightly lower than the specified means.
75/// - However, increasing the specified means increases the actual means, so this still works as a
76/// mechanism for controlling the sci-exponent and precision.
77/// - The specified sci-exponent mean must be greater than 0 and the precision mean greater than 2,
78/// but they may be as high as you like.
79///
80/// Neither positive nor negative zero is generated. `NaN` is not generated either.
81///
82/// The output length is infinite.
83///
84/// # Expected complexity per iteration
85/// $T(n, m) = O(n / m + 1)$
86///
87/// $M(n, m) = O(n / m)$
88///
89/// where $T$ is time, $M$ is additional memory, $n$ is `mean_precision_numerator`, and $m$ is
90/// `mean_precision_denominator`.
91///
92/// # Examples
93/// ```
94/// use itertools::Itertools;
95/// use malachite_base::random::EXAMPLE_SEED;
96/// use malachite_float::float::random::random_positive_finite_floats;
97/// use malachite_float::ComparableFloat;
98///
99/// // The number after the '#' is the precision.
100/// assert_eq!(
101/// random_positive_finite_floats(EXAMPLE_SEED, 10, 1, 10, 1)
102/// .take(20)
103/// .map(|f| ComparableFloat(f).to_string())
104/// .collect_vec()
105/// .as_slice(),
106/// &[
107/// "0.88#3",
108/// "1.31e-6#6",
109/// "0.0078#1",
110/// "0.50#1",
111/// "82144.0#13",
112/// "0.01558827446#29",
113/// "0.016#1",
114/// "3.406#7",
115/// "4.5981711652#33",
116/// "0.000033432058#23",
117/// "0.3392996773764#37",
118/// "2.662e4#7",
119/// "3.3e4#1",
120/// "1.398#8",
121/// "37.38#9",
122/// "0.25#1",
123/// "0.0011108#13",
124/// "1066.0#10",
125/// "0.1836#7",
126/// "0.001332305612#28"
127/// ]
128/// );
129/// ```
130pub fn random_positive_finite_floats(
131 seed: Seed,
132 mean_sci_exponent_abs_numerator: u64,
133 mean_sci_exponent_abs_denominator: u64,
134 mean_precision_numerator: u64,
135 mean_precision_denominator: u64,
136) -> RandomPositiveFiniteFloats<RandomNaturals<GeometricRandomNaturalValues<u64>>> {
137 RandomPositiveFiniteFloats {
138 exponents: geometric_random_signed_inclusive_range(
139 seed.fork("exponents"),
140 Float::MIN_EXPONENT,
141 Float::MAX_EXPONENT,
142 mean_sci_exponent_abs_numerator,
143 mean_sci_exponent_abs_denominator,
144 ),
145 xs: random_positive_naturals(
146 seed.fork("significands"),
147 mean_precision_numerator,
148 mean_precision_denominator,
149 ),
150 }
151}
152
153/// Generates random positive finite [`Float`]s with a specified precision.
154///
155/// Simpler [`Float`]s (those with a lower absolute sci-exponent) are more likely to be chosen. You
156/// can specify the mean absolute sci-exponent by passing the numerators and denominators of its
157/// means.
158///
159/// But note that the specified mean is only approximate, since the distribution we are sampling is
160/// truncated geometric, and its exact means are somewhat annoying to deal with. The practical
161/// implications are that
162/// - The actual mean is slightly lower than the specified mean.
163/// - However, increasing the specified mean increases the actual mean, so this still works as a
164/// mechanism for controlling the sci-exponent.
165/// - The specified sci-exponent mean must be greater than 0, but it may be as high as you like.
166///
167/// Neither positive nor negative zero is generated. `NaN` is not generated either.
168///
169/// The output length is infinite.
170///
171/// # Expected complexity per iteration
172/// $T(n) = O(n)$
173///
174/// $M(n) = O(n)$
175///
176/// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
177///
178/// # Panics
179/// Panics if `prec` is zero.
180///
181/// # Examples
182/// ```
183/// use itertools::Itertools;
184/// use malachite_base::random::EXAMPLE_SEED;
185/// use malachite_float::float::random::random_positive_floats_with_precision;
186/// use malachite_float::ComparableFloat;
187///
188/// // The number after the '#' is the precision.
189/// assert_eq!(
190/// random_positive_floats_with_precision(EXAMPLE_SEED, 10, 1, 10)
191/// .take(20)
192/// .map(|f| ComparableFloat(f).to_string())
193/// .collect_vec()
194/// .as_slice(),
195/// &[
196/// "0.95898#10",
197/// "1.8887e-6#10",
198/// "0.012909#10",
199/// "0.70996#10",
200/// "1.0202e5#10",
201/// "0.011810#10",
202/// "0.019531#10",
203/// "3.0820#10",
204/// "7.2422#10",
205/// "0.000055969#10",
206/// "0.38770#10",
207/// "21440.0#10",
208/// "58560.0#10",
209/// "1.4297#10",
210/// "62.188#10",
211/// "0.46582#10",
212/// "0.0016594#10",
213/// "1914.0#10",
214/// "0.13599#10",
215/// "0.0011444#10"
216/// ]
217/// );
218/// ```
219pub fn random_positive_floats_with_precision(
220 seed: Seed,
221 mean_sci_exponent_abs_numerator: u64,
222 mean_sci_exponent_abs_denominator: u64,
223 prec: u64,
224) -> RandomPositiveFiniteFloats<UniformRandomNaturalRange> {
225 assert_ne!(prec, 0);
226 RandomPositiveFiniteFloats {
227 exponents: geometric_random_signed_inclusive_range(
228 seed.fork("exponents"),
229 Float::MIN_EXPONENT,
230 Float::MAX_EXPONENT,
231 mean_sci_exponent_abs_numerator,
232 mean_sci_exponent_abs_denominator,
233 ),
234 xs: uniform_random_natural_inclusive_range(
235 seed.fork("significands"),
236 Natural::power_of_2(prec - 1),
237 Natural::low_mask(prec),
238 ),
239 }
240}
241
242/// Generates random negative finite [`Float`]s.
243///
244/// This `struct` is created by [`random_negative_finite_floats`]; see its documentation for more.
245#[derive(Clone, Debug)]
246pub struct RandomNegativeFiniteFloats<I: Iterator<Item = Natural>>(RandomPositiveFiniteFloats<I>);
247
248impl<I: Iterator<Item = Natural>> Iterator for RandomNegativeFiniteFloats<I> {
249 type Item = Float;
250
251 #[inline]
252 fn next(&mut self) -> Option<Float> {
253 self.0.next().map(|f| -f)
254 }
255}
256
257/// Generates random negative finite [`Float`]s.
258///
259/// Simpler [`Float`]s (those with a lower absolute sci-exponent or precision) are more likely to be
260/// chosen. You can specify the mean absolute sci-exponent and precision by passing the numerators
261/// and denominators of their means.
262///
263/// But note that the specified means are only approximate, since the distributions we are sampling
264/// are truncated geometric, and their exact means are somewhat annoying to deal with. The practical
265/// implications are that
266/// - The actual means are slightly lower than the specified means.
267/// - However, increasing the specified means increases the actual means, so this still works as a
268/// mechanism for controlling the sci-exponent and precision.
269/// - The specified sci-exponent mean must be greater than 0 and the precision mean greater than 2,
270/// but they may be as high as you like.
271///
272/// Neither positive nor negative zero is generated. `NaN` is not generated either.
273///
274/// The output length is infinite.
275///
276/// # Expected complexity per iteration
277/// $T(n, m) = O(n / m + 1)$
278///
279/// $M(n, m) = O(n / m)$
280///
281/// where $T$ is time, $M$ is additional memory, $n$ is `mean_precision_numerator`, and $m$ is
282/// `mean_precision_denominator`.
283///
284/// # Examples
285/// ```
286/// use itertools::Itertools;
287/// use malachite_base::random::EXAMPLE_SEED;
288/// use malachite_float::float::random::random_negative_finite_floats;
289/// use malachite_float::ComparableFloat;
290///
291/// // The number after the '#' is the precision.
292/// assert_eq!(
293/// random_negative_finite_floats(EXAMPLE_SEED, 10, 1, 10, 1)
294/// .take(20)
295/// .map(|f| ComparableFloat(f).to_string())
296/// .collect_vec()
297/// .as_slice(),
298/// &[
299/// "-0.88#3",
300/// "-1.31e-6#6",
301/// "-0.0078#1",
302/// "-0.50#1",
303/// "-82144.0#13",
304/// "-0.01558827446#29",
305/// "-0.016#1",
306/// "-3.406#7",
307/// "-4.5981711652#33",
308/// "-0.000033432058#23",
309/// "-0.3392996773764#37",
310/// "-2.662e4#7",
311/// "-3.3e4#1",
312/// "-1.398#8",
313/// "-37.38#9",
314/// "-0.25#1",
315/// "-0.0011108#13",
316/// "-1066.0#10",
317/// "-0.1836#7",
318/// "-0.001332305612#28"
319/// ]
320/// );
321/// ```
322#[inline]
323pub fn random_negative_finite_floats(
324 seed: Seed,
325 mean_sci_exponent_abs_numerator: u64,
326 mean_sci_exponent_abs_denominator: u64,
327 mean_precision_numerator: u64,
328 mean_precision_denominator: u64,
329) -> RandomNegativeFiniteFloats<RandomNaturals<GeometricRandomNaturalValues<u64>>> {
330 RandomNegativeFiniteFloats(random_positive_finite_floats(
331 seed,
332 mean_sci_exponent_abs_numerator,
333 mean_sci_exponent_abs_denominator,
334 mean_precision_numerator,
335 mean_precision_denominator,
336 ))
337}
338
339/// Generates random non-negative finite [`Float`]s.
340///
341/// This `struct` is created by [`random_non_negative_finite_floats`]; see its documentation for
342/// more.
343#[derive(Clone, Debug)]
344pub struct RandomNonNegativeFiniteFloats<I: Iterator<Item = Natural>> {
345 bs: WeightedRandomBools,
346 xs: RandomPositiveFiniteFloats<I>,
347}
348
349impl<I: Iterator<Item = Natural>> Iterator for RandomNonNegativeFiniteFloats<I> {
350 type Item = Float;
351
352 #[inline]
353 fn next(&mut self) -> Option<Float> {
354 if self.bs.next().unwrap() {
355 Some(Float::ZERO)
356 } else {
357 self.xs.next()
358 }
359 }
360}
361
362/// Generates random non-negative finite [`Float`]s.
363///
364/// Simpler [`Float`]s (those with a lower absolute sci-exponent or precision) are more likely to be
365/// chosen. You can specify the numerator and denominator of the probability that a zero will be
366/// generated. You can also specify the mean absolute sci-exponent and precision by passing the
367/// numerators and denominators of their means of the nonzero [`Float`]s.
368///
369/// But note that the specified means are only approximate, since the distributions we are sampling
370/// are truncated geometric, and their exact means are somewhat annoying to deal with. The practical
371/// implications are that
372/// - The actual means are slightly lower than the specified means.
373/// - However, increasing the specified means increases the actual means, so this still works as a
374/// mechanism for controlling the sci-exponent and precision.
375/// - The specified sci-exponent mean must be greater than 0 and the precision mean greater than 2,
376/// but they may be as high as you like.
377///
378/// Positive zero is generated, but negative zero is not. `NaN` is not generated either.
379///
380/// The output length is infinite.
381///
382/// # Expected complexity per iteration
383/// $T(n, m) = O(n / m + 1)$
384///
385/// $M(n, m) = O(n / m)$
386///
387/// where $T$ is time, $M$ is additional memory, $n$ is `mean_precision_numerator`, and $m$ is
388/// `mean_precision_denominator`.
389///
390/// # Examples
391/// ```
392/// use itertools::Itertools;
393/// use malachite_base::random::EXAMPLE_SEED;
394/// use malachite_float::float::random::random_non_negative_finite_floats;
395/// use malachite_float::ComparableFloat;
396///
397/// // The number after the '#' is the precision.
398/// assert_eq!(
399/// random_non_negative_finite_floats(EXAMPLE_SEED, 10, 1, 10, 1, 1, 10)
400/// .take(20)
401/// .map(|f| ComparableFloat(f).to_string())
402/// .collect_vec()
403/// .as_slice(),
404/// &[
405/// "1.11e5#5",
406/// "0.03108048#17",
407/// "9.59386e6#14",
408/// "0.0",
409/// "0.0127#5",
410/// "0.018433#11",
411/// "2.00#5",
412/// "3.0820#10",
413/// "0.874954#16",
414/// "10288.29527676#38",
415/// "9.2188#10",
416/// "0.030048549#23",
417/// "311.4521#19",
418/// "0.0",
419/// "1072.0#7",
420/// "0.0009651#9",
421/// "59159.52197#27",
422/// "0.0",
423/// "0.0000353#6",
424/// "16.0#1"
425/// ]
426/// );
427/// ```
428#[inline]
429pub fn random_non_negative_finite_floats(
430 seed: Seed,
431 mean_sci_exponent_abs_numerator: u64,
432 mean_sci_exponent_abs_denominator: u64,
433 mean_precision_numerator: u64,
434 mean_precision_denominator: u64,
435 zero_p_numerator: u64,
436 zero_p_denominator: u64,
437) -> RandomNonNegativeFiniteFloats<RandomNaturals<GeometricRandomNaturalValues<u64>>> {
438 RandomNonNegativeFiniteFloats {
439 bs: weighted_random_bools(seed.fork("bs"), zero_p_numerator, zero_p_denominator),
440 xs: random_positive_finite_floats(
441 seed.fork("xs"),
442 mean_sci_exponent_abs_numerator,
443 mean_sci_exponent_abs_denominator,
444 mean_precision_numerator,
445 mean_precision_denominator,
446 ),
447 }
448}
449
450/// Generates random non-positive finite [`Float`]s.
451///
452/// This `struct` is created by [`random_non_positive_finite_floats`]; see its documentation for
453/// more.
454#[derive(Clone, Debug)]
455pub struct RandomNonPositiveFiniteFloats<I: Iterator<Item = Natural>> {
456 bs: WeightedRandomBools,
457 xs: RandomNegativeFiniteFloats<I>,
458}
459
460impl<I: Iterator<Item = Natural>> Iterator for RandomNonPositiveFiniteFloats<I> {
461 type Item = Float;
462
463 #[inline]
464 fn next(&mut self) -> Option<Float> {
465 if self.bs.next().unwrap() {
466 Some(Float::NEGATIVE_ZERO)
467 } else {
468 self.xs.next()
469 }
470 }
471}
472
473/// Generates random non-positive finite [`Float`]s.
474///
475/// Simpler [`Float`]s (those with a lower absolute sci-exponent or precision) are more likely to be
476/// chosen. You can specify the numerator and denominator of the probability that a zero will be
477/// generated. You can also specify the mean absolute sci-exponent and precision by passing the
478/// numerators and denominators of their means of the nonzero [`Float`]s.
479///
480/// But note that the specified means are only approximate, since the distributions we are sampling
481/// are truncated geometric, and their exact means are somewhat annoying to deal with. The practical
482/// implications are that
483/// - The actual means are slightly lower than the specified means.
484/// - However, increasing the specified means increases the actual means, so this still works as a
485/// mechanism for controlling the sci-exponent and precision.
486/// - The specified sci-exponent mean must be greater than 0 and the precision mean greater than 2,
487/// but they may be as high as you like.
488///
489/// Negative zero is generated, but positive zero is not. `NaN` is not generated either.
490///
491/// The output length is infinite.
492///
493/// # Expected complexity per iteration
494/// $T(n, m) = O(n / m + 1)$
495///
496/// $M(n, m) = O(n / m)$
497///
498/// where $T$ is time, $M$ is additional memory, $n$ is `mean_precision_numerator`, and $m$ is
499/// `mean_precision_denominator`.
500///
501/// # Examples
502/// ```
503/// use itertools::Itertools;
504/// use malachite_base::random::EXAMPLE_SEED;
505/// use malachite_float::float::random::random_non_positive_finite_floats;
506/// use malachite_float::ComparableFloat;
507///
508/// // The number after the '#' is the precision.
509/// assert_eq!(
510/// random_non_positive_finite_floats(EXAMPLE_SEED, 10, 1, 10, 1, 1, 10)
511/// .take(20)
512/// .map(|f| ComparableFloat(f).to_string())
513/// .collect_vec()
514/// .as_slice(),
515/// &[
516/// "-1.11e5#5",
517/// "-0.03108048#17",
518/// "-9.59386e6#14",
519/// "-0.0",
520/// "-0.0127#5",
521/// "-0.018433#11",
522/// "-2.00#5",
523/// "-3.0820#10",
524/// "-0.874954#16",
525/// "-10288.29527676#38",
526/// "-9.2188#10",
527/// "-0.030048549#23",
528/// "-311.4521#19",
529/// "-0.0",
530/// "-1072.0#7",
531/// "-0.0009651#9",
532/// "-59159.52197#27",
533/// "-0.0",
534/// "-0.0000353#6",
535/// "-16.0#1"
536/// ]
537/// );
538/// ```
539#[inline]
540pub fn random_non_positive_finite_floats(
541 seed: Seed,
542 mean_sci_exponent_abs_numerator: u64,
543 mean_sci_exponent_abs_denominator: u64,
544 mean_precision_numerator: u64,
545 mean_precision_denominator: u64,
546 zero_p_numerator: u64,
547 zero_p_denominator: u64,
548) -> RandomNonPositiveFiniteFloats<RandomNaturals<GeometricRandomNaturalValues<u64>>> {
549 RandomNonPositiveFiniteFloats {
550 bs: weighted_random_bools(seed.fork("bs"), zero_p_numerator, zero_p_denominator),
551 xs: random_negative_finite_floats(
552 seed.fork("xs"),
553 mean_sci_exponent_abs_numerator,
554 mean_sci_exponent_abs_denominator,
555 mean_precision_numerator,
556 mean_precision_denominator,
557 ),
558 }
559}
560
561/// Generates random nonzero finite [`Float`]s.
562///
563/// This `struct` is created by [`random_nonzero_finite_floats`]; see its documentation for more.
564#[derive(Clone, Debug)]
565pub struct RandomNonzeroFiniteFloats<I: Iterator<Item = Natural>> {
566 bs: RandomBools,
567 xs: RandomPositiveFiniteFloats<I>,
568}
569
570impl<I: Iterator<Item = Natural>> Iterator for RandomNonzeroFiniteFloats<I> {
571 type Item = Float;
572
573 #[inline]
574 fn next(&mut self) -> Option<Float> {
575 let x = self.xs.next().unwrap();
576 Some(if self.bs.next().unwrap() { x } else { -x })
577 }
578}
579
580/// Generates random nonzero finite [`Float`]s.
581///
582/// Simpler [`Float`]s (those with a lower absolute sci-exponent or precision) are more likely to be
583/// chosen. You can specify the mean absolute sci-exponent and precision by passing the numerators
584/// and denominators of their means.
585///
586/// But note that the specified means are only approximate, since the distributions we are sampling
587/// are truncated geometric, and their exact means are somewhat annoying to deal with. The practical
588/// implications are that
589/// - The actual means are slightly lower than the specified means.
590/// - However, increasing the specified means increases the actual means, so this still works as a
591/// mechanism for controlling the sci-exponent and precision.
592/// - The specified sci-exponent mean must be greater than 0 and the precision mean greater than 2,
593/// but they may be as high as you like.
594///
595/// Neither positive nor negative zero is generated. `NaN` is not generated either.
596///
597/// The output length is infinite.
598///
599/// # Expected complexity per iteration
600/// $T(n, m) = O(n / m + 1)$
601///
602/// $M(n, m) = O(n / m)$
603///
604/// where $T$ is time, $M$ is additional memory, $n$ is `mean_precision_numerator`, and $m$ is
605/// `mean_precision_denominator`.
606///
607/// # Examples
608/// ```
609/// use itertools::Itertools;
610/// use malachite_base::random::EXAMPLE_SEED;
611/// use malachite_float::float::random::random_nonzero_finite_floats;
612/// use malachite_float::ComparableFloat;
613///
614/// // The number after the '#' is the precision.
615/// assert_eq!(
616/// random_nonzero_finite_floats(EXAMPLE_SEED, 10, 1, 10, 1)
617/// .take(20)
618/// .map(|f| ComparableFloat(f).to_string())
619/// .collect_vec()
620/// .as_slice(),
621/// &[
622/// "-1.11e5#5",
623/// "-0.03108048#17",
624/// "-9.59386e6#14",
625/// "0.0127#5",
626/// "-0.018433#11",
627/// "2.00#5",
628/// "-3.0820#10",
629/// "-0.874954#16",
630/// "-10288.29527676#38",
631/// "9.2188#10",
632/// "0.030048549#23",
633/// "311.4521#19",
634/// "-1072.0#7",
635/// "-0.0009651#9",
636/// "59159.52197#27",
637/// "-0.0000353#6",
638/// "-16.0#1",
639/// "-120.0#5",
640/// "-960.0#5",
641/// "-358.24023#20"
642/// ]
643/// );
644/// ```
645#[inline]
646pub fn random_nonzero_finite_floats(
647 seed: Seed,
648 mean_sci_exponent_abs_numerator: u64,
649 mean_sci_exponent_abs_denominator: u64,
650 mean_precision_numerator: u64,
651 mean_precision_denominator: u64,
652) -> RandomNonzeroFiniteFloats<RandomNaturals<GeometricRandomNaturalValues<u64>>> {
653 RandomNonzeroFiniteFloats {
654 bs: random_bools(seed.fork("bs")),
655 xs: random_positive_finite_floats(
656 seed.fork("xs"),
657 mean_sci_exponent_abs_numerator,
658 mean_sci_exponent_abs_denominator,
659 mean_precision_numerator,
660 mean_precision_denominator,
661 ),
662 }
663}
664
665/// Generates random finite [`Float`]s.
666///
667/// This `struct` is created by [`random_finite_floats`]; see its documentation for more.
668#[derive(Clone, Debug)]
669pub struct RandomFiniteFloats<I: Iterator<Item = Natural>> {
670 bs: RandomBools,
671 xs: RandomNonNegativeFiniteFloats<I>,
672}
673
674impl<I: Iterator<Item = Natural>> Iterator for RandomFiniteFloats<I> {
675 type Item = Float;
676
677 #[inline]
678 fn next(&mut self) -> Option<Float> {
679 let x = self.xs.next().unwrap();
680 Some(if self.bs.next().unwrap() { x } else { -x })
681 }
682}
683
684/// Generates random finite [`Float`]s.
685///
686/// Simpler [`Float`]s (those with a lower absolute sci-exponent or precision) are more likely to be
687/// chosen. You can specify the numerator and denominator of the probability that a zero will be
688/// generated. You can also specify the mean absolute sci-exponent and precision by passing the
689/// numerators and denominators of their means of the nonzero [`Float`]s.
690///
691/// But note that the specified means are only approximate, since the distributions we are sampling
692/// are truncated geometric, and their exact means are somewhat annoying to deal with. The practical
693/// implications are that
694/// - The actual means are slightly lower than the specified means.
695/// - However, increasing the specified means increases the actual means, so this still works as a
696/// mechanism for controlling the sci-exponent and precision.
697/// - The specified sci-exponent mean must be greater than 0 and the precision mean greater than 2,
698/// but they may be as high as you like.
699///
700/// Positive zero and negative zero are both generated. `NaN` is not.
701///
702/// The output length is infinite.
703///
704/// # Expected complexity per iteration
705/// $T(n, m) = O(n / m + 1)$
706///
707/// $M(n, m) = O(n / m)$
708///
709/// where $T$ is time, $M$ is additional memory, $n$ is `mean_precision_numerator`, and $m$ is
710/// `mean_precision_denominator`.
711///
712/// # Examples
713/// ```
714/// use itertools::Itertools;
715/// use malachite_base::random::EXAMPLE_SEED;
716/// use malachite_float::float::random::random_finite_floats;
717/// use malachite_float::ComparableFloat;
718///
719/// // The number after the '#' is the precision.
720/// assert_eq!(
721/// random_finite_floats(EXAMPLE_SEED, 10, 1, 10, 1, 1, 10)
722/// .take(20)
723/// .map(|f| ComparableFloat(f).to_string())
724/// .collect_vec()
725/// .as_slice(),
726/// &[
727/// "-2.438#7",
728/// "-2.3233958868e-8#30",
729/// "-0.0859#6",
730/// "1009.3770#20",
731/// "-0.000824#6",
732/// "1.9805#10",
733/// "-1.9e-6#3",
734/// "-268192.0#14",
735/// "-0.00033855#10",
736/// "6.0#2",
737/// "0.0",
738/// "0.102#5",
739/// "-1.3665#13",
740/// "-3.2e9#2",
741/// "0.117#4",
742/// "-0.19#2",
743/// "-0.03003#7",
744/// "-3.8e-6#2",
745/// "-114.0#6",
746/// "-4002.0#13"
747/// ]
748/// );
749/// ```
750#[inline]
751pub fn random_finite_floats(
752 seed: Seed,
753 mean_sci_exponent_abs_numerator: u64,
754 mean_sci_exponent_abs_denominator: u64,
755 mean_precision_numerator: u64,
756 mean_precision_denominator: u64,
757 zero_p_numerator: u64,
758 zero_p_denominator: u64,
759) -> RandomFiniteFloats<RandomNaturals<GeometricRandomNaturalValues<u64>>> {
760 RandomFiniteFloats {
761 bs: random_bools(seed.fork("bs")),
762 xs: random_non_negative_finite_floats(
763 seed.fork("xs"),
764 mean_sci_exponent_abs_numerator,
765 mean_sci_exponent_abs_denominator,
766 mean_precision_numerator,
767 mean_precision_denominator,
768 zero_p_numerator,
769 zero_p_denominator,
770 ),
771 }
772}
773
774/// Generates random [`Float`]s.
775///
776/// Simpler [`Float`]s (those with a lower absolute sci-exponent or precision) are more likely to be
777/// chosen. You can specify the numerator and denominator of the probability that a zero, an
778/// infinity, or a NaN will be generated. You can also specify the mean absolute sci-exponent and
779/// precision by passing the numerators and denominators of their means of the nonzero [`Float`]s.
780///
781/// But note that the specified means are only approximate, since the distributions we are sampling
782/// are truncated geometric, and their exact means are somewhat annoying to deal with. The practical
783/// implications are that
784/// - The actual means are slightly lower than the specified means.
785/// - However, increasing the specified means increases the actual means, so this still works as a
786/// mechanism for controlling the sci-exponent and precision.
787/// - The specified sci-exponent mean must be greater than 0 and the precision mean greater than 2,
788/// but they may be as high as you like.
789///
790/// The output length is infinite.
791///
792/// # Expected complexity per iteration
793/// $T(n, m) = O(n / m + 1)$
794///
795/// $M(n, m) = O(n / m)$
796///
797/// where $T$ is time, $M$ is additional memory, $n$ is `mean_precision_numerator`, and $m$ is
798/// `mean_precision_denominator`.
799///
800/// # Examples
801/// ```
802/// use itertools::Itertools;
803/// use malachite_base::random::EXAMPLE_SEED;
804/// use malachite_float::float::random::random_floats;
805/// use malachite_float::ComparableFloat;
806///
807/// // The number after the '#' is the precision.
808/// assert_eq!(
809/// random_floats(EXAMPLE_SEED, 10, 1, 10, 1, 1, 10)
810/// .take(50)
811/// .map(|f| ComparableFloat(f).to_string())
812/// .collect_vec()
813/// .as_slice(),
814/// &[
815/// "7.2031#10",
816/// "39.25#8",
817/// "0.0",
818/// "NaN",
819/// "-0.000031#2",
820/// "-5.1e2#1",
821/// "-0.08789#8",
822/// "-95.12012#17",
823/// "0.380768#14",
824/// "0.000138037#15",
825/// "-0.1094#7",
826/// "-10.312#12",
827/// "-13.683969005122592#51",
828/// "Infinity",
829/// "-0.344#4",
830/// "-7.28e-12#5",
831/// "-394584.0#16",
832/// "NaN",
833/// "13.5#5",
834/// "-0.0",
835/// "-0.00635#5",
836/// "0.062#1",
837/// "0.18933#12",
838/// "0.0000401#6",
839/// "-4.8189e-8#13",
840/// "1.15e3#6",
841/// "-1.914e7#7",
842/// "475.7344#17",
843/// "1.103e-6#7",
844/// "Infinity",
845/// "-24.0#3",
846/// "-3.6e-15#1",
847/// "-Infinity",
848/// "0.50391#11",
849/// "-1.0e3#3",
850/// "-0.0000281#6",
851/// "-2.0e5#2",
852/// "6.4317792e-6#20",
853/// "-0.000191#5",
854/// "-0.0",
855/// "-30.0#4",
856/// "0.25#1",
857/// "-0.006299376#18",
858/// "4.582787718616e-6#38",
859/// "-0.0002707085#19",
860/// "0.000013128#10",
861/// "NaN",
862/// "-0.0",
863/// "6.7e7#1",
864/// "20263.5#16"
865/// ]
866/// );
867/// ```
868#[inline]
869pub fn random_floats(
870 seed: Seed,
871 mean_sci_exponent_abs_numerator: u64,
872 mean_sci_exponent_abs_denominator: u64,
873 mean_precision_numerator: u64,
874 mean_precision_denominator: u64,
875 mean_special_p_numerator: u64,
876 mean_special_p_denominator: u64,
877) -> WithSpecialValues<RandomFiniteFloats<RandomNaturals<GeometricRandomNaturalValues<u64>>>> {
878 with_special_values(
879 seed,
880 vec![Float::INFINITY, Float::NEGATIVE_INFINITY, Float::NAN],
881 mean_special_p_numerator,
882 mean_special_p_denominator,
883 &|seed_2| {
884 random_finite_floats(
885 seed_2,
886 mean_sci_exponent_abs_numerator,
887 mean_sci_exponent_abs_denominator,
888 mean_precision_numerator,
889 mean_precision_denominator,
890 mean_special_p_numerator,
891 mean_special_p_denominator,
892 )
893 },
894 )
895}
896
897/// Generates striped random positive finite [`Float`]s.
898///
899/// The actual precision is chosen from a geometric distribution with mean $m$, where $m$ is
900/// `mean_sci_exponent_abs_numerator / mean_sci_exponent_abs_denominator`; $m$ must be greater than
901/// 0. A striped bit sequence with the given stripe parameter is generated and truncated at the bit
902/// length. The highest bit is forced to be 1, and the [`Float`] is generated from the sequence and
903/// a random sci-exponent.
904///
905/// See [`StripedBitSource`](malachite_base::num::random::striped::StripedBitSource) for information
906/// about generating striped random numbers.
907///
908/// Neither positive nor negative zero is generated. `NaN` is not generated either.
909///
910/// The output length is infinite.
911///
912/// # Expected complexity per iteration
913/// $T(n, m) = O(n / m + 1)$
914///
915/// $M(n, m) = O(n / m)$
916///
917/// where $T$ is time, $M$ is additional memory, $n$ is `mean_precision_numerator`, and $m$ is
918/// `mean_precision_denominator`.
919///
920/// # Panics
921/// Panics if `mean_stripe_denominator` is zero, if `mean_stripe_numerator <
922/// mean_stripe_denominator`, if `mean_precision_numerator` or `mean_precision_denominator` are
923/// zero, or, if after being reduced to lowest terms, their sum is greater than or equal to
924/// $2^{64}$.
925///
926/// ```
927/// use itertools::Itertools;
928/// use malachite_base::random::EXAMPLE_SEED;
929/// use malachite_float::float::random::striped_random_positive_finite_floats;
930/// use malachite_float::ComparableFloat;
931///
932/// // The number after the '#' is the precision.
933/// assert_eq!(
934/// striped_random_positive_finite_floats(EXAMPLE_SEED, 10, 1, 8, 1, 16, 1)
935/// .take(20)
936/// .map(|f| ComparableFloat(f).to_string())
937/// .collect_vec()
938/// .as_slice(),
939/// &[
940/// "0.938#4",
941/// "1.9064e-6#11",
942/// "0.0078#2",
943/// "0.50#3",
944/// "98332.000#21",
945/// "0.014160633101709896512#60",
946/// "0.023#2",
947/// "2.109#8",
948/// "4.000030282884437849#57",
949/// "0.000057221276833275#43",
950/// "0.25000005983747242139#63",
951/// "24576.0#12",
952/// "3.3e4#1",
953/// "1.98431#16",
954/// "33.500#12",
955/// "0.25#1",
956/// "0.00097680069#23",
957/// "1279.50000#25",
958/// "0.1250#7",
959/// "0.0014648735386622#42"
960/// ]
961/// );
962/// ```
963pub fn striped_random_positive_finite_floats(
964 seed: Seed,
965 mean_sci_exponent_abs_numerator: u64,
966 mean_sci_exponent_abs_denominator: u64,
967 mean_stripe_numerator: u64,
968 mean_stripe_denominator: u64,
969 mean_precision_numerator: u64,
970 mean_precision_denominator: u64,
971) -> RandomPositiveFiniteFloats<StripedRandomNaturals<GeometricRandomNaturalValues<u64>>> {
972 RandomPositiveFiniteFloats {
973 exponents: geometric_random_signed_inclusive_range(
974 seed.fork("exponents"),
975 Float::MIN_EXPONENT,
976 Float::MAX_EXPONENT,
977 mean_sci_exponent_abs_numerator,
978 mean_sci_exponent_abs_denominator,
979 ),
980 xs: striped_random_positive_naturals(
981 seed.fork("significands"),
982 mean_stripe_numerator,
983 mean_stripe_denominator,
984 mean_precision_numerator,
985 mean_precision_denominator,
986 ),
987 }
988}
989
990/// Generates striped random positive finite [`Float`]s with a specified precision.
991///
992/// A striped bit sequence with the given stripe parameter is generated and truncated at the bit
993/// length. The highest bit is forced to be 1, and the [`Float`] is generated from the sequence and
994/// a random sci-exponent.
995///
996/// See [`StripedBitSource`](malachite_base::num::random::striped::StripedBitSource) for information
997/// about generating striped random numbers.
998///
999/// Neither positive nor negative zero is generated. `NaN` is not generated either.
1000///
1001/// The output length is infinite.
1002///
1003/// # Expected complexity per iteration
1004/// $T(n) = O(n)$
1005///
1006/// $M(n) = O(n)$
1007///
1008/// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
1009///
1010/// # Panics
1011/// Panics if `mean_stripe_denominator` is zero, if `mean_stripe_numerator <
1012/// mean_stripe_denominator`, or if `prec` is zero.
1013///
1014/// ```
1015/// use itertools::Itertools;
1016/// use malachite_base::random::EXAMPLE_SEED;
1017/// use malachite_float::float::random::striped_random_positive_floats_with_precision;
1018/// use malachite_float::ComparableFloat;
1019///
1020/// // The number after the '#' is the precision.
1021/// assert_eq!(
1022/// striped_random_positive_floats_with_precision(EXAMPLE_SEED, 10, 1, 8, 1, 10)
1023/// .take(20)
1024/// .map(|f| ComparableFloat(f).to_string())
1025/// .collect_vec()
1026/// .as_slice(),
1027/// &[
1028/// "0.81152#10",
1029/// "9.5367e-7#10",
1030/// "0.015610#10",
1031/// "0.50000#10",
1032/// "65536.0#10",
1033/// "0.015381#10",
1034/// "0.017548#10",
1035/// "3.9961#10",
1036/// "7.9922#10",
1037/// "0.000060976#10",
1038/// "0.44092#10",
1039/// "32736.0#10",
1040/// "64960.0#10",
1041/// "1.1250#10",
1042/// "63.938#10",
1043/// "0.29688#10",
1044/// "0.0019512#10",
1045/// "1920.0#10",
1046/// "0.12573#10",
1047/// "0.0014629#10"
1048/// ]
1049/// );
1050/// ```
1051pub fn striped_random_positive_floats_with_precision(
1052 seed: Seed,
1053 mean_sci_exponent_abs_numerator: u64,
1054 mean_sci_exponent_abs_denominator: u64,
1055 mean_stripe_numerator: u64,
1056 mean_stripe_denominator: u64,
1057 prec: u64,
1058) -> RandomPositiveFiniteFloats<StripedRandomNaturalInclusiveRange> {
1059 assert_ne!(prec, 0);
1060 RandomPositiveFiniteFloats {
1061 exponents: geometric_random_signed_inclusive_range(
1062 seed.fork("exponents"),
1063 Float::MIN_EXPONENT,
1064 Float::MAX_EXPONENT,
1065 mean_sci_exponent_abs_numerator,
1066 mean_sci_exponent_abs_denominator,
1067 ),
1068 xs: striped_random_natural_inclusive_range(
1069 seed.fork("significands"),
1070 Natural::power_of_2(prec - 1),
1071 Natural::low_mask(prec),
1072 mean_stripe_numerator,
1073 mean_stripe_denominator,
1074 ),
1075 }
1076}
1077
1078/// Generates striped random negative finite [`Float`]s.
1079///
1080/// The actual precision is chosen from a geometric distribution with mean $m$, where $m$ is
1081/// `mean_stripe_numerator / mean_stripe_denominator`; $m$ must be greater than 0. A striped bit
1082/// sequence with the given stripe parameter is generated and truncated at the bit length. The
1083/// highest bit is forced to be 1, and the [`Float`] is generated from the sequence and a random
1084/// sci-exponent.
1085///
1086/// See [`StripedBitSource`](malachite_base::num::random::striped::StripedBitSource) for information
1087/// about generating striped random numbers.
1088///
1089/// Neither positive nor negative zero is generated. `NaN` is not generated either.
1090///
1091/// The output length is infinite.
1092///
1093/// # Expected complexity per iteration
1094/// $T(n, m) = O(n / m + 1)$
1095///
1096/// $M(n, m) = O(n / m)$
1097///
1098/// where $T$ is time, $M$ is additional memory, $n$ is `mean_precision_numerator`, and $m$ is
1099/// `mean_precision_denominator`.
1100///
1101/// # Panics
1102/// Panics if `mean_stripe_denominator` is zero, if `mean_stripe_numerator <
1103/// mean_stripe_denominator`, if `mean_precision_numerator` or `mean_precision_denominator` are
1104/// zero, or, if after being reduced to lowest terms, their sum is greater than or equal to
1105/// $2^{64}$.
1106///
1107/// ```
1108/// use itertools::Itertools;
1109/// use malachite_base::random::EXAMPLE_SEED;
1110/// use malachite_float::float::random::striped_random_negative_finite_floats;
1111/// use malachite_float::ComparableFloat;
1112///
1113/// // The number after the '#' is the precision.
1114/// assert_eq!(
1115/// striped_random_negative_finite_floats(EXAMPLE_SEED, 10, 1, 8, 1, 16, 1)
1116/// .take(20)
1117/// .map(|f| ComparableFloat(f).to_string())
1118/// .collect_vec()
1119/// .as_slice(),
1120/// &[
1121/// "-0.938#4",
1122/// "-1.9064e-6#11",
1123/// "-0.0078#2",
1124/// "-0.50#3",
1125/// "-98332.000#21",
1126/// "-0.014160633101709896512#60",
1127/// "-0.023#2",
1128/// "-2.109#8",
1129/// "-4.000030282884437849#57",
1130/// "-0.000057221276833275#43",
1131/// "-0.25000005983747242139#63",
1132/// "-24576.0#12",
1133/// "-3.3e4#1",
1134/// "-1.98431#16",
1135/// "-33.500#12",
1136/// "-0.25#1",
1137/// "-0.00097680069#23",
1138/// "-1279.50000#25",
1139/// "-0.1250#7",
1140/// "-0.0014648735386622#42"
1141/// ]
1142/// );
1143/// ```
1144pub fn striped_random_negative_finite_floats(
1145 seed: Seed,
1146 mean_sci_exponent_abs_numerator: u64,
1147 mean_sci_exponent_abs_denominator: u64,
1148 mean_stripe_numerator: u64,
1149 mean_stripe_denominator: u64,
1150 mean_precision_numerator: u64,
1151 mean_precision_denominator: u64,
1152) -> RandomNegativeFiniteFloats<StripedRandomNaturals<GeometricRandomNaturalValues<u64>>> {
1153 RandomNegativeFiniteFloats(striped_random_positive_finite_floats(
1154 seed,
1155 mean_sci_exponent_abs_numerator,
1156 mean_sci_exponent_abs_denominator,
1157 mean_stripe_numerator,
1158 mean_stripe_denominator,
1159 mean_precision_numerator,
1160 mean_precision_denominator,
1161 ))
1162}
1163
1164/// Generates striped random non-negative finite [`Float`]s.
1165///
1166/// Positive zero is generated with the specified probability. If the [`Float`] to be generated is
1167/// nonzero, then the actual precision is chosen from a geometric distribution with mean $m$, where
1168/// $m$ is `mean_stripe_numerator / mean_stripe_denominator`; $m$ must be greater than 0. A striped
1169/// bit sequence with the given stripe parameter is generated and truncated at the bit length. The
1170/// highest bit is forced to be 1, and the [`Float`] is generated from the sequence and a random
1171/// sci-exponent.
1172///
1173/// See [`StripedBitSource`](malachite_base::num::random::striped::StripedBitSource) for information
1174/// about generating striped random numbers.
1175///
1176/// Positive zero is generated, but negative zero is not. `NaN` is not generated either.
1177///
1178/// The output length is infinite.
1179///
1180/// # Expected complexity per iteration
1181/// $T(n, m) = O(n / m + 1)$
1182///
1183/// $M(n, m) = O(n / m)$
1184///
1185/// where $T$ is time, $M$ is additional memory, $n$ is `mean_precision_numerator`, and $m$ is
1186/// `mean_precision_denominator`.
1187///
1188/// # Panics
1189/// Panics if `mean_stripe_denominator` is zero, if `mean_stripe_numerator <
1190/// mean_stripe_denominator`, if `mean_precision_numerator` or `mean_precision_denominator` are
1191/// zero, or, if after being reduced to lowest terms, their sum is greater than or equal to
1192/// $2^{64}$.
1193///
1194/// ```
1195/// use itertools::Itertools;
1196/// use malachite_base::random::EXAMPLE_SEED;
1197/// use malachite_float::float::random::striped_random_non_negative_finite_floats;
1198/// use malachite_float::ComparableFloat;
1199///
1200/// // The number after the '#' is the precision.
1201/// assert_eq!(
1202/// striped_random_non_negative_finite_floats(EXAMPLE_SEED, 10, 1, 8, 1, 16, 1, 1, 10)
1203/// .take(20)
1204/// .map(|f| ComparableFloat(f).to_string())
1205/// .collect_vec()
1206/// .as_slice(),
1207/// &[
1208/// "6.554e4#7",
1209/// "0.0214843750#26",
1210/// "8404960.0#19",
1211/// "0.0",
1212/// "0.0155065#16",
1213/// "0.031219512#20",
1214/// "3.94#6",
1215/// "2.00378#15",
1216/// "0.61712646#21",
1217/// "16383.978515147231406#61",
1218/// "12.0000#14",
1219/// "0.019531012396#31",
1220/// "380.000229#25",
1221/// "0.0",
1222/// "1511.5#12",
1223/// "0.000915587#14",
1224/// "32799.9997520447#46",
1225/// "0.0",
1226/// "0.0000305#6",
1227/// "24.0#2"
1228/// ]
1229/// );
1230/// ```
1231#[inline]
1232pub fn striped_random_non_negative_finite_floats(
1233 seed: Seed,
1234 mean_sci_exponent_abs_numerator: u64,
1235 mean_sci_exponent_abs_denominator: u64,
1236 mean_stripe_numerator: u64,
1237 mean_stripe_denominator: u64,
1238 mean_precision_numerator: u64,
1239 mean_precision_denominator: u64,
1240 zero_p_numerator: u64,
1241 zero_p_denominator: u64,
1242) -> RandomNonNegativeFiniteFloats<StripedRandomNaturals<GeometricRandomNaturalValues<u64>>> {
1243 RandomNonNegativeFiniteFloats {
1244 bs: weighted_random_bools(seed.fork("bs"), zero_p_numerator, zero_p_denominator),
1245 xs: striped_random_positive_finite_floats(
1246 seed.fork("xs"),
1247 mean_sci_exponent_abs_numerator,
1248 mean_sci_exponent_abs_denominator,
1249 mean_stripe_numerator,
1250 mean_stripe_denominator,
1251 mean_precision_numerator,
1252 mean_precision_denominator,
1253 ),
1254 }
1255}
1256
1257/// Generates striped random non-positive finite [`Float`]s.
1258///
1259/// Negative zero is generated with the specified probability. If the [`Float`] to be generated is
1260/// nonzero, then the actual precision is chosen from a geometric distribution with mean $m$, where
1261/// $m$ is `mean_stripe_numerator / mean_stripe_denominator`; $m$ must be greater than 0. A striped
1262/// bit sequence with the given stripe parameter is generated and truncated at the bit length. The
1263/// highest bit is forced to be 1, and the [`Float`] is generated from the sequence and a random
1264/// sci-exponent.
1265///
1266/// See [`StripedBitSource`](malachite_base::num::random::striped::StripedBitSource) for information
1267/// about generating striped random numbers.
1268///
1269/// Negative zero is generated, but positive zero is not. `NaN` is not generated either.
1270///
1271/// The output length is infinite.
1272///
1273/// # Expected complexity per iteration
1274/// $T(n, m) = O(n / m + 1)$
1275///
1276/// $M(n, m) = O(n / m)$
1277///
1278/// where $T$ is time, $M$ is additional memory, $n$ is `mean_precision_numerator`, and $m$ is
1279/// `mean_precision_denominator`.
1280///
1281/// # Panics
1282/// Panics if `mean_stripe_denominator` is zero, if `mean_stripe_numerator <
1283/// mean_stripe_denominator`, if `mean_precision_numerator` or `mean_precision_denominator` are
1284/// zero, or, if after being reduced to lowest terms, their sum is greater than or equal to
1285/// $2^{64}$.
1286///
1287/// ```
1288/// use itertools::Itertools;
1289/// use malachite_base::random::EXAMPLE_SEED;
1290/// use malachite_float::float::random::striped_random_non_positive_finite_floats;
1291/// use malachite_float::ComparableFloat;
1292///
1293/// // The number after the '#' is the precision.
1294/// assert_eq!(
1295/// striped_random_non_positive_finite_floats(EXAMPLE_SEED, 10, 1, 8, 1, 16, 1, 1, 10)
1296/// .take(20)
1297/// .map(|f| ComparableFloat(f).to_string())
1298/// .collect_vec()
1299/// .as_slice(),
1300/// &[
1301/// "-6.554e4#7",
1302/// "-0.0214843750#26",
1303/// "-8404960.0#19",
1304/// "-0.0",
1305/// "-0.0155065#16",
1306/// "-0.031219512#20",
1307/// "-3.94#6",
1308/// "-2.00378#15",
1309/// "-0.61712646#21",
1310/// "-16383.978515147231406#61",
1311/// "-12.0000#14",
1312/// "-0.019531012396#31",
1313/// "-380.000229#25",
1314/// "-0.0",
1315/// "-1511.5#12",
1316/// "-0.000915587#14",
1317/// "-32799.9997520447#46",
1318/// "-0.0",
1319/// "-0.0000305#6",
1320/// "-24.0#2"
1321/// ]
1322/// );
1323/// ```
1324#[inline]
1325pub fn striped_random_non_positive_finite_floats(
1326 seed: Seed,
1327 mean_sci_exponent_abs_numerator: u64,
1328 mean_sci_exponent_abs_denominator: u64,
1329 mean_stripe_numerator: u64,
1330 mean_stripe_denominator: u64,
1331 mean_precision_numerator: u64,
1332 mean_precision_denominator: u64,
1333 zero_p_numerator: u64,
1334 zero_p_denominator: u64,
1335) -> RandomNonPositiveFiniteFloats<StripedRandomNaturals<GeometricRandomNaturalValues<u64>>> {
1336 RandomNonPositiveFiniteFloats {
1337 bs: weighted_random_bools(seed.fork("bs"), zero_p_numerator, zero_p_denominator),
1338 xs: striped_random_negative_finite_floats(
1339 seed.fork("xs"),
1340 mean_sci_exponent_abs_numerator,
1341 mean_sci_exponent_abs_denominator,
1342 mean_stripe_numerator,
1343 mean_stripe_denominator,
1344 mean_precision_numerator,
1345 mean_precision_denominator,
1346 ),
1347 }
1348}
1349
1350/// Generates striped random nonzero finite [`Float`]s.
1351///
1352/// The actual precision is chosen from a geometric distribution with mean $m$, where $m$ is
1353/// `mean_stripe_numerator / mean_stripe_denominator`; $m$ must be greater than 0. A striped bit
1354/// sequence with the given stripe parameter is generated and truncated at the bit length. The
1355/// highest bit is forced to be 1, and the [`Float`] is generated from the sequence and a random
1356/// sci-exponent.
1357///
1358/// See [`StripedBitSource`](malachite_base::num::random::striped::StripedBitSource) for information
1359/// about generating striped random numbers.
1360///
1361/// Neither positive nor negative zero is generated. `NaN` is not generated either.
1362///
1363/// The output length is infinite.
1364///
1365/// # Expected complexity per iteration
1366/// $T(n, m) = O(n / m + 1)$
1367///
1368/// $M(n, m) = O(n / m)$
1369///
1370/// where $T$ is time, $M$ is additional memory, $n$ is `mean_precision_numerator`, and $m$ is
1371/// `mean_precision_denominator`.
1372///
1373/// # Panics
1374/// Panics if `mean_stripe_denominator` is zero, if `mean_stripe_numerator <
1375/// mean_stripe_denominator`, if `mean_precision_numerator` or `mean_precision_denominator` are
1376/// zero, or, if after being reduced to lowest terms, their sum is greater than or equal to
1377/// $2^{64}$.
1378///
1379/// ```
1380/// use itertools::Itertools;
1381/// use malachite_base::random::EXAMPLE_SEED;
1382/// use malachite_float::float::random::striped_random_nonzero_finite_floats;
1383/// use malachite_float::ComparableFloat;
1384///
1385/// // The number after the '#' is the precision.
1386/// assert_eq!(
1387/// striped_random_nonzero_finite_floats(EXAMPLE_SEED, 10, 1, 8, 1, 16, 1)
1388/// .take(20)
1389/// .map(|f| ComparableFloat(f).to_string())
1390/// .collect_vec()
1391/// .as_slice(),
1392/// &[
1393/// "-6.554e4#7",
1394/// "-0.0214843750#26",
1395/// "-8404960.0#19",
1396/// "0.0155065#16",
1397/// "-0.031219512#20",
1398/// "3.94#6",
1399/// "-2.00378#15",
1400/// "-0.61712646#21",
1401/// "-16383.978515147231406#61",
1402/// "12.0000#14",
1403/// "0.019531012396#31",
1404/// "380.000229#25",
1405/// "-1511.5#12",
1406/// "-0.000915587#14",
1407/// "32799.9997520447#46",
1408/// "-0.0000305#6",
1409/// "-24.0#2",
1410/// "-64.00#9",
1411/// "-760.0#7",
1412/// "-287.765624970#34"
1413/// ]
1414/// );
1415/// ```
1416#[inline]
1417pub fn striped_random_nonzero_finite_floats(
1418 seed: Seed,
1419 mean_sci_exponent_abs_numerator: u64,
1420 mean_sci_exponent_abs_denominator: u64,
1421 mean_stripe_numerator: u64,
1422 mean_stripe_denominator: u64,
1423 mean_precision_numerator: u64,
1424 mean_precision_denominator: u64,
1425) -> RandomNonzeroFiniteFloats<StripedRandomNaturals<GeometricRandomNaturalValues<u64>>> {
1426 RandomNonzeroFiniteFloats {
1427 bs: random_bools(seed.fork("bs")),
1428 xs: striped_random_positive_finite_floats(
1429 seed.fork("xs"),
1430 mean_sci_exponent_abs_numerator,
1431 mean_sci_exponent_abs_denominator,
1432 mean_stripe_numerator,
1433 mean_stripe_denominator,
1434 mean_precision_numerator,
1435 mean_precision_denominator,
1436 ),
1437 }
1438}
1439
1440/// Generates striped random finite [`Float`]s.
1441///
1442/// Zero is generated with the specified probability. If the [`Float`] to be generated is nonzero,
1443/// then the actual precision is chosen from a geometric distribution with mean $m$, where $m$ is
1444/// `mean_stripe_numerator / mean_stripe_denominator`; $m$ must be greater than 0. A striped bit
1445/// sequence with the given stripe parameter is generated and truncated at the bit length. The
1446/// highest bit is forced to be 1, and the [`Float`] is generated from the sequence and a random
1447/// sci-exponent.
1448///
1449/// See [`StripedBitSource`](malachite_base::num::random::striped::StripedBitSource) for information
1450/// about generating striped random numbers.
1451///
1452/// Both positive and negative zero are generated. `NaN` is not.
1453///
1454/// The output length is infinite.
1455///
1456/// # Expected complexity per iteration
1457/// $T(n, m) = O(n / m + 1)$
1458///
1459/// $M(n, m) = O(n / m)$
1460///
1461/// where $T$ is time, $M$ is additional memory, $n$ is `mean_precision_numerator`, and $m$ is
1462/// `mean_precision_denominator`.
1463///
1464/// # Panics
1465/// Panics if `mean_stripe_denominator` is zero, if `mean_stripe_numerator <
1466/// mean_stripe_denominator`, if `mean_precision_numerator` or `mean_precision_denominator` are
1467/// zero, or, if after being reduced to lowest terms, their sum is greater than or equal to
1468/// $2^{64}$.
1469///
1470/// ```
1471/// use itertools::Itertools;
1472/// use malachite_base::random::EXAMPLE_SEED;
1473/// use malachite_float::float::random::striped_random_finite_floats;
1474/// use malachite_float::ComparableFloat;
1475///
1476/// // The number after the '#' is the precision.
1477/// assert_eq!(
1478/// striped_random_finite_floats(EXAMPLE_SEED, 10, 1, 8, 1, 16, 1, 1, 10)
1479/// .take(20)
1480/// .map(|f| ComparableFloat(f).to_string())
1481/// .collect_vec()
1482/// .as_slice(),
1483/// &[
1484/// "-3.89209#14",
1485/// "-2.607703209227954e-8#47",
1486/// "-0.093750#11",
1487/// "527.9999997541#38",
1488/// "-0.0005112#7",
1489/// "1.003845#17",
1490/// "-1.9e-6#3",
1491/// "-524272.0#16",
1492/// "-0.0004407074#18",
1493/// "7.75#5",
1494/// "0.0",
1495/// "0.12451#12",
1496/// "-1.9921865#21",
1497/// "-3.2e9#2",
1498/// "0.06250#8",
1499/// "-0.22#3",
1500/// "-0.015625#11",
1501/// "-3.81e-6#4",
1502/// "-64.000#13",
1503/// "-4064.000#19"
1504/// ]
1505/// );
1506/// ```
1507#[inline]
1508pub fn striped_random_finite_floats(
1509 seed: Seed,
1510 mean_sci_exponent_abs_numerator: u64,
1511 mean_sci_exponent_abs_denominator: u64,
1512 mean_stripe_numerator: u64,
1513 mean_stripe_denominator: u64,
1514 mean_precision_numerator: u64,
1515 mean_precision_denominator: u64,
1516 zero_p_numerator: u64,
1517 zero_p_denominator: u64,
1518) -> RandomFiniteFloats<StripedRandomNaturals<GeometricRandomNaturalValues<u64>>> {
1519 RandomFiniteFloats {
1520 bs: random_bools(seed.fork("bs")),
1521 xs: striped_random_non_negative_finite_floats(
1522 seed.fork("xs"),
1523 mean_sci_exponent_abs_numerator,
1524 mean_sci_exponent_abs_denominator,
1525 mean_stripe_numerator,
1526 mean_stripe_denominator,
1527 mean_precision_numerator,
1528 mean_precision_denominator,
1529 zero_p_numerator,
1530 zero_p_denominator,
1531 ),
1532 }
1533}
1534
1535/// Generates striped random finite [`Float`]s.
1536///
1537/// Special values (NaN, infinities, and zeros) are generated with the specified probability. If the
1538/// [`Float`] to be generated is finite and nonzero, then the actual precision is chosen from a
1539/// geometric distribution with mean $m$, where $m$ is `mean_stripe_numerator /
1540/// mean_stripe_denominator`; $m$ must be greater than 0. A striped bit sequence with the given
1541/// stripe parameter is generated and truncated at the bit length. The highest bit is forced to be
1542/// 1, and the [`Float`] is generated from the sequence and a random sci-exponent.
1543///
1544/// See [`StripedBitSource`](malachite_base::num::random::striped::StripedBitSource) for information
1545/// about generating striped random numbers.
1546///
1547/// The output length is infinite.
1548///
1549/// # Expected complexity per iteration
1550/// $T(n, m) = O(n / m + 1)$
1551///
1552/// $M(n, m) = O(n / m)$
1553///
1554/// where $T$ is time, $M$ is additional memory, $n$ is `mean_precision_numerator`, and $m$ is
1555/// `mean_precision_denominator`.
1556///
1557/// # Panics
1558/// Panics if `mean_stripe_denominator` is zero, if `mean_stripe_numerator <
1559/// mean_stripe_denominator`, if `mean_precision_numerator` or `mean_precision_denominator` are
1560/// zero, or, if after being reduced to lowest terms, their sum is greater than or equal to
1561/// $2^{64}$.
1562///
1563/// ```
1564/// use itertools::Itertools;
1565/// use malachite_base::random::EXAMPLE_SEED;
1566/// use malachite_float::float::random::striped_random_floats;
1567/// use malachite_float::ComparableFloat;
1568///
1569/// // The number after the '#' is the precision.
1570/// assert_eq!(
1571/// striped_random_floats(EXAMPLE_SEED, 10, 1, 8, 1, 16, 1, 1, 10)
1572/// .take(50)
1573/// .map(|f| ComparableFloat(f).to_string())
1574/// .collect_vec()
1575/// .as_slice(),
1576/// &[
1577/// "7.99976#15",
1578/// "32.75#9",
1579/// "0.0",
1580/// "NaN",
1581/// "-0.000046#2",
1582/// "-5.1e2#1",
1583/// "-0.12488#10",
1584/// "-127.4999852#28",
1585/// "0.49999988#22",
1586/// "0.0002439022091#28",
1587/// "-0.11719#11",
1588/// "-9.9687500#23",
1589/// "-15.9844663292160586998132#75",
1590/// "Infinity",
1591/// "-0.484#5",
1592/// "-1.41e-11#5",
1593/// "-262144.00#21",
1594/// "NaN",
1595/// "8.8750#12",
1596/// "-0.0",
1597/// "-0.005859#7",
1598/// "0.062#1",
1599/// "0.12695307#22",
1600/// "0.000060976#10",
1601/// "-3.0733631e-8#22",
1602/// "1024.0#9",
1603/// "-3.1519e7#13",
1604/// "483.93847632#31",
1605/// "9.832438e-7#17",
1606/// "Infinity",
1607/// "-24.0#6",
1608/// "-3.6e-15#1",
1609/// "-Infinity",
1610/// "0.60839844448#31",
1611/// "-1.02e3#4",
1612/// "-0.00001526#7",
1613/// "-1.3e5#2",
1614/// "3.82971439e-6#24",
1615/// "-0.00012350#10",
1616/// "-0.0",
1617/// "-23.94#9",
1618/// "0.25#1",
1619/// "-0.0073261258913#31",
1620/// "3.8184225337224168437e-6#61",
1621/// "-0.000488281237267#34",
1622/// "0.0000151538#16",
1623/// "NaN",
1624/// "-0.0",
1625/// "6.7e7#1",
1626/// "20423.984375#33"
1627/// ]
1628/// );
1629/// ```
1630#[inline]
1631pub fn striped_random_floats(
1632 seed: Seed,
1633 mean_sci_exponent_abs_numerator: u64,
1634 mean_sci_exponent_abs_denominator: u64,
1635 mean_stripe_numerator: u64,
1636 mean_stripe_denominator: u64,
1637 mean_precision_numerator: u64,
1638 mean_precision_denominator: u64,
1639 mean_special_p_numerator: u64,
1640 mean_special_p_denominator: u64,
1641) -> WithSpecialValues<RandomFiniteFloats<StripedRandomNaturals<GeometricRandomNaturalValues<u64>>>>
1642{
1643 with_special_values(
1644 seed,
1645 vec![Float::INFINITY, Float::NEGATIVE_INFINITY, Float::NAN],
1646 mean_special_p_numerator,
1647 mean_special_p_denominator,
1648 &|seed_2| {
1649 striped_random_finite_floats(
1650 seed_2,
1651 mean_sci_exponent_abs_numerator,
1652 mean_sci_exponent_abs_denominator,
1653 mean_stripe_numerator,
1654 mean_stripe_denominator,
1655 mean_precision_numerator,
1656 mean_precision_denominator,
1657 mean_special_p_numerator,
1658 mean_special_p_denominator,
1659 )
1660 },
1661 )
1662}
1663
1664// This is a translation of mpfr_urandomb from urandomb.c, MPFR 4.2.2, using Malachite's seeded
1665// random streams in place of a GMP randstate.
1666/// Generates uniform random [`Float`]s in the interval $[0, 1)$, with a fixed precision.
1667///
1668/// This `struct` is created by [`uniform_random_non_negative_floats_less_than_one`]; see its
1669/// documentation for more.
1670#[derive(Clone, Debug)]
1671pub struct UniformRandomNonNegativeFloatsLessThanOne {
1672 xs: RandomPrimitiveInts<u64>,
1673 prec: u64,
1674}
1675
1676impl Iterator for UniformRandomNonNegativeFloatsLessThanOne {
1677 type Item = Float;
1678
1679 fn next(&mut self) -> Option<Float> {
1680 // Draws exactly prec bits (in u64 chunks on every platform), mirroring mpfr_rand_raw's
1681 // guarantee that the stream position is independent of the machine word size.
1682 let k = get_random_natural_with_up_to_bits(&mut self.xs, self.prec);
1683 if k == 0u32 {
1684 // all drawn bits are zero
1685 Some(Float::ZERO)
1686 } else {
1687 let bits = k.significant_bits();
1688 // The value is k / 2^prec, so the raw exponent is bits - prec.
1689 let exponent = i64::exact_from(bits) - i64::exact_from(self.prec);
1690 if exponent < Float::MIN_EXPONENT_I64 {
1691 // Mirrors mpfr_urandomb: if the exponent is out of range (possible only when the
1692 // precision is on the order of 2^30), a NaN is returned as this is probably a user
1693 // error. This branch cannot be exercised by sampling: it requires a draw whose top
1694 // 2^30 or so bits are all zero, with probability around 2^(-2^30). It is not
1695 // limb-width-dependent (the stream is u64-based on every platform).
1696 Some(Float::NAN)
1697 } else {
1698 Some(Float(Finite {
1699 sign: true,
1700 exponent: i32::exact_from(exponent),
1701 precision: self.prec,
1702 significand: k
1703 << (self.prec.neg_mod_power_of_2(Limb::LOG_WIDTH) + self.prec - bits),
1704 }))
1705 }
1706 }
1707 }
1708}
1709
1710/// Generates uniform random [`Float`]s in the interval $[0, 1)$, with a fixed precision.
1711///
1712/// Each output is $k/2^p$, where $p$ is `prec` and $k$ is chosen uniformly from $[0, 2^p)$, so
1713/// every value is a dyadic rational whose denominator divides $2^p$, and each of the $2^p$ possible
1714/// values is equally likely. Every nonzero output has precision `prec`. Zero is drawn with
1715/// probability $2^{-p}$, and is a positive zero.
1716///
1717/// This function samples the same distribution as `mpfr_urandomb`. Like that function, it draws
1718/// exactly `prec` bits from the underlying stream per output, independently of the machine word
1719/// size, and returns `NaN` in the (practically unobservable) case that the scientific exponent of
1720/// the drawn value falls below [`Float::MIN_EXPONENT`], which can only happen when `prec` is on the
1721/// order of $2^{30}$.
1722///
1723/// The output length is infinite.
1724///
1725/// # Expected complexity per iteration
1726/// $T(n) = O(n)$
1727///
1728/// $M(n) = O(n)$
1729///
1730/// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
1731///
1732/// # Panics
1733/// Panics if `prec` is zero.
1734///
1735/// # Examples
1736/// ```
1737/// use itertools::Itertools;
1738/// use malachite_base::random::EXAMPLE_SEED;
1739/// use malachite_float::float::random::uniform_random_non_negative_floats_less_than_one;
1740/// use malachite_float::ComparableFloat;
1741///
1742/// // The number after the '#' is the precision.
1743/// assert_eq!(
1744/// uniform_random_non_negative_floats_less_than_one(EXAMPLE_SEED, 10)
1745/// .take(20)
1746/// .map(|f| ComparableFloat(f).to_string())
1747/// .collect_vec()
1748/// .as_slice(),
1749/// &[
1750/// "0.86035#10",
1751/// "0.084961#10",
1752/// "0.090820#10",
1753/// "0.61426#10",
1754/// "0.50684#10",
1755/// "0.97754#10",
1756/// "0.61133#10",
1757/// "0.35156#10",
1758/// "0.23633#10",
1759/// "0.47949#10",
1760/// "0.082031#10",
1761/// "0.15137#10",
1762/// "0.91992#10",
1763/// "0.34082#10",
1764/// "0.021484#10",
1765/// "0.20898#10",
1766/// "0.72949#10",
1767/// "0.62598#10",
1768/// "0.11230#10",
1769/// "0.13184#10"
1770/// ]
1771/// );
1772/// ```
1773pub fn uniform_random_non_negative_floats_less_than_one(
1774 seed: Seed,
1775 prec: u64,
1776) -> UniformRandomNonNegativeFloatsLessThanOne {
1777 assert_ne!(prec, 0);
1778 UniformRandomNonNegativeFloatsLessThanOne {
1779 xs: random_primitive_ints(seed),
1780 prec,
1781 }
1782}
1783
1784// A bit source that consumes u32s from a u64 stream (low half of each word first) and serves n-bit
1785// requests by assembling full 64-bit chunks (two u32s, low first) and masking the low bits of one
1786// final u32 (or u32 pair) for the partial chunk. This is exactly the consumption pattern of MPFR
1787// driven by the same u64 stream through a custom GMP randstate whose partial requests take low
1788// bits, so a Float sampler built on this source can be compared against MPFR output-for-output over
1789// a whole stream, not just on first draws.
1790#[derive(Clone, Debug)]
1791struct U32BitSource<I: Iterator<Item = u64>> {
1792 xs: I,
1793 hi: Option<u32>,
1794}
1795
1796impl<I: Iterator<Item = u64>> U32BitSource<I> {
1797 fn next_u32(&mut self) -> u32 {
1798 if let Some(h) = self.hi.take() {
1799 h
1800 } else {
1801 let x = self.xs.next().unwrap();
1802 self.hi = Some((x >> 32) as u32);
1803 x as u32
1804 }
1805 }
1806
1807 // Draws n bits for n <= 32, low-aligned in the low bits of one u32.
1808 fn u32_bits(&mut self, n: u64) -> u32 {
1809 self.next_u32().mod_power_of_2(n)
1810 }
1811
1812 // Draws a uniform random value in [0, n), replicating gmp_urandomm_ui: each attempt draws
1813 // exactly enough bits for n (one fewer when n is a power of 2, in which case no rejection can
1814 // occur), rejecting values that are too large. The iteration cap and the final fallback,
1815 // reachable only with a degenerate stream, are GMP's.
1816 fn uniform_mod(&mut self, n: u64) -> u64 {
1817 assert_ne!(n, 0);
1818 let bits = n.significant_bits() - u64::from(n.is_power_of_2());
1819 let mut r = 0;
1820 for _ in 0..80 {
1821 r = u64::exact_from(&self.bits(bits));
1822 if r < n {
1823 return r;
1824 }
1825 }
1826 r - n
1827 }
1828
1829 // Draws n bits, low-aligned.
1830 fn bits(&mut self, n: u64) -> Natural {
1831 let mut result = Natural::ZERO;
1832 let mut shift = 0;
1833 for _ in 0..(n >> 6) {
1834 let lo = u64::from(self.next_u32());
1835 let hi = u64::from(self.next_u32());
1836 result |= Natural::from(lo | (hi << 32)) << shift;
1837 shift += 64;
1838 }
1839 let rest = n.mod_power_of_2(6);
1840 if rest >= 32 {
1841 let mut chunk = u64::from(self.next_u32());
1842 if rest > 32 {
1843 chunk |= u64::from(self.u32_bits(rest - 32)) << 32;
1844 }
1845 result |= Natural::from(chunk) << shift;
1846 } else if rest != 0 {
1847 result |= Natural::from(self.u32_bits(rest)) << shift;
1848 }
1849 result
1850 }
1851}
1852
1853// This is a translation of mpfr_urandom from urandom.c, MPFR 4.2.2, including the underflow
1854// handling of mpfr_check_range from exceptions.c.
1855/// Generates random [`Float`]s in $[0, 1]$, as if a uniform random real number were drawn from the
1856/// unit interval and rounded to a fixed precision with a fixed rounding mode.
1857///
1858/// This `struct` is created by [`uniform_random_non_negative_floats_at_most_one`]; see its
1859/// documentation for more.
1860#[derive(Clone, Debug)]
1861pub struct UniformRandomNonNegativeFloatsAtMostOne<I: Iterator<Item = u64>> {
1862 bits: U32BitSource<I>,
1863 prec: u64,
1864 rm: RoundingMode,
1865}
1866
1867impl<I: Iterator<Item = u64>> Iterator for UniformRandomNonNegativeFloatsAtMostOne<I> {
1868 type Item = Float;
1869
1870 fn next(&mut self) -> Option<Float> {
1871 // Step 1 (exponent): 0 with probability 1/2, -1 with probability 1/4, and so on, determined
1872 // by leading-zero counts of 8-bit blocks.
1873 let mut exponent: i64 = 0;
1874 loop {
1875 let block = self.u32_bits_block();
1876 let cnt = 8 - block.significant_bits();
1877 // Any exponent below MIN_EXPONENT - 1 behaves identically, so clamping here cannot
1878 // change the result, and it prevents any theoretical overflow. The generator is still
1879 // advanced, so the stream position does not depend on the clamp.
1880 if exponent >= const { Float::MIN_EXPONENT_I64 - 2 } {
1881 exponent -= i64::exact_from(cnt);
1882 }
1883 if cnt != 8 {
1884 break;
1885 }
1886 }
1887 // Step 2 (significand): prec - 1 drawn bits under an implicit leading 1, so the
1888 // pre-rounding value is in [1/2, 1) at the raw exponent 0 drawn above.
1889 let mut mantissa = if self.prec == 1 {
1890 Natural::ONE
1891 } else {
1892 self.bits.bits(self.prec - 1) | Natural::power_of_2(self.prec - 1)
1893 };
1894 // The rounding bit, which decides between the two neighboring representable values when
1895 // rounding to nearest: the exact value lies in an open 1-ulp interval, and the two halves
1896 // of that interval have equal measure.
1897 let rbit = self.bits.u32_bits(1);
1898 let up = match self.rm {
1899 Ceiling | Up => true,
1900 Floor | Down => false,
1901 Nearest => rbit != 0,
1902 // the constructor rejects Exact
1903 Exact => unreachable!(),
1904 };
1905 if up {
1906 mantissa += Natural::ONE;
1907 if mantissa.significant_bits() > self.prec {
1908 // the significand was all ones, so rounding up reaches the next binade
1909 mantissa >>= 1u64;
1910 exponent += 1;
1911 }
1912 }
1913 // Underflow handling, as in mpfr_check_range: unreachable by sampling, since reaching it
1914 // requires on the order of 2^27 consecutive all-zero 8-bit blocks.
1915 if exponent < Float::MIN_EXPONENT_I64 {
1916 // In the Nearest mode, round toward zero if the value is below half of the minimum
1917 // positive Float, or equal to that half with the exact value below it.
1918 let down = match self.rm {
1919 Floor | Down => true,
1920 Ceiling | Up => false,
1921 Nearest => {
1922 exponent < Float::MIN_EXPONENT_MINUS_1_I64 || up && mantissa.is_power_of_2()
1923 }
1924 Exact => unreachable!(),
1925 };
1926 return Some(if down {
1927 Float::ZERO
1928 } else {
1929 {}
1930 Float(Finite {
1931 sign: true,
1932 exponent: Float::MIN_EXPONENT,
1933 precision: self.prec,
1934 significand: Natural::power_of_2(
1935 self.prec.neg_mod_power_of_2(Limb::LOG_WIDTH) + self.prec - 1,
1936 ),
1937 })
1938 });
1939 }
1940 Some(Float(Finite {
1941 sign: true,
1942 exponent: i32::exact_from(exponent),
1943 precision: self.prec,
1944 significand: mantissa << self.prec.neg_mod_power_of_2(Limb::LOG_WIDTH),
1945 }))
1946 }
1947}
1948
1949impl<I: Iterator<Item = u64>> UniformRandomNonNegativeFloatsAtMostOne<I> {
1950 // Draws the 8-bit block used by the exponent loop.
1951 fn u32_bits_block(&mut self) -> u32 {
1952 self.bits.u32_bits(8)
1953 }
1954}
1955
1956crate_test_fn! {
1957 // Like [`uniform_random_non_negative_floats_at_most_one`], but takes an arbitrary stream of
1958 // u64s instead of a seed, allowing tests to inject a rigged stream (for example, one that
1959 // reaches the underflow branches, which no seed can reach by sampling).
1960 uniform_random_non_negative_floats_at_most_one_from_u64s<I: Iterator<Item = u64>>(
1961 xs: I,
1962 prec: u64,
1963 rm: RoundingMode,
1964 ) -> UniformRandomNonNegativeFloatsAtMostOne<I> {
1965 assert_ne!(prec, 0);
1966 assert_ne!(rm, Exact);
1967 UniformRandomNonNegativeFloatsAtMostOne {
1968 bits: U32BitSource { xs, hi: None },
1969 prec,
1970 rm,
1971 }
1972 }
1973}
1974
1975/// Generates random [`Float`]s in $[0, 1]$, as if a uniform random real number were drawn from the
1976/// unit interval and rounded to precision `prec` with rounding mode `rm`.
1977///
1978/// The distribution is that of a continuous uniform random variable on the unit interval, correctly
1979/// rounded: each output is a precision-`prec` [`Float`], and the probability of any output equals
1980/// the measure of the set of real numbers that round to it. Every output has precision `prec`. The
1981/// rounded value can be $1$ (under `Ceiling`, `Up`, or `Nearest`), but under `Floor` or `Down` it
1982/// is always less than $1$. It can be $0$ only via underflow, which requires the drawn exponent to
1983/// fall below the minimum exponent; this is unreachable in practice, since its probability is
1984/// roughly $2^{-2^{30}}$.
1985///
1986/// This function samples the same distribution as `mpfr_urandom`, and consumes randomness from the
1987/// underlying stream in the same pattern, including the fact that the amount consumed depends on
1988/// `prec` but not on `rm`. The result is never exact, so `Exact` is not a valid rounding mode.
1989///
1990/// The output length is infinite.
1991///
1992/// # Expected complexity per iteration
1993/// $T(n) = O(n)$
1994///
1995/// $M(n) = O(n)$
1996///
1997/// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
1998///
1999/// # Panics
2000/// Panics if `prec` is zero or if `rm` is `Exact`.
2001///
2002/// # Examples
2003/// ```
2004/// use itertools::Itertools;
2005/// use malachite_base::random::EXAMPLE_SEED;
2006/// use malachite_base::rounding_modes::RoundingMode::*;
2007/// use malachite_float::float::random::uniform_random_non_negative_floats_at_most_one;
2008/// use malachite_float::ComparableFloat;
2009///
2010/// // The number after the '#' is the precision.
2011/// assert_eq!(
2012/// uniform_random_non_negative_floats_at_most_one(EXAMPLE_SEED, 10, Nearest)
2013/// .take(20)
2014/// .map(|f| ComparableFloat(f).to_string())
2015/// .collect_vec()
2016/// .as_slice(),
2017/// &[
2018/// "0.36182#10",
2019/// "0.59180#10",
2020/// "0.44922#10",
2021/// "0.48877#10",
2022/// "0.26904#10",
2023/// "0.73730#10",
2024/// "0.69531#10",
2025/// "0.65234#10",
2026/// "0.85059#10",
2027/// "0.52148#10",
2028/// "0.85547#10",
2029/// "0.039124#10",
2030/// "0.30127#10",
2031/// "0.38965#10",
2032/// "0.94336#10",
2033/// "0.48535#10",
2034/// "0.21631#10",
2035/// "0.078979#10",
2036/// "0.12866#10",
2037/// "0.36182#10"
2038/// ]
2039/// );
2040/// ```
2041#[inline]
2042pub fn uniform_random_non_negative_floats_at_most_one(
2043 seed: Seed,
2044 prec: u64,
2045 rm: RoundingMode,
2046) -> UniformRandomNonNegativeFloatsAtMostOne<RandomPrimitiveInts<u64>> {
2047 uniform_random_non_negative_floats_at_most_one_from_u64s(random_primitive_ints(seed), prec, rm)
2048}
2049
2050// The random-deviate machinery of random_deviate.c, MPFR 4.2.2 (contributed to MPFR by Charles
2051// Karney): a lazily-extended random real, uniform in (0, 1), of which only the leading `e` bits
2052// have been decided. The first 32 bits (the "high fraction") live in `h`, and the rest in `f`. `h`
2053// is meaningless if e == 0, and `f` is meaningless if e <= 32. MPFR standardizes the chunk size at
2054// 32 bits for cross-platform reproducibility; every request below is one u32 from the stream, which
2055// keeps this machinery sequence-comparable with MPFR through the test harness.
2056#[derive(Clone, Debug)]
2057struct RandomDeviate {
2058 e: u64,
2059 h: u32,
2060 f: Natural,
2061}
2062
2063const CHUNK: u64 = 32;
2064const CHUNK_PLUS_1: u64 = CHUNK + 1;
2065const TWICE_CHUNK: u64 = CHUNK << 1;
2066// A bound so large that exceeding it indicates a defective random stream.
2067const SANITY_BOUND: u64 = u64::MAX >> 1;
2068
2069impl RandomDeviate {
2070 const fn new() -> Self {
2071 Self {
2072 e: 0,
2073 h: 0,
2074 f: Natural::ZERO,
2075 }
2076 }
2077
2078 const fn reset(&mut self) {
2079 self.e = 0;
2080 }
2081
2082 // Ensures that at least k bits of the fraction have been decided, drawing 32 bits at a time.
2083 // This is random_deviate_generate with a null mpz_t argument.
2084 fn generate<I: Iterator<Item = u64>>(&mut self, k: u64, src: &mut U32BitSource<I>) {
2085 if self.e >= k {
2086 return;
2087 }
2088 if self.e == 0 {
2089 self.h = src.next_u32();
2090 self.e = CHUNK;
2091 if self.e >= k {
2092 return;
2093 }
2094 }
2095 while self.e < k {
2096 let w = Natural::from(src.next_u32());
2097 self.f = if self.e == CHUNK {
2098 w
2099 } else {
2100 (&self.f << CHUNK) + w
2101 };
2102 self.e += CHUNK;
2103 }
2104 }
2105
2106 // Like `generate`, but requests all needed bits at once, as random_deviate_generate does when
2107 // passed an mpz_t temporary. The batched request assembles its bits in the opposite order from
2108 // the chunked path, exactly as mpz_urandomb does relative to repeated gmp_urandomb_ui calls, so
2109 // the two paths must be kept distinct for MPFR parity.
2110 fn generate_batch<I: Iterator<Item = u64>>(&mut self, k: u64, src: &mut U32BitSource<I>) {
2111 if self.e >= k {
2112 return;
2113 }
2114 if self.e == 0 {
2115 self.h = src.next_u32();
2116 self.e = CHUNK;
2117 if self.e >= k {
2118 return;
2119 }
2120 }
2121 let k = k.div_round(CHUNK, Ceiling).0 * CHUNK - self.e;
2122 let t = src.bits(k);
2123 self.f = if self.e == CHUNK {
2124 t
2125 } else {
2126 (&self.f << k) + t
2127 };
2128 self.e += k;
2129 }
2130
2131 // The position of the leading bit of the fraction, counting from 1: the leading bit represents
2132 // 2^(-l).
2133 fn leading_bit<I: Iterator<Item = u64>>(&mut self, src: &mut U32BitSource<I>) -> u64 {
2134 self.generate(CHUNK, src);
2135 if self.h != 0 {
2136 return CHUNK_PLUS_1 - self.h.significant_bits();
2137 }
2138 self.generate(TWICE_CHUNK, src);
2139 while self.f == 0u32 {
2140 self.generate(self.e + 1, src);
2141 }
2142 let l = self.e + 1 - self.f.significant_bits();
2143 // A ridiculously long string of leading zeros (probability on the order of 2^(-2^31)) would
2144 // indicate a defective random stream.
2145 assert!(l < SANITY_BOUND);
2146 l
2147 }
2148
2149 // The kth bit of the fraction, representing 2^(-k). The k == 0 and k <= 32 arms are not
2150 // reachable from the exponential sampler, whose only caller of this function is the comparison
2151 // loop, which starts at k = 33; they are used by mpfr_nrandom's algorithms, which test fraction
2152 // bits from position 1.
2153 fn tstbit<I: Iterator<Item = u64>>(&mut self, k: u64, src: &mut U32BitSource<I>) -> bool {
2154 if k == 0 {
2155 return false;
2156 }
2157 self.generate(k, src);
2158 if k <= CHUNK {
2159 self.h.get_bit(CHUNK - k)
2160 } else {
2161 self.f.get_bit(self.e - k)
2162 }
2163 }
2164}
2165
2166// Compares two random deviates, deciding more of their bits as needed to break ties. Since the
2167// deviates are (conceptually) uniform random reals, this terminates with probability 1.
2168fn random_deviate_less<I: Iterator<Item = u64>>(
2169 x: &mut RandomDeviate,
2170 y: &mut RandomDeviate,
2171 src: &mut U32BitSource<I>,
2172) -> bool {
2173 x.generate(CHUNK, src);
2174 y.generate(CHUNK, src);
2175 if x.h != y.h {
2176 return x.h < y.h;
2177 }
2178 let mut k = CHUNK_PLUS_1;
2179 loop {
2180 let a = x.tstbit(k, src);
2181 let b = y.tstbit(k, src);
2182 if a != b {
2183 return b;
2184 }
2185 k += 1;
2186 }
2187}
2188
2189// Converts n + x, where x is a random deviate, to a Float rounded to `prec` with `rm`, deciding as
2190// many more bits of x as the precision requires. This is mpfr_random_deviate_value, with the sign
2191// applied before the rounding, since the directed rounding modes do not commute with negation. The
2192// trailing bit of the assembled integer is set, so the result is always inexact, and there are
2193// never ties to break in the Nearest mode.
2194fn random_deviate_value<I: Iterator<Item = u64>>(
2195 neg: bool,
2196 n: u64,
2197 x: &mut RandomDeviate,
2198 prec: u64,
2199 rm: RoundingMode,
2200 src: &mut U32BitSource<I>,
2201) -> Float {
2202 let (s_positive, l) = if n == 0 {
2203 (false, x.leading_bit(src))
2204 } else {
2205 (true, n.significant_bits() - 1)
2206 };
2207 if s_positive && prec + 1 > l || !s_positive {
2208 let k = if s_positive {
2209 prec + 1 - l
2210 } else {
2211 prec + 1 + l
2212 };
2213 x.generate_batch(k, src);
2214 }
2215 let mut t = if n == 0 {
2216 // the minimum precision is 1, so the high fraction has been generated
2217 Natural::from(x.h)
2218 } else {
2219 let mut t = Natural::from(n);
2220 if x.e > 0 {
2221 t <<= CHUNK;
2222 t += Natural::from(x.h);
2223 }
2224 t
2225 };
2226 if x.e > CHUNK {
2227 t <<= x.e - CHUNK;
2228 t += &x.f;
2229 }
2230 t.set_bit(0);
2231 // The exact value is +/- t * 2^(-e). Negating exactly and then shifting with rounding rounds
2232 // once, as mpfr_set_z_2exp does, and handles the (unreachable-by-sampling) underflow at extreme
2233 // e.
2234 let mut exact = Float::exact_from(t);
2235 if neg {
2236 exact.neg_assign();
2237 }
2238 exact.shr_prec_round(x.e, prec, rm).0
2239}
2240
2241// This is a translation of mpfr_erandom from erandom.c, MPFR 4.2.2, which uses von Neumann's
2242// rejection algorithm: the integer part of the deviate is the number of leading rejections, and
2243// each accept/reject test is a Bernoulli trial with success probability exp(-x), realized as
2244// comparisons of lazily-decided uniform deviates, with no transcendental evaluations.
2245/// Generates random [`Float`]s sampled, with rounding, from the exponential distribution with mean
2246/// 1.
2247///
2248/// This `struct` is created by [`exponential_random_floats`]; see its documentation for more.
2249#[derive(Clone, Debug)]
2250pub struct ExponentialRandomFloats<I: Iterator<Item = u64>> {
2251 bits: U32BitSource<I>,
2252 prec: u64,
2253 rm: RoundingMode,
2254}
2255
2256// True with probability exp(-x): von Neumann's test, using p and q as scratch deviates.
2257fn exp_bernoulli<I: Iterator<Item = u64>>(
2258 x: &mut RandomDeviate,
2259 p: &mut RandomDeviate,
2260 q: &mut RandomDeviate,
2261 src: &mut U32BitSource<I>,
2262) -> bool {
2263 p.reset();
2264 if !random_deviate_less(p, x, src) {
2265 return true;
2266 }
2267 loop {
2268 q.reset();
2269 if !random_deviate_less(q, p, src) {
2270 return false;
2271 }
2272 p.reset();
2273 if !random_deviate_less(p, q, src) {
2274 return true;
2275 }
2276 }
2277}
2278
2279impl<I: Iterator<Item = u64>> Iterator for ExponentialRandomFloats<I> {
2280 type Item = Float;
2281
2282 fn next(&mut self) -> Option<Float> {
2283 let mut x = RandomDeviate::new();
2284 let mut p = RandomDeviate::new();
2285 let mut q = RandomDeviate::new();
2286 let mut k: u64 = 0;
2287 while !exp_bernoulli(&mut x, &mut p, &mut q, &mut self.bits) {
2288 k += 1;
2289 // A wraparound of k (probability on the order of exp(-2^64)) would indicate a defective
2290 // random stream.
2291 assert_ne!(k, 0);
2292 x.reset();
2293 }
2294 Some(random_deviate_value(
2295 false,
2296 k,
2297 &mut x,
2298 self.prec,
2299 self.rm,
2300 &mut self.bits,
2301 ))
2302 }
2303}
2304
2305crate_test_fn! {
2306 // Like [`exponential_random_floats`], but takes an arbitrary stream of u64s instead of a seed,
2307 // allowing tests to inject a rigged stream.
2308 exponential_random_floats_from_u64s<I: Iterator<Item = u64>>(
2309 xs: I,
2310 prec: u64,
2311 rm: RoundingMode,
2312 ) -> ExponentialRandomFloats<I> {
2313 assert_ne!(prec, 0);
2314 assert_ne!(rm, Exact);
2315 ExponentialRandomFloats {
2316 bits: U32BitSource { xs, hi: None },
2317 prec,
2318 rm,
2319 }
2320 }
2321}
2322
2323/// Generates random [`Float`]s sampled, with rounding, from the exponential distribution with mean
2324/// 1.
2325///
2326/// The result is a correctly-rounded sample: each output is a precision-`prec` [`Float`], and the
2327/// probability of any output equals the probability that an exponentially-distributed real number
2328/// rounds to it under `rm`. The sampler is von Neumann's rejection algorithm as used by
2329/// `mpfr_erandom`, which draws no transcendental function evaluations; the number of random bits
2330/// consumed is finite with probability 1 but not bounded. Every output is positive: a zero would
2331/// require underflow, whose probability is on the order of $2^{-2^{30}}$. The result is never
2332/// exact, so `Exact` is not a valid rounding mode.
2333///
2334/// The output length is infinite.
2335///
2336/// # Expected complexity per iteration
2337/// $T(n) = O(n)$
2338///
2339/// $M(n) = O(n)$
2340///
2341/// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
2342///
2343/// # Panics
2344/// Panics if `prec` is zero or if `rm` is `Exact`.
2345///
2346/// # Examples
2347/// ```
2348/// use itertools::Itertools;
2349/// use malachite_base::random::EXAMPLE_SEED;
2350/// use malachite_base::rounding_modes::RoundingMode::*;
2351/// use malachite_float::float::random::exponential_random_floats;
2352/// use malachite_float::ComparableFloat;
2353///
2354/// // The number after the '#' is the precision.
2355/// assert_eq!(
2356/// exponential_random_floats(EXAMPLE_SEED, 10, Nearest)
2357/// .take(20)
2358/// .map(|f| ComparableFloat(f).to_string())
2359/// .collect_vec()
2360/// .as_slice(),
2361/// &[
2362/// "0.63184#10",
2363/// "1.4648#10",
2364/// "0.96582#10",
2365/// "2.6836#10",
2366/// "3.6719#10",
2367/// "2.5703#10",
2368/// "0.097046#10",
2369/// "1.6602#10",
2370/// "0.69629#10",
2371/// "0.052429#10",
2372/// "0.58398#10",
2373/// "0.23486#10",
2374/// "0.88965#10",
2375/// "2.1992#10",
2376/// "1.7480#10",
2377/// "0.16748#10",
2378/// "0.35693#10",
2379/// "1.0996#10",
2380/// "0.44238#10",
2381/// "0.51172#10"
2382/// ]
2383/// );
2384/// ```
2385#[inline]
2386pub fn exponential_random_floats(
2387 seed: Seed,
2388 prec: u64,
2389 rm: RoundingMode,
2390) -> ExponentialRandomFloats<RandomPrimitiveInts<u64>> {
2391 exponential_random_floats_from_u64s(random_primitive_ints(seed), prec, rm)
2392}
2393
2394// True with probability exp(-1/2): algorithm H of mpfr_nrandom, whose initial rejection step just
2395// tests the leading fraction bit.
2396fn half_exp_bernoulli<I: Iterator<Item = u64>>(
2397 p: &mut RandomDeviate,
2398 q: &mut RandomDeviate,
2399 src: &mut U32BitSource<I>,
2400) -> bool {
2401 p.reset();
2402 if p.tstbit(1, src) {
2403 return true;
2404 }
2405 loop {
2406 q.reset();
2407 if !random_deviate_less(q, p, src) {
2408 return false;
2409 }
2410 p.reset();
2411 if !random_deviate_less(p, q, src) {
2412 return true;
2413 }
2414 }
2415}
2416
2417// Returns n >= 0 with probability exp(-n/2) * (1 - exp(-1/2)): step N1 of mpfr_nrandom.
2418fn truncated_exponential<I: Iterator<Item = u64>>(
2419 p: &mut RandomDeviate,
2420 q: &mut RandomDeviate,
2421 src: &mut U32BitSource<I>,
2422) -> u64 {
2423 let mut n = 0;
2424 while half_exp_bernoulli(p, q, src) {
2425 n += 1;
2426 // A wraparound of n (probability on the order of exp(-2^64)) would indicate a defective
2427 // random stream.
2428 assert_ne!(n, 0);
2429 }
2430 n
2431}
2432
2433// True with probability exp(-m * n / 2): step N2 of mpfr_nrandom. The product m * n is passed as
2434// two separate factors because the caller passes m = k and n = k - 1 with a wrapping subtraction:
2435// for k = 0, m = 0 and the wrapped n is never used, so the result is true.
2436fn exp_half_product_bernoulli<I: Iterator<Item = u64>>(
2437 m: u64,
2438 n: u64,
2439 p: &mut RandomDeviate,
2440 q: &mut RandomDeviate,
2441 src: &mut U32BitSource<I>,
2442) -> bool {
2443 for _ in 0..m {
2444 for _ in 0..n {
2445 if !half_exp_bernoulli(p, q, src) {
2446 return false;
2447 }
2448 }
2449 }
2450 true
2451}
2452
2453// Returns -1, 0, or 1 with probabilities 1/m, 1/m, and 1 - 2/m: algorithm C of mpfr_nrandom.
2454fn choice<I: Iterator<Item = u64>>(m: u64, src: &mut U32BitSource<I>) -> i8 {
2455 match src.uniform_mod(m) {
2456 0 => -1,
2457 1 => 0,
2458 _ => 1,
2459 }
2460}
2461
2462// True with probability exp(-x * (2 * k + x) / (2 * k + 2)): algorithm B of mpfr_nrandom. The loop
2463// unpacks the short-circuit condition chain of the C original, preserving the order of the draws;
2464// the result is whether the number of completed iterations is even.
2465fn tail_bernoulli<I: Iterator<Item = u64>>(
2466 k: u64,
2467 x: &mut RandomDeviate,
2468 p: &mut RandomDeviate,
2469 q: &mut RandomDeviate,
2470 src: &mut U32BitSource<I>,
2471) -> bool {
2472 // 2 * k + 2 would overflow; a k this large (probability on the order of exp(-2^63)) would
2473 // indicate a defective random stream.
2474 assert!(k < SANITY_BOUND);
2475 let m = (k << 1) + 2;
2476 let mut parity_even = true;
2477 let mut first = true;
2478 loop {
2479 let mut f = if k == 0 { choice(m, src) } else { 0 };
2480 if f < 0 {
2481 break;
2482 }
2483 q.reset();
2484 if !random_deviate_less(q, if first { &mut *x } else { &mut *p }, src) {
2485 break;
2486 }
2487 if k != 0 {
2488 f = choice(m, src);
2489 }
2490 if f < 0 {
2491 break;
2492 }
2493 if f == 0 {
2494 p.reset();
2495 if !random_deviate_less(p, x, src) {
2496 break;
2497 }
2498 }
2499 core::mem::swap(p, q);
2500 parity_even.not_assign();
2501 first = false;
2502 }
2503 parity_even
2504}
2505
2506// This is a translation of mpfr_nrandom from nrandom.c, MPFR 4.2.2: algorithm N of Karney,
2507// "Sampling exactly from the normal distribution", ACM Transactions on Mathematical Software 42(1)
2508// (2016). Everything is built from Bernoulli trials on lazily-decided uniform deviates, with no
2509// transcendental evaluations.
2510/// Generates random [`Float`]s sampled, with rounding, from the normal distribution with mean 0 and
2511/// variance 1.
2512///
2513/// This `struct` is created by [`normal_random_floats`]; see its documentation for more.
2514#[derive(Clone, Debug)]
2515pub struct NormalRandomFloats<I: Iterator<Item = u64>> {
2516 bits: U32BitSource<I>,
2517 prec: u64,
2518 rm: RoundingMode,
2519}
2520
2521impl<I: Iterator<Item = u64>> Iterator for NormalRandomFloats<I> {
2522 type Item = Float;
2523
2524 fn next(&mut self) -> Option<Float> {
2525 let mut x = RandomDeviate::new();
2526 let mut p = RandomDeviate::new();
2527 let mut q = RandomDeviate::new();
2528 let k;
2529 loop {
2530 // step 1: k with probability exp(-k/2) * (1 - exp(-1/2))
2531 let kk = truncated_exponential(&mut p, &mut q, &mut self.bits);
2532 // step 2: accept with probability exp(-k * (k - 1) / 2), so that k now follows the
2533 // normal tail weights
2534 if !exp_half_product_bernoulli(kk, kk.wrapping_sub(1), &mut p, &mut q, &mut self.bits) {
2535 continue;
2536 }
2537 // steps 3 and 4: accept the fraction x with probability exp(-x * (2 * k + x) / 2), via
2538 // k + 1 successes of the tail test
2539 x.reset();
2540 let mut j = 0;
2541 while j <= kk && tail_bernoulli(kk, &mut x, &mut p, &mut q, &mut self.bits) {
2542 j += 1;
2543 }
2544 if j > kk {
2545 k = kk;
2546 break;
2547 }
2548 }
2549 // steps 5 to 7: attach a random sign to k + x and round
2550 let neg = self.bits.u32_bits(1) != 0;
2551 Some(random_deviate_value(
2552 neg,
2553 k,
2554 &mut x,
2555 self.prec,
2556 self.rm,
2557 &mut self.bits,
2558 ))
2559 }
2560}
2561
2562crate_test_fn! {
2563 // Like [`normal_random_floats`], but takes an arbitrary stream of u64s instead of a seed,
2564 // allowing tests to inject a rigged stream.
2565 normal_random_floats_from_u64s<I: Iterator<Item = u64>>(
2566 xs: I,
2567 prec: u64,
2568 rm: RoundingMode,
2569 ) -> NormalRandomFloats<I> {
2570 assert_ne!(prec, 0);
2571 assert_ne!(rm, Exact);
2572 NormalRandomFloats {
2573 bits: U32BitSource { xs, hi: None },
2574 prec,
2575 rm,
2576 }
2577 }
2578}
2579
2580crate_test_fn! {
2581 // Direct access to the gmp_urandomm_ui replica, for differential testing against GMP.
2582 uniform_mod_from_u64s<I: Iterator<Item = u64>>(xs: I, n: u64) -> u64 {
2583 let mut src = U32BitSource { xs, hi: None };
2584 src.uniform_mod(n)
2585 }
2586}
2587
2588/// Generates random [`Float`]s sampled, with rounding, from the normal distribution with mean 0 and
2589/// variance 1.
2590///
2591/// The result is a correctly-rounded sample: each output is a precision-`prec` [`Float`], and the
2592/// probability of any output equals the probability that a normally-distributed real number rounds
2593/// to it under `rm`. The sampler is algorithm N of Karney, "Sampling exactly from the normal
2594/// distribution", as used by `mpfr_nrandom`; it is built entirely from Bernoulli trials on
2595/// lazily-decided uniform deviates and draws no transcendental function evaluations. The number of
2596/// random bits consumed is finite with probability 1 but not bounded. Every output is nonzero: a
2597/// zero would require underflow, whose probability is on the order of $2^{-2^{30}}$. The result is
2598/// never exact, so `Exact` is not a valid rounding mode.
2599///
2600/// The output length is infinite.
2601///
2602/// # Expected complexity per iteration
2603/// $T(n) = O(n)$
2604///
2605/// $M(n) = O(n)$
2606///
2607/// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
2608///
2609/// # Panics
2610/// Panics if `prec` is zero or if `rm` is `Exact`.
2611///
2612/// # Examples
2613/// ```
2614/// use itertools::Itertools;
2615/// use malachite_base::random::EXAMPLE_SEED;
2616/// use malachite_base::rounding_modes::RoundingMode::*;
2617/// use malachite_float::float::random::normal_random_floats;
2618/// use malachite_float::ComparableFloat;
2619///
2620/// // The number after the '#' is the precision.
2621/// assert_eq!(
2622/// normal_random_floats(EXAMPLE_SEED, 10, Nearest)
2623/// .take(20)
2624/// .map(|f| ComparableFloat(f).to_string())
2625/// .collect_vec()
2626/// .as_slice(),
2627/// &[
2628/// "-0.45166#10",
2629/// "-2.2695#10",
2630/// "-2.1602#10",
2631/// "-0.78516#10",
2632/// "0.23486#10",
2633/// "-0.61230#10",
2634/// "-0.91797#10",
2635/// "-0.13672#10",
2636/// "1.2891#10",
2637/// "-0.045227#10",
2638/// "-0.77051#10",
2639/// "-0.21143#10",
2640/// "0.61621#10",
2641/// "-0.58594#10",
2642/// "0.57520#10",
2643/// "1.0117#10",
2644/// "0.58008#10",
2645/// "1.0195#10",
2646/// "0.89453#10",
2647/// "-0.069092#10"
2648/// ]
2649/// );
2650/// ```
2651#[inline]
2652pub fn normal_random_floats(
2653 seed: Seed,
2654 prec: u64,
2655 rm: RoundingMode,
2656) -> NormalRandomFloats<RandomPrimitiveInts<u64>> {
2657 normal_random_floats_from_u64s(random_primitive_ints(seed), prec, rm)
2658}