malachite_nz/integer_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::integer::Integer;
10use crate::integer::random::{
11 RandomIntegers, StripedRandomIntegers, random_integers, random_nonzero_integers,
12 striped_random_integers, striped_random_nonzero_integers,
13};
14use crate::integer_polynomial::IntegerPolynomial;
15use malachite_base::num::random::RandomUnsignedInclusiveRange;
16use malachite_base::num::random::geometric::{
17 GeometricRandomNaturalValues, GeometricRandomNonzeroSigneds, GeometricRandomSigneds,
18};
19use malachite_base::polynomial::Polynomial;
20use malachite_base::random::Seed;
21use malachite_base::vecs::random::{
22 RandomFixedLengthVecsWithLast, RandomVecsWithLast, random_vecs_with_last,
23 random_vecs_with_last_fixed_length, random_vecs_with_last_length_inclusive_range,
24 random_vecs_with_last_min_length,
25};
26
27/// Generates random [`IntegerPolynomial`]s with coefficients from one iterator and leading
28/// coefficients from another.
29///
30/// This `struct` is created by [`random_integer_polynomials_from_iterators`] and the generators
31/// built on it; see their documentation for more.
32#[derive(Clone, Debug)]
33pub struct RandomIntegerPolynomials<
34 I: Iterator<Item = u64>,
35 J: Iterator<Item = Integer>,
36 K: Iterator<Item = Integer>,
37>(RandomVecsWithLast<Integer, I, J, K>);
38
39impl<I: Iterator<Item = u64>, J: Iterator<Item = Integer>, K: Iterator<Item = Integer>> Iterator
40 for RandomIntegerPolynomials<I, J, K>
41{
42 type Item = IntegerPolynomial;
43
44 #[inline]
45 fn next(&mut self) -> Option<IntegerPolynomial> {
46 self.0.next().map(IntegerPolynomial::from_coefficients_asc)
47 }
48}
49
50/// The type of the [`IntegerPolynomial`] generators that draw their coefficients from every
51/// [`Integer`] and their leading coefficients from every nonzero one, with lengths from a geometric
52/// distribution.
53pub type RandomIntegerPolynomialsFromIntegers = RandomIntegerPolynomials<
54 GeometricRandomNaturalValues<u64>,
55 RandomPolynomialCoefficients,
56 RandomPolynomialLeadingCoefficients,
57>;
58
59/// Generates random [`IntegerPolynomial`]s whose coefficients come from one iterator and whose
60/// leading coefficients come from another.
61///
62/// A polynomial is its coefficients, and the only thing that distinguishes them from any other list
63/// of [`Integer`]s is that the last of them may not be zero. Singling out that one coefficient is
64/// therefore all it takes: `xs_gen` supplies every coefficient below the leading one, and `ys_gen`
65/// supplies the leading one.
66///
67/// `ys_gen` should produce no zeros, since a polynomial's leading coefficient is never zero. If it
68/// does, the zeros are trimmed away, and the polynomial has a lower degree than its length
69/// suggests.
70///
71/// The lengths of the polynomials — the number of coefficients, which is one more than the
72/// degree, or zero for the zero polynomial — are sampled from a geometric distribution with a
73/// specified mean $m$, equal to `mean_length_numerator / mean_length_denominator`. $m$ must be
74/// greater than 0.
75///
76/// The iterators produced by `xs_gen` and `ys_gen` must be infinite.
77///
78/// # Worst-case complexity per iteration
79/// $T(i) = O(\ell T^\prime(i))$
80///
81/// $M(i) = O(\ell M^\prime(i))$
82///
83/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $T^\prime$ and
84/// $M^\prime$ are the time and memory functions of the iterators produced by `xs_gen` and `ys_gen`,
85/// and $\ell$ is the number of coefficients of the $i$th output.
86///
87/// # Panics
88/// Panics if `mean_length_numerator` or `mean_length_denominator` are zero, or if their ratio is
89/// greater than or equal to $2^{64}$.
90///
91/// # Examples
92/// ```
93/// use malachite_base::iterators::prefix_to_string;
94/// use malachite_base::random::EXAMPLE_SEED;
95/// use malachite_nz::integer::random::{random_integers, random_nonzero_integers};
96/// use malachite_nz::integer_polynomial::random::random_integer_polynomials_from_iterators;
97///
98/// assert_eq!(
99/// prefix_to_string(
100/// random_integer_polynomials_from_iterators(
101/// EXAMPLE_SEED,
102/// &|seed| random_integers(seed, 4, 1),
103/// &|seed| random_nonzero_integers(seed, 4, 1),
104/// 1,
105/// 1,
106/// ),
107/// 5
108/// ),
109/// "[14, -2*x-497, 2*x-1, 122*x+1, 1, ...]"
110/// );
111/// ```
112#[inline]
113pub fn random_integer_polynomials_from_iterators<
114 J: Iterator<Item = Integer>,
115 K: Iterator<Item = Integer>,
116>(
117 seed: Seed,
118 xs_gen: &dyn Fn(Seed) -> J,
119 ys_gen: &dyn Fn(Seed) -> K,
120 mean_length_numerator: u64,
121 mean_length_denominator: u64,
122) -> RandomIntegerPolynomials<GeometricRandomNaturalValues<u64>, J, K> {
123 RandomIntegerPolynomials(random_vecs_with_last(
124 seed,
125 xs_gen,
126 ys_gen,
127 mean_length_numerator,
128 mean_length_denominator,
129 ))
130}
131
132/// Generates random [`IntegerPolynomial`]s.
133///
134/// The coefficients are sampled from [`random_integers`] and the leading coefficient from
135/// [`random_nonzero_integers`], both with a mean bit count of `mean_bits_numerator /
136/// mean_bits_denominator`.
137///
138/// The lengths — the number of coefficients, which is one more than the degree, or zero for the
139/// zero polynomial — are sampled from a geometric distribution with mean `mean_length_numerator /
140/// mean_length_denominator`, so the zero polynomial is generated with the probability that that
141/// distribution gives to 0.
142///
143/// # Worst-case complexity per iteration
144/// $T(i) = O(\ell b)$
145///
146/// $M(i) = O(\ell b)$
147///
148/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $\ell$ is the number
149/// of coefficients of the $i$th output, and $b$ is `mean_bits_numerator / mean_bits_denominator`.
150///
151/// # Panics
152/// Panics if `mean_bits_numerator` or `mean_bits_denominator` are zero, if their ratio is less than
153/// or equal to 1, or if `mean_length_numerator` or `mean_length_denominator` are zero or their
154/// ratio is greater than or equal to $2^{64}$.
155///
156/// # Examples
157/// ```
158/// use malachite_base::iterators::prefix_to_string;
159/// use malachite_base::random::EXAMPLE_SEED;
160/// use malachite_nz::integer_polynomial::random::random_integer_polynomials;
161///
162/// assert_eq!(
163/// prefix_to_string(random_integer_polynomials(EXAMPLE_SEED, 4, 1, 1, 1), 5),
164/// "[14, -2*x-497, 2*x-1, 122*x+1, 1, ...]"
165/// );
166/// ```
167#[inline]
168pub fn random_integer_polynomials(
169 seed: Seed,
170 mean_bits_numerator: u64,
171 mean_bits_denominator: u64,
172 mean_length_numerator: u64,
173 mean_length_denominator: u64,
174) -> RandomIntegerPolynomialsFromIntegers {
175 random_integer_polynomials_from_iterators(
176 seed,
177 &|seed_2| random_integers(seed_2, mean_bits_numerator, mean_bits_denominator),
178 &|seed_2| random_nonzero_integers(seed_2, mean_bits_numerator, mean_bits_denominator),
179 mean_length_numerator,
180 mean_length_denominator,
181 )
182}
183
184/// Generates random [`IntegerPolynomial`]s of a given degree, with coefficients from one iterator
185/// and leading coefficients from another.
186///
187/// This `struct` is created by [`random_integer_polynomials_with_degree`] and
188/// [`striped_random_integer_polynomials_with_degree`]; see their documentation for more.
189#[derive(Clone, Debug)]
190pub struct RandomIntegerPolynomialsWithDegree<
191 J: Iterator<Item = Integer>,
192 K: Iterator<Item = Integer>,
193>(RandomFixedLengthVecsWithLast<Integer, J, K>);
194
195impl<J: Iterator<Item = Integer>, K: Iterator<Item = Integer>> Iterator
196 for RandomIntegerPolynomialsWithDegree<J, K>
197{
198 type Item = IntegerPolynomial;
199
200 #[inline]
201 fn next(&mut self) -> Option<IntegerPolynomial> {
202 self.0.next().map(IntegerPolynomial::from_coefficients_asc)
203 }
204}
205
206/// The coefficients that the unstriped [`IntegerPolynomial`] generators draw on.
207pub type RandomPolynomialCoefficients = RandomIntegers<GeometricRandomSigneds<i64>>;
208
209/// The leading coefficients that the unstriped [`IntegerPolynomial`] generators draw on: a
210/// polynomial's leading coefficient is never zero.
211pub type RandomPolynomialLeadingCoefficients = RandomIntegers<GeometricRandomNonzeroSigneds<i64>>;
212
213/// The coefficients that the striped [`IntegerPolynomial`] generators draw on.
214pub type StripedRandomPolynomialCoefficients = StripedRandomIntegers<GeometricRandomSigneds<i64>>;
215
216/// The leading coefficients that the striped [`IntegerPolynomial`] generators draw on.
217pub type StripedRandomPolynomialLeadingCoefficients =
218 StripedRandomIntegers<GeometricRandomNonzeroSigneds<i64>>;
219
220/// The type of the [`IntegerPolynomial`] generators whose degrees are uniform over a range.
221pub type RandomIntegerPolynomialsInDegreeRange = RandomIntegerPolynomials<
222 RandomUnsignedInclusiveRange<u64>,
223 RandomPolynomialCoefficients,
224 RandomPolynomialLeadingCoefficients,
225>;
226
227/// The type of the striped [`IntegerPolynomial`] generators with geometrically distributed lengths.
228pub type StripedRandomIntegerPolynomialsFromIntegers = RandomIntegerPolynomials<
229 GeometricRandomNaturalValues<u64>,
230 StripedRandomPolynomialCoefficients,
231 StripedRandomPolynomialLeadingCoefficients,
232>;
233
234/// The type of the striped [`IntegerPolynomial`] generators whose degrees are uniform over a range.
235pub type StripedRandomIntegerPolynomialsInDegreeRange = RandomIntegerPolynomials<
236 RandomUnsignedInclusiveRange<u64>,
237 StripedRandomPolynomialCoefficients,
238 StripedRandomPolynomialLeadingCoefficients,
239>;
240
241/// Generates random [`IntegerPolynomial`]s of a given degree.
242///
243/// A polynomial of degree $d$ has $d+1$ coefficients, of which the leading one is nonzero. The zero
244/// polynomial is never generated: it has no degree at all, so no degree is the one it has.
245///
246/// The coefficients are sampled from [`random_integers`] and the leading coefficient from
247/// [`random_nonzero_integers`], both with a mean bit count of `mean_bits_numerator /
248/// mean_bits_denominator`.
249///
250/// # Worst-case complexity per iteration
251/// $T(i) = O(db)$
252///
253/// $M(i) = O(db)$
254///
255/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $d$ is `degree`, and
256/// $b$ is `mean_bits_numerator / mean_bits_denominator`.
257///
258/// # Panics
259/// Panics if `mean_bits_numerator` or `mean_bits_denominator` are zero, or if their ratio is less
260/// than or equal to 1.
261///
262/// # Examples
263/// ```
264/// use malachite_base::iterators::prefix_to_string;
265/// use malachite_base::random::EXAMPLE_SEED;
266/// use malachite_nz::integer_polynomial::random::random_integer_polynomials_with_degree;
267///
268/// assert_eq!(
269/// prefix_to_string(
270/// random_integer_polynomials_with_degree(EXAMPLE_SEED, 2, 4, 1),
271/// 5
272/// ),
273/// "[14*x^2-x-497, -2*x^2+19*x+1, 2*x^2+799*x+799, 122*x^2+66*x-1, x^2+334*x-10721, ...]"
274/// );
275/// ```
276#[inline]
277pub fn random_integer_polynomials_with_degree(
278 seed: Seed,
279 degree: u64,
280 mean_bits_numerator: u64,
281 mean_bits_denominator: u64,
282) -> RandomIntegerPolynomialsWithDegree<
283 RandomPolynomialCoefficients,
284 RandomPolynomialLeadingCoefficients,
285> {
286 RandomIntegerPolynomialsWithDegree(random_vecs_with_last_fixed_length(
287 degree.saturating_add(1),
288 random_integers(seed.fork("xs"), mean_bits_numerator, mean_bits_denominator),
289 random_nonzero_integers(seed.fork("ys"), mean_bits_numerator, mean_bits_denominator),
290 ))
291}
292
293/// Generates random [`IntegerPolynomial`]s with a minimum degree.
294///
295/// The zero polynomial is never generated: it has no degree at all, so it is not of any degree at
296/// least `min_degree`.
297///
298/// The coefficients are sampled from [`random_integers`] and the leading coefficient from
299/// [`random_nonzero_integers`], both with a mean bit count of `mean_bits_numerator /
300/// mean_bits_denominator`. The lengths — the number of coefficients, which is one more than the
301/// degree — are sampled from a geometric distribution with mean `mean_length_numerator /
302/// mean_length_denominator`, which must be greater than `min_degree + 1`.
303///
304/// # Worst-case complexity per iteration
305/// $T(i) = O(\ell b)$
306///
307/// $M(i) = O(\ell b)$
308///
309/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $\ell$ is the number
310/// of coefficients of the $i$th output, and $b$ is `mean_bits_numerator / mean_bits_denominator`.
311///
312/// # Panics
313/// Panics if `mean_bits_numerator` or `mean_bits_denominator` are zero, if their ratio is less than
314/// or equal to 1, or if `mean_length_numerator / mean_length_denominator` is less than or equal to
315/// `min_degree + 1`.
316///
317/// # Examples
318/// ```
319/// use malachite_base::iterators::prefix_to_string;
320/// use malachite_base::random::EXAMPLE_SEED;
321/// use malachite_nz::integer_polynomial::random::random_integer_polynomials_min_degree;
322///
323/// assert_eq!(
324/// prefix_to_string(
325/// random_integer_polynomials_min_degree(EXAMPLE_SEED, 1, 4, 1, 3, 1),
326/// 5
327/// ),
328/// "[14*x^2-x-497, -2*x^3+799*x^2+19*x+1, 2*x^3+66*x^2-x+799, 122*x^3+59*x^2+334*x-10721, \
329/// x^2-5*x-119, ...]"
330/// );
331/// ```
332#[inline]
333pub fn random_integer_polynomials_min_degree(
334 seed: Seed,
335 min_degree: u64,
336 mean_bits_numerator: u64,
337 mean_bits_denominator: u64,
338 mean_length_numerator: u64,
339 mean_length_denominator: u64,
340) -> RandomIntegerPolynomialsFromIntegers {
341 RandomIntegerPolynomials(random_vecs_with_last_min_length(
342 seed,
343 min_degree.saturating_add(1),
344 &|seed_2| random_integers(seed_2, mean_bits_numerator, mean_bits_denominator),
345 &|seed_2| random_nonzero_integers(seed_2, mean_bits_numerator, mean_bits_denominator),
346 mean_length_numerator,
347 mean_length_denominator,
348 ))
349}
350
351/// Generates random [`IntegerPolynomial`]s with degrees in $[a, b)$.
352///
353/// The degrees are sampled from a uniform distribution on $[a, b)$. The zero polynomial is never
354/// generated: it has no degree at all, so its degree is in no range.
355///
356/// The coefficients are sampled from [`random_integers`] and the leading coefficient from
357/// [`random_nonzero_integers`], both with a mean bit count of `mean_bits_numerator /
358/// mean_bits_denominator`.
359///
360/// # Worst-case complexity per iteration
361/// $T(i) = O(bd)$
362///
363/// $M(i) = O(bd)$
364///
365/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $d$ is $b$, and $b$ is
366/// `mean_bits_numerator / mean_bits_denominator`.
367///
368/// # Panics
369/// Panics if $a \geq b$, if `mean_bits_numerator` or `mean_bits_denominator` are zero, or if their
370/// ratio is less than or equal to 1.
371///
372/// # Examples
373/// ```
374/// use malachite_base::iterators::prefix_to_string;
375/// use malachite_base::random::EXAMPLE_SEED;
376/// use malachite_nz::integer_polynomial::random::random_integer_polynomials_degree_range;
377///
378/// assert_eq!(
379/// prefix_to_string(
380/// random_integer_polynomials_degree_range(EXAMPLE_SEED, 1, 3, 4, 1),
381/// 5
382/// ),
383/// "[14*x^2-x-497, -2*x+1, 2*x^2+799*x+19, 122*x^2-x+799, x+66, ...]"
384/// );
385/// ```
386#[inline]
387pub fn random_integer_polynomials_degree_range(
388 seed: Seed,
389 a: u64,
390 b: u64,
391 mean_bits_numerator: u64,
392 mean_bits_denominator: u64,
393) -> RandomIntegerPolynomialsInDegreeRange {
394 assert!(a < b, "the degree range [{a}, {b}) is empty");
395 random_integer_polynomials_degree_inclusive_range(
396 seed,
397 a,
398 b - 1,
399 mean_bits_numerator,
400 mean_bits_denominator,
401 )
402}
403
404/// Generates random [`IntegerPolynomial`]s with degrees in $[a, b]$.
405///
406/// The degrees are sampled from a uniform distribution on $[a, b]$. The zero polynomial is never
407/// generated: it has no degree at all, so its degree is in no range.
408///
409/// The coefficients are sampled from [`random_integers`] and the leading coefficient from
410/// [`random_nonzero_integers`], both with a mean bit count of `mean_bits_numerator /
411/// mean_bits_denominator`.
412///
413/// # Worst-case complexity per iteration
414/// $T(i) = O(b^\prime b)$
415///
416/// $M(i) = O(b^\prime b)$
417///
418/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $b^\prime$ is the
419/// largest degree, and $b$ is `mean_bits_numerator / mean_bits_denominator`.
420///
421/// # Panics
422/// Panics if $a > b$, if `mean_bits_numerator` or `mean_bits_denominator` are zero, or if their
423/// ratio is less than or equal to 1.
424///
425/// # Examples
426/// ```
427/// use malachite_base::iterators::prefix_to_string;
428/// use malachite_base::random::EXAMPLE_SEED;
429/// use malachite_nz::integer_polynomial::random::*;
430///
431/// assert_eq!(
432/// prefix_to_string(
433/// random_integer_polynomials_degree_inclusive_range(EXAMPLE_SEED, 1, 2, 4, 1),
434/// 5
435/// ),
436/// "[14*x^2-x-497, -2*x+1, 2*x^2+799*x+19, 122*x^2-x+799, x+66, ...]"
437/// );
438/// ```
439#[inline]
440pub fn random_integer_polynomials_degree_inclusive_range(
441 seed: Seed,
442 a: u64,
443 b: u64,
444 mean_bits_numerator: u64,
445 mean_bits_denominator: u64,
446) -> RandomIntegerPolynomialsInDegreeRange {
447 assert!(a <= b, "the degree range [{a}, {b}] is empty");
448 RandomIntegerPolynomials(random_vecs_with_last_length_inclusive_range(
449 seed,
450 a.saturating_add(1),
451 b.saturating_add(1),
452 &|seed_2| random_integers(seed_2, mean_bits_numerator, mean_bits_denominator),
453 &|seed_2| random_nonzero_integers(seed_2, mean_bits_numerator, mean_bits_denominator),
454 ))
455}
456
457/// Generates random [`IntegerPolynomial`]s with striped coefficients.
458///
459/// The coefficients are sampled from [`striped_random_integers`] and the leading coefficient from
460/// [`striped_random_nonzero_integers`], with a mean run length of `mean_stripe_numerator /
461/// mean_stripe_denominator` and a mean bit count of `mean_bits_numerator / mean_bits_denominator`.
462/// A striped coefficient is one whose bits come in long runs, which is what makes the carries and
463/// borrows of an arithmetic test interesting.
464///
465/// The lengths — the number of coefficients, which is one more than the degree, or zero for the
466/// zero polynomial — are sampled from a geometric distribution with mean `mean_length_numerator /
467/// mean_length_denominator`, so the zero polynomial is generated with the probability that that
468/// distribution gives to 0.
469///
470/// # Worst-case complexity per iteration
471/// $T(i) = O(\ell b)$
472///
473/// $M(i) = O(\ell b)$
474///
475/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $\ell$ is the number
476/// of coefficients of the $i$th output, and $b$ is `mean_bits_numerator / mean_bits_denominator`.
477///
478/// # Panics
479/// Panics if `mean_stripe_denominator` is zero, if `mean_stripe_numerator <
480/// mean_stripe_denominator`, if `mean_bits_numerator` or `mean_bits_denominator` are zero, if their
481/// ratio is less than or equal to 1, or if `mean_length_numerator` or `mean_length_denominator` are
482/// zero or their ratio is greater than or equal to $2^{64}$.
483///
484/// # Examples
485/// ```
486/// use malachite_base::iterators::prefix_to_string;
487/// use malachite_base::random::EXAMPLE_SEED;
488/// use malachite_nz::integer_polynomial::random::striped_random_integer_polynomials;
489///
490/// assert_eq!(
491/// prefix_to_string(
492/// striped_random_integer_polynomials(EXAMPLE_SEED, 16, 1, 4, 1, 1, 1),
493/// 5
494/// ),
495/// "[15, -2*x-496, 2*x-1, 65*x+1, 1, ...]"
496/// );
497/// ```
498#[inline]
499pub fn striped_random_integer_polynomials(
500 seed: Seed,
501 mean_stripe_numerator: u64,
502 mean_stripe_denominator: u64,
503 mean_bits_numerator: u64,
504 mean_bits_denominator: u64,
505 mean_length_numerator: u64,
506 mean_length_denominator: u64,
507) -> StripedRandomIntegerPolynomialsFromIntegers {
508 random_integer_polynomials_from_iterators(
509 seed,
510 &|seed_2| {
511 striped_random_integers(
512 seed_2,
513 mean_stripe_numerator,
514 mean_stripe_denominator,
515 mean_bits_numerator,
516 mean_bits_denominator,
517 )
518 },
519 &|seed_2| {
520 striped_random_nonzero_integers(
521 seed_2,
522 mean_stripe_numerator,
523 mean_stripe_denominator,
524 mean_bits_numerator,
525 mean_bits_denominator,
526 )
527 },
528 mean_length_numerator,
529 mean_length_denominator,
530 )
531}
532
533/// Generates random [`IntegerPolynomial`]s of a given degree, with striped coefficients.
534///
535/// A polynomial of degree $d$ has $d+1$ coefficients, of which the leading one is nonzero. The zero
536/// polynomial is never generated: it has no degree at all, so no degree is the one it has.
537///
538/// The coefficients are striped, as they are in [`striped_random_integer_polynomials`].
539///
540/// # Worst-case complexity per iteration
541/// $T(i) = O(db)$
542///
543/// $M(i) = O(db)$
544///
545/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $d$ is `degree`, and
546/// $b$ is `mean_bits_numerator / mean_bits_denominator`.
547///
548/// # Panics
549/// Panics if `mean_stripe_denominator` is zero, if `mean_stripe_numerator <
550/// mean_stripe_denominator`, if `mean_bits_numerator` or `mean_bits_denominator` are zero, or if
551/// their ratio is less than or equal to 1.
552///
553/// # Examples
554/// ```
555/// use malachite_base::iterators::prefix_to_string;
556/// use malachite_base::random::EXAMPLE_SEED;
557/// use malachite_nz::integer_polynomial::random::*;
558///
559/// assert_eq!(
560/// prefix_to_string(
561/// striped_random_integer_polynomials_with_degree(EXAMPLE_SEED, 2, 16, 1, 4, 1),
562/// 5
563/// ),
564/// "[15*x^2-x-496, -2*x^2+16*x+1, 2*x^2+543*x+512, 65*x^2+127*x-1, x^2+383*x-10239, ...]"
565/// );
566/// ```
567#[inline]
568pub fn striped_random_integer_polynomials_with_degree(
569 seed: Seed,
570 degree: u64,
571 mean_stripe_numerator: u64,
572 mean_stripe_denominator: u64,
573 mean_bits_numerator: u64,
574 mean_bits_denominator: u64,
575) -> RandomIntegerPolynomialsWithDegree<
576 StripedRandomPolynomialCoefficients,
577 StripedRandomPolynomialLeadingCoefficients,
578> {
579 RandomIntegerPolynomialsWithDegree(random_vecs_with_last_fixed_length(
580 degree.saturating_add(1),
581 striped_random_integers(
582 seed.fork("xs"),
583 mean_stripe_numerator,
584 mean_stripe_denominator,
585 mean_bits_numerator,
586 mean_bits_denominator,
587 ),
588 striped_random_nonzero_integers(
589 seed.fork("ys"),
590 mean_stripe_numerator,
591 mean_stripe_denominator,
592 mean_bits_numerator,
593 mean_bits_denominator,
594 ),
595 ))
596}
597
598/// Generates random [`IntegerPolynomial`]s with a minimum degree and striped coefficients.
599///
600/// The zero polynomial is never generated: it has no degree at all, so it is not of any degree at
601/// least `min_degree`.
602///
603/// The coefficients are striped, as they are in [`striped_random_integer_polynomials`]. The lengths
604/// — one more than the degree — are sampled from a geometric distribution with mean
605/// `mean_length_numerator / mean_length_denominator`, which must be greater than `min_degree + 1`.
606///
607/// # Worst-case complexity per iteration
608/// $T(i) = O(\ell b)$
609///
610/// $M(i) = O(\ell b)$
611///
612/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $\ell$ is the number
613/// of coefficients of the $i$th output, and $b$ is `mean_bits_numerator / mean_bits_denominator`.
614///
615/// # Panics
616/// Panics if `mean_stripe_denominator` is zero, if `mean_stripe_numerator <
617/// mean_stripe_denominator`, if `mean_bits_numerator` or `mean_bits_denominator` are zero, if their
618/// ratio is less than or equal to 1, or if `mean_length_numerator / mean_length_denominator` is
619/// less than or equal to `min_degree + 1`.
620///
621/// # Examples
622/// ```
623/// use malachite_base::iterators::prefix_to_string;
624/// use malachite_base::random::EXAMPLE_SEED;
625/// use malachite_nz::integer_polynomial::random::*;
626///
627/// assert_eq!(
628/// prefix_to_string(
629/// striped_random_integer_polynomials_min_degree(EXAMPLE_SEED, 1, 16, 1, 4, 1, 3, 1),
630/// 5
631/// ),
632/// "[15*x^2-x-496, -2*x^3+512*x^2+16*x+1, 2*x^3+127*x^2-x+543, 65*x^3+36*x^2+383*x-10239, \
633/// x^2-4*x-127, ...]"
634/// );
635/// ```
636#[inline]
637pub fn striped_random_integer_polynomials_min_degree(
638 seed: Seed,
639 min_degree: u64,
640 mean_stripe_numerator: u64,
641 mean_stripe_denominator: u64,
642 mean_bits_numerator: u64,
643 mean_bits_denominator: u64,
644 mean_length_numerator: u64,
645 mean_length_denominator: u64,
646) -> StripedRandomIntegerPolynomialsFromIntegers {
647 RandomIntegerPolynomials(random_vecs_with_last_min_length(
648 seed,
649 min_degree.saturating_add(1),
650 &|seed_2| {
651 striped_random_integers(
652 seed_2,
653 mean_stripe_numerator,
654 mean_stripe_denominator,
655 mean_bits_numerator,
656 mean_bits_denominator,
657 )
658 },
659 &|seed_2| {
660 striped_random_nonzero_integers(
661 seed_2,
662 mean_stripe_numerator,
663 mean_stripe_denominator,
664 mean_bits_numerator,
665 mean_bits_denominator,
666 )
667 },
668 mean_length_numerator,
669 mean_length_denominator,
670 ))
671}
672
673/// Generates random [`IntegerPolynomial`]s with degrees in $[a, b)$ and striped coefficients.
674///
675/// The degrees are sampled from a uniform distribution on $[a, b)$. The zero polynomial is never
676/// generated: it has no degree at all, so its degree is in no range.
677///
678/// The coefficients are striped, as they are in [`striped_random_integer_polynomials`].
679///
680/// # Worst-case complexity per iteration
681/// $T(i) = O(bd)$
682///
683/// $M(i) = O(bd)$
684///
685/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $d$ is $b$, and $b$ is
686/// `mean_bits_numerator / mean_bits_denominator`.
687///
688/// # Panics
689/// Panics if $a \geq b$, if `mean_stripe_denominator` is zero, if `mean_stripe_numerator <
690/// mean_stripe_denominator`, if `mean_bits_numerator` or `mean_bits_denominator` are zero, or if
691/// their ratio is less than or equal to 1.
692///
693/// # Examples
694/// ```
695/// use malachite_base::iterators::prefix_to_string;
696/// use malachite_base::random::EXAMPLE_SEED;
697/// use malachite_nz::integer_polynomial::random::*;
698///
699/// assert_eq!(
700/// prefix_to_string(
701/// striped_random_integer_polynomials_degree_range(EXAMPLE_SEED, 1, 3, 16, 1, 4, 1),
702/// 5
703/// ),
704/// "[15*x^2-x-496, -2*x+1, 2*x^2+512*x+16, 65*x^2-x+543, x+127, ...]"
705/// );
706/// ```
707#[inline]
708pub fn striped_random_integer_polynomials_degree_range(
709 seed: Seed,
710 a: u64,
711 b: u64,
712 mean_stripe_numerator: u64,
713 mean_stripe_denominator: u64,
714 mean_bits_numerator: u64,
715 mean_bits_denominator: u64,
716) -> StripedRandomIntegerPolynomialsInDegreeRange {
717 assert!(a < b, "the degree range [{a}, {b}) is empty");
718 striped_random_integer_polynomials_degree_inclusive_range(
719 seed,
720 a,
721 b - 1,
722 mean_stripe_numerator,
723 mean_stripe_denominator,
724 mean_bits_numerator,
725 mean_bits_denominator,
726 )
727}
728
729/// Generates random [`IntegerPolynomial`]s with degrees in $[a, b]$ and striped coefficients.
730///
731/// The degrees are sampled from a uniform distribution on $[a, b]$. The zero polynomial is never
732/// generated: it has no degree at all, so its degree is in no range.
733///
734/// The coefficients are striped, as they are in [`striped_random_integer_polynomials`].
735///
736/// # Worst-case complexity per iteration
737/// $T(i) = O(b^\prime b)$
738///
739/// $M(i) = O(b^\prime b)$
740///
741/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $b^\prime$ is the
742/// largest degree, and $b$ is `mean_bits_numerator / mean_bits_denominator`.
743///
744/// # Panics
745/// Panics if $a > b$, if `mean_stripe_denominator` is zero, if `mean_stripe_numerator <
746/// mean_stripe_denominator`, if `mean_bits_numerator` or `mean_bits_denominator` are zero, or if
747/// their ratio is less than or equal to 1.
748///
749/// # Examples
750/// ```
751/// use malachite_base::iterators::prefix_to_string;
752/// use malachite_base::random::EXAMPLE_SEED;
753/// use malachite_nz::integer_polynomial::random::*;
754///
755/// assert_eq!(
756/// prefix_to_string(
757/// striped_random_integer_polynomials_degree_inclusive_range(
758/// EXAMPLE_SEED,
759/// 1,
760/// 2,
761/// 16,
762/// 1,
763/// 4,
764/// 1
765/// ),
766/// 5
767/// ),
768/// "[15*x^2-x-496, -2*x+1, 2*x^2+512*x+16, 65*x^2-x+543, x+127, ...]"
769/// );
770/// ```
771#[inline]
772pub fn striped_random_integer_polynomials_degree_inclusive_range(
773 seed: Seed,
774 a: u64,
775 b: u64,
776 mean_stripe_numerator: u64,
777 mean_stripe_denominator: u64,
778 mean_bits_numerator: u64,
779 mean_bits_denominator: u64,
780) -> StripedRandomIntegerPolynomialsInDegreeRange {
781 assert!(a <= b, "the degree range [{a}, {b}] is empty");
782 RandomIntegerPolynomials(random_vecs_with_last_length_inclusive_range(
783 seed,
784 a.saturating_add(1),
785 b.saturating_add(1),
786 &|seed_2| {
787 striped_random_integers(
788 seed_2,
789 mean_stripe_numerator,
790 mean_stripe_denominator,
791 mean_bits_numerator,
792 mean_bits_denominator,
793 )
794 },
795 &|seed_2| {
796 striped_random_nonzero_integers(
797 seed_2,
798 mean_stripe_numerator,
799 mean_stripe_denominator,
800 mean_bits_numerator,
801 mean_bits_denominator,
802 )
803 },
804 ))
805}