Skip to main content

malachite_base/unsigned_polynomial/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::iterators::{NonzeroValues, nonzero_values};
10use crate::num::basic::integers::PrimitiveInt;
11use crate::num::basic::unsigneds::PrimitiveUnsigned;
12use crate::num::random::geometric::GeometricRandomNaturalValues;
13use crate::num::random::striped::{
14    StripedRandomUnsignedBitChunks, StripedRandomUnsignedInclusiveRange,
15    striped_random_positive_unsigneds, striped_random_unsigned_bit_chunks,
16    striped_random_unsigned_range, striped_random_unsigneds,
17};
18use crate::num::random::{
19    RandomPrimitiveInts, RandomUnsignedInclusiveRange, RandomUnsignedRange,
20    random_positive_unsigneds, random_primitive_ints, random_unsigned_inclusive_range,
21    random_unsigned_range,
22};
23use crate::polynomial::Polynomial;
24use crate::random::Seed;
25use crate::unsigned_polynomial::UnsignedPolynomial;
26use crate::vecs::random::{
27    RandomFixedLengthVecsWithLast, RandomVecsWithLast, random_vecs_with_last,
28    random_vecs_with_last_fixed_length, random_vecs_with_last_length_inclusive_range,
29    random_vecs_with_last_min_length,
30};
31
32/// Generates random [`UnsignedPolynomial`]s with coefficients from one iterator and leading
33/// coefficients from another.
34///
35/// This `struct` is created by [`random_unsigned_polynomials_from_iterators`] and the generators
36/// built on it; see their documentation for more.
37#[derive(Clone, Debug)]
38pub struct RandomUnsignedPolynomials<
39    T: PrimitiveUnsigned,
40    I: Iterator<Item = u64>,
41    J: Iterator<Item = T>,
42    K: Iterator<Item = T>,
43>(RandomVecsWithLast<T, I, J, K>);
44
45impl<T: PrimitiveUnsigned, I: Iterator<Item = u64>, J: Iterator<Item = T>, K: Iterator<Item = T>>
46    Iterator for RandomUnsignedPolynomials<T, I, J, K>
47{
48    type Item = UnsignedPolynomial<T>;
49
50    #[inline]
51    fn next(&mut self) -> Option<UnsignedPolynomial<T>> {
52        self.0.next().map(UnsignedPolynomial::from_coefficients_asc)
53    }
54}
55
56/// The type of the [`UnsignedPolynomial`] generators that draw their coefficients from every
57/// [`u64`] and their leading coefficients from every positive one, with lengths from a geometric
58/// distribution.
59pub type RandomUnsignedPolynomialsFromUnsigneds<T> = RandomUnsignedPolynomials<
60    T,
61    GeometricRandomNaturalValues<u64>,
62    RandomPolynomialCoefficients<T>,
63    RandomPolynomialLeadingCoefficients<T>,
64>;
65
66/// Generates random [`UnsignedPolynomial`]s whose coefficients come from one iterator and whose
67/// leading coefficients come from another.
68///
69/// A polynomial is its coefficients, and the only thing that distinguishes them from any other list
70/// of [`u64`]s is that the last of them may not be zero. Singling out that one coefficient is
71/// therefore all it takes: `xs_gen` supplies every coefficient below the leading one, and `ys_gen`
72/// supplies the leading one.
73///
74/// `ys_gen` should produce no zeros, since a polynomial's leading coefficient is never zero. If it
75/// does, the zeros are trimmed away, and the polynomial has a lower degree than its length
76/// suggests.
77///
78/// The lengths of the polynomials — the number of coefficients, which is one more than the
79/// degree, or zero for the zero polynomial — are sampled from a geometric distribution with a
80/// specified mean $m$, equal to `mean_length_numerator / mean_length_denominator`. $m$ must be
81/// greater than 0.
82///
83/// The iterators produced by `xs_gen` and `ys_gen` must be infinite.
84///
85/// # Worst-case complexity per iteration
86/// $T(i) = O(\ell T^\prime(i))$
87///
88/// $M(i) = O(\ell M^\prime(i))$
89///
90/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $T^\prime$ and
91/// $M^\prime$ are the time and memory functions of the iterators produced by `xs_gen` and `ys_gen`,
92/// and $\ell$ is the number of coefficients of the $i$th output.
93///
94/// # Panics
95/// Panics if `mean_length_numerator` or `mean_length_denominator` are zero, or if their ratio is
96/// greater than or equal to $2^{64}$.
97///
98/// # Examples
99/// ```
100/// use malachite_base::iterators::prefix_to_string;
101/// use malachite_base::num::random::{random_positive_unsigneds, random_primitive_ints};
102/// use malachite_base::random::EXAMPLE_SEED;
103/// use malachite_base::unsigned_polynomial::random::random_unsigned_polynomials_from_iterators;
104///
105/// assert_eq!(
106///     prefix_to_string(
107///         random_unsigned_polynomials_from_iterators(
108///             EXAMPLE_SEED,
109///             &|seed| random_primitive_ints::<u64>(seed),
110///             &|seed| random_positive_unsigneds::<u64>(seed),
111///             1,
112///             1,
113///         ),
114///         5
115///     ),
116///     "[6282517168718784610, 3854918945212287108*x+16126131237969988437, 3848495687584076941*x+16\
117///     908237734149745446, 8242875068444962379*x+10938355129926736414, 33570146165392012, ...]"
118/// );
119/// ```
120#[inline]
121pub fn random_unsigned_polynomials_from_iterators<
122    T: PrimitiveUnsigned,
123    J: Iterator<Item = T>,
124    K: Iterator<Item = T>,
125>(
126    seed: Seed,
127    xs_gen: &dyn Fn(Seed) -> J,
128    ys_gen: &dyn Fn(Seed) -> K,
129    mean_length_numerator: u64,
130    mean_length_denominator: u64,
131) -> RandomUnsignedPolynomials<T, GeometricRandomNaturalValues<u64>, J, K> {
132    RandomUnsignedPolynomials(random_vecs_with_last(
133        seed,
134        xs_gen,
135        ys_gen,
136        mean_length_numerator,
137        mean_length_denominator,
138    ))
139}
140
141/// Generates random [`UnsignedPolynomial`]s.
142///
143/// The coefficients are sampled from [`random_primitive_ints`] and the leading coefficient from
144/// [`random_positive_unsigneds`], so each is uniform over its whole range — a [`u64`] has no mean
145/// bit count to choose.
146///
147/// The lengths — the number of coefficients, which is one more than the degree, or zero for the
148/// zero polynomial — are sampled from a geometric distribution with mean `mean_length_numerator /
149/// mean_length_denominator`, so the zero polynomial is generated with the probability that that
150/// distribution gives to 0.
151///
152/// # Worst-case complexity per iteration
153/// $T(i) = O(\ell)$
154///
155/// $M(i) = O(\ell)$
156///
157/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $\ell$ is the number
158/// of coefficients of the $i$th output.
159///
160/// # Panics
161/// Panics if `mean_length_numerator` or `mean_length_denominator` are zero or their ratio is
162/// greater than or equal to $2^{64}$.
163///
164/// # Examples
165/// ```
166/// use malachite_base::iterators::prefix_to_string;
167/// use malachite_base::random::EXAMPLE_SEED;
168/// use malachite_base::unsigned_polynomial::random::random_unsigned_polynomials;
169///
170/// assert_eq!(
171///     prefix_to_string(random_unsigned_polynomials::<u64>(EXAMPLE_SEED, 1, 1), 5),
172///     "[6282517168718784610, 3854918945212287108*x+16126131237969988437, 3848495687584076941*x+16\
173///     908237734149745446, 8242875068444962379*x+10938355129926736414, 33570146165392012, ...]"
174/// );
175/// ```
176#[inline]
177pub fn random_unsigned_polynomials<T: PrimitiveUnsigned>(
178    seed: Seed,
179    mean_length_numerator: u64,
180    mean_length_denominator: u64,
181) -> RandomUnsignedPolynomialsFromUnsigneds<T> {
182    random_unsigned_polynomials_from_iterators(
183        seed,
184        &|seed_2| random_primitive_ints(seed_2),
185        &|seed_2| random_positive_unsigneds(seed_2),
186        mean_length_numerator,
187        mean_length_denominator,
188    )
189}
190
191/// Generates random [`UnsignedPolynomial`]s of a given degree, with coefficients from one iterator
192/// and leading coefficients from another.
193///
194/// This `struct` is created by [`random_unsigned_polynomials_with_degree`] and
195/// [`striped_random_unsigned_polynomials_with_degree`]; see their documentation for more.
196#[derive(Clone, Debug)]
197pub struct RandomUnsignedPolynomialsWithDegree<
198    T: PrimitiveUnsigned,
199    J: Iterator<Item = T>,
200    K: Iterator<Item = T>,
201>(RandomFixedLengthVecsWithLast<T, J, K>);
202
203impl<T: PrimitiveUnsigned, J: Iterator<Item = T>, K: Iterator<Item = T>> Iterator
204    for RandomUnsignedPolynomialsWithDegree<T, J, K>
205{
206    type Item = UnsignedPolynomial<T>;
207
208    #[inline]
209    fn next(&mut self) -> Option<UnsignedPolynomial<T>> {
210        self.0.next().map(UnsignedPolynomial::from_coefficients_asc)
211    }
212}
213
214/// The coefficients that the unstriped [`UnsignedPolynomial`] generators draw on.
215pub type RandomPolynomialCoefficients<T> = RandomPrimitiveInts<T>;
216
217/// The leading coefficients that the unstriped [`UnsignedPolynomial`] generators draw on: a
218/// polynomial's leading coefficient is never zero.
219pub type RandomPolynomialLeadingCoefficients<T> = NonzeroValues<RandomPrimitiveInts<T>>;
220
221/// The coefficients that the striped [`UnsignedPolynomial`] generators draw on.
222pub type StripedRandomPolynomialCoefficients<T> = StripedRandomUnsignedBitChunks<T>;
223
224/// The leading coefficients that the striped [`UnsignedPolynomial`] generators draw on.
225pub type StripedRandomPolynomialLeadingCoefficients<T> =
226    NonzeroValues<StripedRandomUnsignedBitChunks<T>>;
227
228/// The type of the [`UnsignedPolynomial`] generator whose degree is fixed.
229pub type RandomUnsignedPolynomialsWithFixedDegree<T> = RandomUnsignedPolynomialsWithDegree<
230    T,
231    RandomPolynomialCoefficients<T>,
232    RandomPolynomialLeadingCoefficients<T>,
233>;
234
235/// The type of the [`UnsignedPolynomial`] generators whose degrees are uniform over a range.
236pub type RandomUnsignedPolynomialsInDegreeRange<T> = RandomUnsignedPolynomials<
237    T,
238    RandomUnsignedInclusiveRange<u64>,
239    RandomPolynomialCoefficients<T>,
240    RandomPolynomialLeadingCoefficients<T>,
241>;
242
243/// The type of the striped [`UnsignedPolynomial`] generators with geometrically distributed
244/// lengths.
245pub type StripedRandomUnsignedPolynomialsFromUnsigneds<T> = RandomUnsignedPolynomials<
246    T,
247    GeometricRandomNaturalValues<u64>,
248    StripedRandomPolynomialCoefficients<T>,
249    StripedRandomPolynomialLeadingCoefficients<T>,
250>;
251
252/// The type of the striped [`UnsignedPolynomial`] generator whose degree is fixed.
253pub type StripedRandomUnsignedPolynomialsWithFixedDegree<T> = RandomUnsignedPolynomialsWithDegree<
254    T,
255    StripedRandomPolynomialCoefficients<T>,
256    StripedRandomPolynomialLeadingCoefficients<T>,
257>;
258
259/// The type of the striped [`UnsignedPolynomial`] generators whose degrees are uniform over a
260/// range.
261pub type StripedRandomUnsignedPolynomialsInDegreeRange<T> = RandomUnsignedPolynomials<
262    T,
263    RandomUnsignedInclusiveRange<u64>,
264    StripedRandomPolynomialCoefficients<T>,
265    StripedRandomPolynomialLeadingCoefficients<T>,
266>;
267
268/// Generates random [`UnsignedPolynomial`]s of a given degree.
269///
270/// A polynomial of degree $d$ has $d+1$ coefficients, of which the leading one is positive. The
271/// zero polynomial is never generated: it has no degree at all, so no degree is the one it has.
272///
273/// The coefficients are sampled from [`random_primitive_ints`] and the leading coefficient from
274/// [`random_positive_unsigneds`], so each is uniform over its whole range — a [`u64`] has no mean
275/// bit count to choose.
276///
277/// # Worst-case complexity per iteration
278/// $T(i) = O(d)$
279///
280/// $M(i) = O(d)$
281///
282/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $d$ is `degree`, and
283/// the coefficients are 64 bits each.
284///
285/// # Panics
286/// Never panics.
287///
288/// # Examples
289/// ```
290/// use malachite_base::iterators::prefix_to_string;
291/// use malachite_base::random::EXAMPLE_SEED;
292/// use malachite_base::unsigned_polynomial::random::random_unsigned_polynomials_with_degree;
293///
294/// assert_eq!(
295///     prefix_to_string(
296///         random_unsigned_polynomials_with_degree::<u64>(EXAMPLE_SEED, 2),
297///         5
298///     ),
299///     "[6282517168718784610*x^2+16908237734149745446*x+16126131237969988437, 3854918945212287108*\
300///     x^2+12663883950309859797*x+10938355129926736414, 3848495687584076941*x^2+160309163093886283\
301///     38*x+14328508029084493994, 8242875068444962379*x^2+6855165495190718789*x+527496784918977578\
302///     9, 33570146165392012*x^2+5364743571823285937*x+12452306358869796714, ...]"
303/// );
304/// ```
305#[inline]
306pub fn random_unsigned_polynomials_with_degree<T: PrimitiveUnsigned>(
307    seed: Seed,
308    degree: u64,
309) -> RandomUnsignedPolynomialsWithFixedDegree<T> {
310    RandomUnsignedPolynomialsWithDegree(random_vecs_with_last_fixed_length(
311        degree.saturating_add(1),
312        random_primitive_ints(seed.fork("xs")),
313        random_positive_unsigneds(seed.fork("ys")),
314    ))
315}
316
317/// Generates random [`UnsignedPolynomial`]s with a minimum degree.
318///
319/// The zero polynomial is never generated: it has no degree at all, so it is not of any degree at
320/// least `min_degree`.
321///
322/// The coefficients are sampled from [`random_primitive_ints`] and the leading coefficient from
323/// [`random_positive_unsigneds`], so each is uniform over its whole range — a [`u64`] has no mean
324/// bit count to choose. The lengths — the number of coefficients, which is one more than the
325/// degree — are sampled from a geometric distribution with mean `mean_length_numerator /
326/// mean_length_denominator`, which must be greater than `min_degree + 1`.
327///
328/// # Worst-case complexity per iteration
329/// $T(i) = O(\ell)$
330///
331/// $M(i) = O(\ell)$
332///
333/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $\ell$ is the number
334/// of coefficients of the $i$th output.
335///
336/// # Panics
337/// Panics if `mean_length_numerator / mean_length_denominator` is less than or equal to `min_degree
338/// + 1`.
339///
340/// # Examples
341/// ```
342/// use malachite_base::iterators::prefix_to_string;
343/// use malachite_base::random::EXAMPLE_SEED;
344/// use malachite_base::unsigned_polynomial::random::random_unsigned_polynomials_min_degree;
345///
346/// assert_eq!(
347///     prefix_to_string(
348///         random_unsigned_polynomials_min_degree::<u64>(EXAMPLE_SEED, 1, 3, 1),
349///         5
350///     ),
351///     "[6282517168718784610*x^2+16908237734149745446*x+16126131237969988437, 3854918945212287108*\
352///     x^3+14328508029084493994*x^2+12663883950309859797*x+10938355129926736414, 38484956875840769\
353///     41*x^3+6855165495190718789*x^2+5274967849189775789*x+16030916309388628338, 8242875068444962\
354///     379*x^3+18084098515246349065*x^2+5364743571823285937*x+12452306358869796714, 33570146165392\
355///     012*x^2+8082601913180739774*x+4929296619887363376, ...]"
356/// );
357/// ```
358#[inline]
359pub fn random_unsigned_polynomials_min_degree<T: PrimitiveUnsigned>(
360    seed: Seed,
361    min_degree: u64,
362    mean_length_numerator: u64,
363    mean_length_denominator: u64,
364) -> RandomUnsignedPolynomialsFromUnsigneds<T> {
365    RandomUnsignedPolynomials(random_vecs_with_last_min_length(
366        seed,
367        min_degree.saturating_add(1),
368        &|seed_2| random_primitive_ints(seed_2),
369        &|seed_2| random_positive_unsigneds(seed_2),
370        mean_length_numerator,
371        mean_length_denominator,
372    ))
373}
374
375/// Generates random [`UnsignedPolynomial`]s with degrees in $[a, b)$.
376///
377/// The degrees are sampled from a uniform distribution on $[a, b)$. The zero polynomial is never
378/// generated: it has no degree at all, so its degree is in no range.
379///
380/// The coefficients are sampled from [`random_primitive_ints`] and the leading coefficient from
381/// [`random_positive_unsigneds`], so each is uniform over its whole range — a [`u64`] has no mean
382/// bit count to choose.
383///
384/// # Worst-case complexity per iteration
385/// $T(i) = O(bd)$
386///
387/// $M(i) = O(bd)$
388///
389/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $d$ is $b$, and $b$ is
390/// `mean_bits_numerator / mean_bits_denominator`.
391///
392/// # Panics
393/// Panics if $a \geq b$, nothing else.
394///
395/// # Examples
396/// ```
397/// use malachite_base::iterators::prefix_to_string;
398/// use malachite_base::random::EXAMPLE_SEED;
399/// use malachite_base::unsigned_polynomial::random::random_unsigned_polynomials_degree_range;
400///
401/// assert_eq!(
402///     prefix_to_string(
403///         random_unsigned_polynomials_degree_range::<u64>(EXAMPLE_SEED, 1, 3),
404///         5
405///     ),
406///     "[6282517168718784610*x^2+16908237734149745446*x+16126131237969988437, 3854918945212287108*\
407///     x+10938355129926736414, 3848495687584076941*x^2+14328508029084493994*x+12663883950309859797\
408///     , 8242875068444962379*x^2+5274967849189775789*x+16030916309388628338, 33570146165392012*x+6\
409///     855165495190718789, ...]"
410/// );
411/// ```
412#[inline]
413pub fn random_unsigned_polynomials_degree_range<T: PrimitiveUnsigned>(
414    seed: Seed,
415    a: u64,
416    b: u64,
417) -> RandomUnsignedPolynomialsInDegreeRange<T> {
418    assert!(a < b, "the degree range [{a}, {b}) is empty");
419    random_unsigned_polynomials_degree_inclusive_range(seed, a, b - 1)
420}
421
422/// Generates random [`UnsignedPolynomial`]s with degrees in $[a, b]$.
423///
424/// The degrees are sampled from a uniform distribution on $[a, b]$. The zero polynomial is never
425/// generated: it has no degree at all, so its degree is in no range.
426///
427/// The coefficients are sampled from [`random_primitive_ints`] and the leading coefficient from
428/// [`random_positive_unsigneds`], so each is uniform over its whole range — a [`u64`] has no mean
429/// bit count to choose.
430///
431/// # Worst-case complexity per iteration
432/// $T(i) = O(b)$
433///
434/// $M(i) = O(b)$
435///
436/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, and $b$ is the upper
437/// bound on the degree.
438///
439/// # Panics
440/// Panics if $a > b$, nothing else.
441///
442/// # Examples
443/// ```
444/// use malachite_base::iterators::prefix_to_string;
445/// use malachite_base::random::EXAMPLE_SEED;
446/// use malachite_base::unsigned_polynomial::random::*;
447///
448/// assert_eq!(
449///     prefix_to_string(
450///         random_unsigned_polynomials_degree_inclusive_range::<u64>(EXAMPLE_SEED, 1, 2),
451///         5
452///     ),
453///     "[6282517168718784610*x^2+16908237734149745446*x+16126131237969988437, 3854918945212287108*\
454///     x+10938355129926736414, 3848495687584076941*x^2+14328508029084493994*x+12663883950309859797\
455///     , 8242875068444962379*x^2+5274967849189775789*x+16030916309388628338, 33570146165392012*x+6\
456///     855165495190718789, ...]"
457/// );
458/// ```
459#[inline]
460pub fn random_unsigned_polynomials_degree_inclusive_range<T: PrimitiveUnsigned>(
461    seed: Seed,
462    a: u64,
463    b: u64,
464) -> RandomUnsignedPolynomialsInDegreeRange<T> {
465    assert!(a <= b, "the degree range [{a}, {b}] is empty");
466    RandomUnsignedPolynomials(random_vecs_with_last_length_inclusive_range(
467        seed,
468        a.saturating_add(1),
469        b.saturating_add(1),
470        &|seed_2| random_primitive_ints(seed_2),
471        &|seed_2| random_positive_unsigneds(seed_2),
472    ))
473}
474
475/// Generates random [`UnsignedPolynomial`]s with striped coefficients.
476///
477/// The coefficients are sampled from [`striped_random_unsigneds`] and the leading coefficient from
478/// [`striped_random_positive_unsigneds`], with a mean run length of `mean_stripe_numerator /
479/// mean_stripe_denominator` and a mean bit count of `mean_bits_numerator / mean_bits_denominator`.
480/// A striped coefficient is one whose bits come in long runs, which is what makes the carries and
481/// borrows of an arithmetic test interesting.
482///
483/// The lengths — the number of coefficients, which is one more than the degree, or zero for the
484/// zero polynomial — are sampled from a geometric distribution with mean `mean_length_numerator /
485/// mean_length_denominator`, so the zero polynomial is generated with the probability that that
486/// distribution gives to 0.
487///
488/// # Worst-case complexity per iteration
489/// $T(i) = O(\ell)$
490///
491/// $M(i) = O(\ell)$
492///
493/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $\ell$ is the number
494/// of coefficients of the $i$th output.
495///
496/// # Panics
497/// Panics if `mean_stripe_denominator` is zero, if `mean_stripe_numerator <
498/// mean_stripe_denominator`, if `mean_bits_numerator` or `mean_bits_denominator` are zero, if their
499/// ratio is less than or equal to 1, or if `mean_length_numerator` or `mean_length_denominator` are
500/// zero or their ratio is greater than or equal to $2^{64}$.
501///
502/// # Examples
503/// ```
504/// use malachite_base::iterators::prefix_to_string;
505/// use malachite_base::random::EXAMPLE_SEED;
506/// use malachite_base::unsigned_polynomial::random::striped_random_unsigned_polynomials;
507///
508/// assert_eq!(
509///     prefix_to_string(
510///         striped_random_unsigned_polynomials::<u64>(EXAMPLE_SEED, 16, 1, 1, 1),
511///         5
512///     ),
513///     "[271656550527, 27127151148662784*x+18302682203357708288, 8866461766451184*x+18446744005015\
514///     272960, 18446181398633971712*x+9727775212300075008, 18446708889362628608, ...]"
515/// );
516/// ```
517#[inline]
518pub fn striped_random_unsigned_polynomials<T: PrimitiveUnsigned>(
519    seed: Seed,
520    mean_stripe_numerator: u64,
521    mean_stripe_denominator: u64,
522    mean_length_numerator: u64,
523    mean_length_denominator: u64,
524) -> StripedRandomUnsignedPolynomialsFromUnsigneds<T> {
525    random_unsigned_polynomials_from_iterators(
526        seed,
527        &|seed_2| striped_random_unsigneds(seed_2, mean_stripe_numerator, mean_stripe_denominator),
528        &|seed_2| {
529            striped_random_positive_unsigneds(
530                seed_2,
531                mean_stripe_numerator,
532                mean_stripe_denominator,
533            )
534        },
535        mean_length_numerator,
536        mean_length_denominator,
537    )
538}
539
540/// Generates random [`UnsignedPolynomial`]s of a given degree, with striped coefficients.
541///
542/// A polynomial of degree $d$ has $d+1$ coefficients, of which the leading one is positive. The
543/// zero polynomial is never generated: it has no degree at all, so no degree is the one it has.
544///
545/// The coefficients are striped, as they are in [`striped_random_unsigned_polynomials`].
546///
547/// # Worst-case complexity per iteration
548/// $T(i) = O(d)$
549///
550/// $M(i) = O(d)$
551///
552/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $d$ is `degree`, and
553/// the coefficients are 64 bits each.
554///
555/// # Panics
556/// Panics if `mean_stripe_denominator` is zero, if `mean_stripe_numerator <
557/// mean_stripe_denominator`, if `mean_bits_numerator` or `mean_bits_denominator` are zero, or if
558/// their ratio is less than or equal to 1.
559///
560/// # Examples
561/// ```
562/// use malachite_base::iterators::prefix_to_string;
563/// use malachite_base::random::EXAMPLE_SEED;
564/// use malachite_base::unsigned_polynomial::random::*;
565///
566/// assert_eq!(
567///     prefix_to_string(
568///         striped_random_unsigned_polynomials_with_degree::<u64>(EXAMPLE_SEED, 2, 16, 1),
569///         5
570///     ),
571///     "[271656550527*x^2+18446744005015272960*x+18302682203357708288, 27127151148662784*x^2+22517\
572///     99813816318*x+9727775212300075008, 8866461766451184*x^2+79164805742588*x+4398046510592, 184\
573///     46181398633971712*x^2+13835058055549583359*x+31525223161659391, 18446708889362628608*x^2+90\
574///     07199254740543*x+9223652962075148288, ...]"
575/// );
576/// ```
577#[inline]
578pub fn striped_random_unsigned_polynomials_with_degree<T: PrimitiveUnsigned>(
579    seed: Seed,
580    degree: u64,
581    mean_stripe_numerator: u64,
582    mean_stripe_denominator: u64,
583) -> StripedRandomUnsignedPolynomialsWithFixedDegree<T> {
584    RandomUnsignedPolynomialsWithDegree(random_vecs_with_last_fixed_length(
585        degree.saturating_add(1),
586        striped_random_unsigneds(
587            seed.fork("xs"),
588            mean_stripe_numerator,
589            mean_stripe_denominator,
590        ),
591        striped_random_positive_unsigneds(
592            seed.fork("ys"),
593            mean_stripe_numerator,
594            mean_stripe_denominator,
595        ),
596    ))
597}
598
599/// Generates random [`UnsignedPolynomial`]s with a minimum degree and striped coefficients.
600///
601/// The zero polynomial is never generated: it has no degree at all, so it is not of any degree at
602/// least `min_degree`.
603///
604/// The coefficients are striped, as they are in [`striped_random_unsigned_polynomials`]. The
605/// lengths — one more than the degree — are sampled from a geometric distribution with mean
606/// `mean_length_numerator / mean_length_denominator`, which must be greater than `min_degree + 1`.
607///
608/// # Worst-case complexity per iteration
609/// $T(i) = O(\ell)$
610///
611/// $M(i) = O(\ell)$
612///
613/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $\ell$ is the number
614/// of coefficients of the $i$th output.
615///
616/// # Panics
617/// Panics if `mean_stripe_denominator` is zero, if `mean_stripe_numerator <
618/// mean_stripe_denominator`, if `mean_bits_numerator` or `mean_bits_denominator` are zero, if their
619/// ratio is less than or equal to 1, or if `mean_length_numerator / mean_length_denominator` is
620/// less than or equal to `min_degree + 1`.
621///
622/// # Examples
623/// ```
624/// use malachite_base::iterators::prefix_to_string;
625/// use malachite_base::random::EXAMPLE_SEED;
626/// use malachite_base::unsigned_polynomial::random::*;
627///
628/// assert_eq!(
629///     prefix_to_string(
630///         striped_random_unsigned_polynomials_min_degree::<u64>(EXAMPLE_SEED, 1, 16, 1, 3, 1),
631///         5
632///     ),
633///     "[271656550527*x^2+18446744005015272960*x+18302682203357708288, 27127151148662784*x^3+43980\
634///     46510592*x^2+2251799813816318*x+9727775212300075008, 8866461766451184*x^3+13835058055549583\
635///     359*x^2+31525223161659391*x+79164805742588, 18446181398633971712*x^3+4398046446591*x^2+9007\
636///     199254740543*x+9223652962075148288, 18446708889362628608*x^2+35047000244217*x, ...]"
637/// );
638/// ```
639#[inline]
640pub fn striped_random_unsigned_polynomials_min_degree<T: PrimitiveUnsigned>(
641    seed: Seed,
642    min_degree: u64,
643    mean_stripe_numerator: u64,
644    mean_stripe_denominator: u64,
645    mean_length_numerator: u64,
646    mean_length_denominator: u64,
647) -> StripedRandomUnsignedPolynomialsFromUnsigneds<T> {
648    RandomUnsignedPolynomials(random_vecs_with_last_min_length(
649        seed,
650        min_degree.saturating_add(1),
651        &|seed_2| striped_random_unsigneds(seed_2, mean_stripe_numerator, mean_stripe_denominator),
652        &|seed_2| {
653            striped_random_positive_unsigneds(
654                seed_2,
655                mean_stripe_numerator,
656                mean_stripe_denominator,
657            )
658        },
659        mean_length_numerator,
660        mean_length_denominator,
661    ))
662}
663
664/// Generates random [`UnsignedPolynomial`]s with degrees in $[a, b)$ and striped coefficients.
665///
666/// The degrees are sampled from a uniform distribution on $[a, b)$. The zero polynomial is never
667/// generated: it has no degree at all, so its degree is in no range.
668///
669/// The coefficients are striped, as they are in [`striped_random_unsigned_polynomials`].
670///
671/// # Worst-case complexity per iteration
672/// $T(i) = O(bd)$
673///
674/// $M(i) = O(bd)$
675///
676/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $d$ is $b$, and $b$ is
677/// `mean_bits_numerator / mean_bits_denominator`.
678///
679/// # Panics
680/// Panics if $a \geq b$, if `mean_stripe_denominator` is zero, if `mean_stripe_numerator <
681/// mean_stripe_denominator`, if `mean_bits_numerator` or `mean_bits_denominator` are zero, or if
682/// their ratio is less than or equal to 1.
683///
684/// # Examples
685/// ```
686/// use malachite_base::iterators::prefix_to_string;
687/// use malachite_base::random::EXAMPLE_SEED;
688/// use malachite_base::unsigned_polynomial::random::*;
689///
690/// assert_eq!(
691///     prefix_to_string(
692///         striped_random_unsigned_polynomials_degree_range::<u64>(EXAMPLE_SEED, 1, 3, 16, 1),
693///         5
694///     ),
695///     "[271656550527*x^2+18446744005015272960*x+18302682203357708288, 27127151148662784*x+9727775\
696///     212300075008, 8866461766451184*x^2+4398046510592*x+2251799813816318, 18446181398633971712*x\
697///     ^2+31525223161659391*x+79164805742588, 18446708889362628608*x+13835058055549583359, ...]"
698/// );
699/// ```
700#[inline]
701pub fn striped_random_unsigned_polynomials_degree_range<T: PrimitiveUnsigned>(
702    seed: Seed,
703    a: u64,
704    b: u64,
705    mean_stripe_numerator: u64,
706    mean_stripe_denominator: u64,
707) -> StripedRandomUnsignedPolynomialsInDegreeRange<T> {
708    assert!(a < b, "the degree range [{a}, {b}) is empty");
709    striped_random_unsigned_polynomials_degree_inclusive_range(
710        seed,
711        a,
712        b - 1,
713        mean_stripe_numerator,
714        mean_stripe_denominator,
715    )
716}
717
718/// Generates random [`UnsignedPolynomial`]s with degrees in $[a, b]$ and striped coefficients.
719///
720/// The degrees are sampled from a uniform distribution on $[a, b]$. The zero polynomial is never
721/// generated: it has no degree at all, so its degree is in no range.
722///
723/// The coefficients are striped, as they are in [`striped_random_unsigned_polynomials`].
724///
725/// # Worst-case complexity per iteration
726/// $T(i) = O(b)$
727///
728/// $M(i) = O(b)$
729///
730/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, and $b$ is the upper
731/// bound on the degree.
732///
733/// # Panics
734/// Panics if $a > b$, if `mean_stripe_denominator` is zero, if `mean_stripe_numerator <
735/// mean_stripe_denominator`, if `mean_bits_numerator` or `mean_bits_denominator` are zero, or if
736/// their ratio is less than or equal to 1.
737///
738/// # Examples
739/// ```
740/// use malachite_base::iterators::prefix_to_string;
741/// use malachite_base::random::EXAMPLE_SEED;
742/// use malachite_base::unsigned_polynomial::random::*;
743///
744/// assert_eq!(
745///     prefix_to_string(
746///         striped_random_unsigned_polynomials_degree_inclusive_range::<u64>(
747///             EXAMPLE_SEED,
748///             1,
749///             2,
750///             16,
751///             1
752///         ),
753///         5
754///     ),
755///     "[271656550527*x^2+18446744005015272960*x+18302682203357708288, 27127151148662784*x+9727775\
756///     212300075008, 8866461766451184*x^2+4398046510592*x+2251799813816318, 18446181398633971712*x\
757///     ^2+31525223161659391*x+79164805742588, 18446708889362628608*x+13835058055549583359, ...]"
758/// );
759/// ```
760#[inline]
761pub fn striped_random_unsigned_polynomials_degree_inclusive_range<T: PrimitiveUnsigned>(
762    seed: Seed,
763    a: u64,
764    b: u64,
765    mean_stripe_numerator: u64,
766    mean_stripe_denominator: u64,
767) -> StripedRandomUnsignedPolynomialsInDegreeRange<T> {
768    assert!(a <= b, "the degree range [{a}, {b}] is empty");
769    RandomUnsignedPolynomials(random_vecs_with_last_length_inclusive_range(
770        seed,
771        a.saturating_add(1),
772        b.saturating_add(1),
773        &|seed_2| striped_random_unsigneds(seed_2, mean_stripe_numerator, mean_stripe_denominator),
774        &|seed_2| {
775            striped_random_positive_unsigneds(
776                seed_2,
777                mean_stripe_numerator,
778                mean_stripe_denominator,
779            )
780        },
781    ))
782}
783
784/// The type of the [`UnsignedPolynomial`] generator whose coefficients are reduced modulo a power
785/// of 2.
786pub type RandomUnsignedPolynomialsReducedModPowerOf2<T> = RandomUnsignedPolynomials<
787    T,
788    GeometricRandomNaturalValues<u64>,
789    RandomUnsignedInclusiveRange<T>,
790    RandomUnsignedInclusiveRange<T>,
791>;
792
793/// Generates random [`UnsignedPolynomial`]s that are reduced modulo $2^k$.
794///
795/// A polynomial is reduced modulo $2^k$ when every one of its coefficients is, so the coefficients
796/// are sampled uniformly from $[0, 2^k)$ and the leading coefficient, which may not be zero, from
797/// $[1, 2^k)$.
798///
799/// The lengths — the number of coefficients, which is one more than the degree, or zero for the
800/// zero polynomial — are sampled from a geometric distribution with mean `mean_length_numerator /
801/// mean_length_denominator`.
802///
803/// # Worst-case complexity per iteration
804/// $T(i) = O(\ell)$
805///
806/// $M(i) = O(\ell)$
807///
808/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, and $\ell$ is the
809/// number of coefficients of the $i$th output.
810///
811/// # Panics
812/// Panics if `pow` is zero or greater than 64, if `mean_length_numerator` or
813/// `mean_length_denominator` are zero, or if their ratio is greater than or equal to $2^{64}$. The
814/// only polynomial reduced modulo $2^0$ is the zero polynomial, which leaves no leading coefficient
815/// to choose, and no [`u64`] has more than 64 bits.
816///
817/// # Examples
818/// ```
819/// use malachite_base::iterators::prefix_to_string;
820/// use malachite_base::random::EXAMPLE_SEED;
821/// use malachite_base::unsigned_polynomial::random::*;
822///
823/// assert_eq!(
824///     prefix_to_string(
825///         random_unsigned_polynomials_reduced_mod_power_of_2::<u64>(EXAMPLE_SEED, 4, 2, 1),
826///         5
827///     ),
828///     "[3*x^5+8*x^4+11*x^2+5*x+5, 7, \
829///     9*x^7+8*x^6+6*x^5+14*x^4+11*x^3+12*x^2+8*x+8, 11, \
830///     7*x^13+2*x^12+11*x^11+x^10+13*x^9+9*x^8+14*x^7+11*x^6+2*x^5+6*x^4+13*x^3+15*x^2+12*x+11, \
831///     ...]"
832/// );
833/// ```
834#[inline]
835pub fn random_unsigned_polynomials_reduced_mod_power_of_2<T: PrimitiveUnsigned>(
836    seed: Seed,
837    pow: u64,
838    mean_length_numerator: u64,
839    mean_length_denominator: u64,
840) -> RandomUnsignedPolynomialsReducedModPowerOf2<T> {
841    assert_ne!(
842        pow, 0,
843        "the only polynomial reduced modulo 2^0 is the zero polynomial"
844    );
845    assert!(pow <= T::WIDTH);
846    let max = T::low_mask(pow);
847    random_unsigned_polynomials_from_iterators(
848        seed,
849        &|seed_2| random_unsigned_inclusive_range(seed_2, T::ZERO, max),
850        &|seed_2| random_unsigned_inclusive_range(seed_2, T::ONE, max),
851        mean_length_numerator,
852        mean_length_denominator,
853    )
854}
855
856/// The type of the striped [`UnsignedPolynomial`] generator whose coefficients are reduced modulo a
857/// power of 2.
858pub type StripedRandomUnsignedPolynomialsReducedModPowerOf2<T> = RandomUnsignedPolynomials<
859    T,
860    GeometricRandomNaturalValues<u64>,
861    StripedRandomUnsignedBitChunks<T>,
862    NonzeroValues<StripedRandomUnsignedBitChunks<T>>,
863>;
864
865/// Generates random [`UnsignedPolynomial`]s that are reduced modulo $2^k$, with striped
866/// coefficients.
867///
868/// A coefficient is a striped bit chunk $k$ bits wide, which is exactly a value below $2^k$, so the
869/// striping and the reduction are the same restriction rather than two: the bit chunk's width is
870/// what makes the polynomial reduced. The leading coefficient, which may not be zero, is drawn from
871/// the same source with the zeros filtered out.
872///
873/// The lengths — the number of coefficients, which is one more than the degree, or zero for the
874/// zero polynomial — are sampled from a geometric distribution with mean `mean_length_numerator /
875/// mean_length_denominator`.
876///
877/// # Worst-case complexity per iteration
878/// $T(i) = O(\ell)$
879///
880/// $M(i) = O(\ell)$
881///
882/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, and $\ell$ is the
883/// number of coefficients of the $i$th output.
884///
885/// # Panics
886/// Panics if `pow` is zero or greater than 64, if `mean_stripe_denominator` is zero, if
887/// `mean_stripe_numerator < mean_stripe_denominator`, if `mean_length_numerator` or
888/// `mean_length_denominator` are zero, or if their ratio is greater than or equal to $2^{64}$.
889///
890/// # Examples
891/// ```
892/// use malachite_base::iterators::prefix_to_string;
893/// use malachite_base::random::EXAMPLE_SEED;
894/// use malachite_base::unsigned_polynomial::random::*;
895///
896/// assert_eq!(
897///     prefix_to_string(
898///         striped_random_unsigned_polynomials_reduced_mod_power_of_2::<u64>(
899///             EXAMPLE_SEED,
900///             8,
901///             8,
902///             1,
903///             2,
904///             1
905///         ),
906///         5
907///     ),
908///     "[248*x^5+7*x^4+31*x^3+248*x^2+220*x+255, 224, \
909///     111*x^7+112*x^4+255*x^3+255*x^2+x+3, 241, \
910///     124*x^13+159*x^12+127*x^11+239*x^10+63*x^9+252*x^8+216*x^7+135*x^6+32*x^5+3*x^4+255*x^3+\
911///     x^2, ...]"
912/// );
913/// ```
914#[inline]
915pub fn striped_random_unsigned_polynomials_reduced_mod_power_of_2<T: PrimitiveUnsigned>(
916    seed: Seed,
917    pow: u64,
918    mean_stripe_numerator: u64,
919    mean_stripe_denominator: u64,
920    mean_length_numerator: u64,
921    mean_length_denominator: u64,
922) -> StripedRandomUnsignedPolynomialsReducedModPowerOf2<T> {
923    assert_ne!(
924        pow, 0,
925        "the only polynomial reduced modulo 2^0 is the zero polynomial"
926    );
927    assert!(pow <= u64::WIDTH);
928    random_unsigned_polynomials_from_iterators(
929        seed,
930        &|seed_2| {
931            striped_random_unsigned_bit_chunks(
932                seed_2,
933                pow,
934                mean_stripe_numerator,
935                mean_stripe_denominator,
936            )
937        },
938        &|seed_2| {
939            nonzero_values(striped_random_unsigned_bit_chunks(
940                seed_2,
941                pow,
942                mean_stripe_numerator,
943                mean_stripe_denominator,
944            ))
945        },
946        mean_length_numerator,
947        mean_length_denominator,
948    )
949}
950
951/// The type of the [`UnsignedPolynomial`] generator whose coefficients are reduced modulo a number.
952pub type RandomUnsignedPolynomialsReducedMod<T> = RandomUnsignedPolynomials<
953    T,
954    GeometricRandomNaturalValues<u64>,
955    RandomUnsignedRange<T>,
956    RandomUnsignedRange<T>,
957>;
958
959/// Generates random [`UnsignedPolynomial`]s that are reduced modulo $m$.
960///
961/// A polynomial is reduced modulo $m$ when every one of its coefficients is, so the coefficients
962/// are sampled uniformly from $[0, m)$ and the leading coefficient, which may not be zero, from
963/// $[1, m)$.
964///
965/// The lengths — the number of coefficients, which is one more than the degree, or zero for the
966/// zero polynomial — are sampled from a geometric distribution with mean `mean_length_numerator /
967/// mean_length_denominator`.
968///
969/// Where $m$ is a power of 2, [`random_unsigned_polynomials_reduced_mod_power_of_2`] generates from
970/// the same set, though not the same sequence.
971///
972/// # Worst-case complexity per iteration
973/// $T(i) = O(\ell)$
974///
975/// $M(i) = O(\ell)$
976///
977/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, and $\ell$ is the
978/// number of coefficients of the $i$th output.
979///
980/// # Panics
981/// Panics if `m` is less than 2, if `mean_length_numerator` or `mean_length_denominator` are zero,
982/// or if their ratio is greater than or equal to $2^{64}$. Nothing is reduced modulo 0, and the
983/// only polynomial reduced modulo 1 is the zero polynomial, which leaves no leading coefficient to
984/// choose.
985///
986/// # Examples
987/// ```
988/// use malachite_base::iterators::prefix_to_string;
989/// use malachite_base::random::EXAMPLE_SEED;
990/// use malachite_base::unsigned_polynomial::random::*;
991///
992/// assert_eq!(
993///     prefix_to_string(
994///         random_unsigned_polynomials_reduced_mod::<u64>(EXAMPLE_SEED, 10, 2, 1),
995///         5
996///     ),
997///     "[3*x^5+8*x^4+8*x^3+5*x+5, 7, 9*x^7+x^6+9*x^5+2*x^4+6*x^3+8*x^2+6*x+8, 7, \
998///     9*x^13+5*x^12+9*x^11+7*x^10+8*x^9+9*x^7+6*x^6+5*x^5+x^4+6*x^3+2*x^2+2, ...]"
999/// );
1000/// ```
1001#[inline]
1002pub fn random_unsigned_polynomials_reduced_mod<T: PrimitiveUnsigned>(
1003    seed: Seed,
1004    m: T,
1005    mean_length_numerator: u64,
1006    mean_length_denominator: u64,
1007) -> RandomUnsignedPolynomialsReducedMod<T> {
1008    assert!(
1009        m >= T::TWO,
1010        "nothing is reduced modulo 0, and only the zero polynomial is reduced modulo 1"
1011    );
1012    random_unsigned_polynomials_from_iterators(
1013        seed,
1014        &|seed_2| random_unsigned_range(seed_2, T::ZERO, m),
1015        &|seed_2| random_unsigned_range(seed_2, T::ONE, m),
1016        mean_length_numerator,
1017        mean_length_denominator,
1018    )
1019}
1020
1021/// The type of the striped [`UnsignedPolynomial`] generator whose coefficients are reduced modulo a
1022/// number.
1023pub type StripedRandomUnsignedPolynomialsReducedMod<T> = RandomUnsignedPolynomials<
1024    T,
1025    GeometricRandomNaturalValues<u64>,
1026    StripedRandomUnsignedInclusiveRange<T>,
1027    StripedRandomUnsignedInclusiveRange<T>,
1028>;
1029
1030/// Generates random [`UnsignedPolynomial`]s that are reduced modulo $m$, with striped coefficients.
1031///
1032/// The coefficients are striped values in $[0, m)$, and the leading coefficient, which may not be
1033/// zero, is a striped value in $[1, m)$.
1034///
1035/// Unlike [`striped_random_unsigned_polynomials_reduced_mod_power_of_2`], where a striped bit chunk
1036/// of the right width is already a reduced coefficient, an arbitrary $m$ is not a bit-width
1037/// boundary, so the striping and the reduction are two restrictions rather than one. A striped
1038/// value in a range keeps the long runs of equal bits that the range allows, so the coefficients
1039/// just below $m$ are the ones whose bit patterns are least free.
1040///
1041/// The lengths — the number of coefficients, which is one more than the degree, or zero for the
1042/// zero polynomial — are sampled from a geometric distribution with mean `mean_length_numerator /
1043/// mean_length_denominator`.
1044///
1045/// # Worst-case complexity per iteration
1046/// $T(i) = O(\ell)$
1047///
1048/// $M(i) = O(\ell)$
1049///
1050/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, and $\ell$ is the
1051/// number of coefficients of the $i$th output.
1052///
1053/// # Panics
1054/// Panics if `m` is less than 2, if `mean_stripe_denominator` is zero, if `mean_stripe_numerator <
1055/// mean_stripe_denominator`, if `mean_length_numerator` or `mean_length_denominator` are zero, or
1056/// if their ratio is greater than or equal to $2^{64}$.
1057///
1058/// # Examples
1059/// ```
1060/// use malachite_base::iterators::prefix_to_string;
1061/// use malachite_base::random::EXAMPLE_SEED;
1062/// use malachite_base::unsigned_polynomial::random::*;
1063///
1064/// assert_eq!(
1065///     prefix_to_string(
1066///         striped_random_unsigned_polynomials_reduced_mod::<u64>(EXAMPLE_SEED, 1000, 8, 1, 2, 1),
1067///         5
1068///     ),
1069///     "[x^5+3*x^4+x^3+62*x^2+952*x+999, 1, x^7+511*x^3+7*x^2+999*x+7, 775, \
1070///     992*x^13+959*x^12+3*x^11+481*x^10+512*x^9+636*x^8+992*x^7+33*x^6+799*x^5+639*x^4+542*x^3+\
1071///     479*x^2+992*x+127, ...]"
1072/// );
1073/// ```
1074#[inline]
1075pub fn striped_random_unsigned_polynomials_reduced_mod<T: PrimitiveUnsigned>(
1076    seed: Seed,
1077    m: T,
1078    mean_stripe_numerator: u64,
1079    mean_stripe_denominator: u64,
1080    mean_length_numerator: u64,
1081    mean_length_denominator: u64,
1082) -> StripedRandomUnsignedPolynomialsReducedMod<T> {
1083    assert!(
1084        m >= T::TWO,
1085        "nothing is reduced modulo 0, and only the zero polynomial is reduced modulo 1"
1086    );
1087    random_unsigned_polynomials_from_iterators(
1088        seed,
1089        &|seed_2| {
1090            striped_random_unsigned_range(
1091                seed_2,
1092                T::ZERO,
1093                m,
1094                mean_stripe_numerator,
1095                mean_stripe_denominator,
1096            )
1097        },
1098        &|seed_2| {
1099            striped_random_unsigned_range(
1100                seed_2,
1101                T::ONE,
1102                m,
1103                mean_stripe_numerator,
1104                mean_stripe_denominator,
1105            )
1106        },
1107        mean_length_numerator,
1108        mean_length_denominator,
1109    )
1110}