malachite_q/exhaustive/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::Rational;
10use crate::arithmetic::denominators_in_closed_interval::DenominatorsInClosedRationalInterval;
11use crate::arithmetic::traits::DenominatorsInClosedInterval;
12use core::iter::{Chain, Once, once};
13use core::mem::swap;
14use malachite_base::num::arithmetic::traits::{CoprimeWith, UnsignedAbs};
15use malachite_base::num::basic::traits::{One, Zero};
16use malachite_base::num::conversion::traits::RoundingFrom;
17use malachite_base::num::iterators::{RulerSequence, ruler_sequence};
18use malachite_base::rounding_modes::RoundingMode::*;
19use malachite_base::tuples::exhaustive::{
20 ExhaustiveDependentPairs, ExhaustiveDependentPairsYsGenerator, exhaustive_dependent_pairs,
21};
22use malachite_nz::integer::Integer;
23use malachite_nz::integer::exhaustive::{
24 ExhaustiveIntegerRange, ExhaustiveIntegerRangeToInfinity,
25 ExhaustiveIntegerRangeToNegativeInfinity, exhaustive_integer_range,
26 exhaustive_integer_range_to_infinity, exhaustive_integer_range_to_negative_infinity,
27};
28use malachite_nz::natural::Natural;
29use malachite_nz::natural::exhaustive::{
30 ExhaustiveNaturalRangeToInfinity, exhaustive_positive_naturals,
31};
32
33/// Generates all positive [`Rational`]s.
34///
35/// This `struct` is created by [`exhaustive_positive_rationals`]; see its documentation for more.
36#[derive(Clone, Debug)]
37pub struct ExhaustivePositiveRationals {
38 pred_pred: Natural,
39 pred: Natural,
40}
41
42impl Iterator for ExhaustivePositiveRationals {
43 type Item = Rational;
44
45 fn next(&mut self) -> Option<Rational> {
46 let mut anm1 = Natural::ZERO;
47 swap(&mut self.pred_pred, &mut anm1);
48 swap(&mut self.pred, &mut self.pred_pred);
49 let k = &anm1 / &self.pred_pred; // floor(a(n - 1) / a(n))
50 self.pred = ((k << 1u32) | Natural::ONE) * &self.pred_pred - anm1;
51 Some(Rational {
52 sign: true,
53 numerator: self.pred_pred.clone(),
54 denominator: self.pred.clone(),
55 })
56 }
57}
58
59/// Generates all positive [`Rational`]s.
60///
61/// The [`Rational`]s are ordered as in the [Calkin-Wilf
62/// sequence](https://en.wikipedia.org/wiki/Calkin%E2%80%93Wilf_tree#Breadth_first_traversal). Their
63/// numerators and denominators are given by the [Stern-Brocot
64/// sequence](https://en.wikipedia.org/wiki/Stern%E2%80%93Brocot_tree#Relation_to_Farey_sequences).
65/// To generate the latter sequence, this iterator uses the formula
66/// $$
67/// a_{n+1} = \left ( 2 \left \lfloor \frac{a_{n-1}}{a_n} \right \rfloor +1 \right ) a_n - a_{n-1},
68/// $$
69/// attributed to David S. Newman at <https://oeis.org/A002487>.
70///
71/// The output length is infinite. The numerators and denominators of the $n$th element are
72/// $O(n^\frac{\log \phi}{\log 2})$.
73///
74/// # Worst-case complexity per iteration
75/// $T(i) = O(\log i \log\log i \log\log\log i)$
76///
77/// $M(i) = O(\log i \log\log i)$
78///
79/// where $T$ is time, $M$ is additional memory, and $n$ is the iteration number.
80///
81/// # Examples
82/// ```
83/// use malachite_base::iterators::prefix_to_string;
84/// use malachite_q::exhaustive::exhaustive_positive_rationals;
85///
86/// assert_eq!(
87/// prefix_to_string(exhaustive_positive_rationals(), 20),
88/// "[1, 1/2, 2, 1/3, 3/2, 2/3, 3, 1/4, 4/3, 3/5, 5/2, 2/5, 5/3, 3/4, 4, 1/5, 5/4, 4/7, 7/3, \
89/// 3/8, ...]"
90/// )
91/// ```
92pub const fn exhaustive_positive_rationals() -> ExhaustivePositiveRationals {
93 ExhaustivePositiveRationals {
94 pred_pred: Natural::ZERO,
95 pred: Natural::ONE,
96 }
97}
98
99/// Generates all non-positive [`Rational`]s.
100///
101/// Zero is generated first, followed by all the positive [`Rational`]s. See
102/// [`exhaustive_positive_rationals`] for details.
103///
104/// The output length is infinite. The numerators and denominators of the $n$th element are
105/// $O(n^\frac{\log \phi}{\log 2})$.
106///
107/// # Worst-case complexity per iteration
108/// $T(i) = O(\log i \log\log i \log\log\log i)$
109///
110/// $M(i) = O(\log i \log\log i)$
111///
112/// where $T$ is time, $M$ is additional memory, and $n$ is the iteration number.
113///
114/// # Examples
115/// ```
116/// use malachite_base::iterators::prefix_to_string;
117/// use malachite_q::exhaustive::exhaustive_non_negative_rationals;
118///
119/// assert_eq!(
120/// prefix_to_string(exhaustive_non_negative_rationals(), 20),
121/// "[0, 1, 1/2, 2, 1/3, 3/2, 2/3, 3, 1/4, 4/3, 3/5, 5/2, 2/5, 5/3, 3/4, 4, 1/5, 5/4, 4/7, \
122/// 7/3, ...]"
123/// )
124/// ```
125pub fn exhaustive_non_negative_rationals() -> Chain<Once<Rational>, ExhaustivePositiveRationals> {
126 once(Rational::ZERO).chain(exhaustive_positive_rationals())
127}
128
129/// Generates all negative [`Rational`]s.
130///
131/// This `struct` is created by [`exhaustive_negative_rationals`]; see its documentation for more.
132#[derive(Clone, Debug)]
133pub struct ExhaustiveNegativeRationals {
134 xs: ExhaustivePositiveRationals,
135}
136
137impl Iterator for ExhaustiveNegativeRationals {
138 type Item = Rational;
139
140 fn next(&mut self) -> Option<Rational> {
141 self.xs.next().map(|mut q| {
142 q.sign = false;
143 q
144 })
145 }
146}
147
148/// Generates all negative [`Rational`]s.
149///
150/// The sequence is the same as the sequence of positive [`Rational`]s, but negated. See
151/// [`exhaustive_positive_rationals`] for details.
152///
153/// The output length is infinite. The absolute values of the numerators and denominators of the
154/// $n$th element are $O(n^\frac{\log \phi}{\log 2})$.
155///
156/// # Worst-case complexity per iteration
157/// $T(i) = O(\log i \log\log i \log\log\log i)$
158///
159/// $M(i) = O(\log i \log\log i)$
160///
161/// where $T$ is time, $M$ is additional memory, and $n$ is the iteration number.
162///
163/// # Examples
164/// ```
165/// use malachite_base::iterators::prefix_to_string;
166/// use malachite_q::exhaustive::exhaustive_negative_rationals;
167///
168/// assert_eq!(
169/// prefix_to_string(exhaustive_negative_rationals(), 20),
170/// "[-1, -1/2, -2, -1/3, -3/2, -2/3, -3, -1/4, -4/3, -3/5, -5/2, -2/5, -5/3, -3/4, -4, -1/5, \
171/// -5/4, -4/7, -7/3, -3/8, ...]"
172/// )
173/// ```
174pub const fn exhaustive_negative_rationals() -> ExhaustiveNegativeRationals {
175 ExhaustiveNegativeRationals {
176 xs: exhaustive_positive_rationals(),
177 }
178}
179
180/// Generates all nonzero [`Rational`]s.
181///
182/// This `struct` is created by [`exhaustive_nonzero_rationals`]; see its documentation for more.
183#[derive(Clone, Debug)]
184pub struct ExhaustiveNonzeroRationals {
185 xs: ExhaustivePositiveRationals,
186 x: Option<Rational>,
187 sign: bool,
188}
189
190impl Iterator for ExhaustiveNonzeroRationals {
191 type Item = Rational;
192
193 fn next(&mut self) -> Option<Rational> {
194 if self.sign {
195 self.sign = false;
196 let mut x = None;
197 swap(&mut self.x, &mut x);
198 let mut x = x.unwrap();
199 x.sign = false;
200 Some(x)
201 } else {
202 self.sign = true;
203 self.x = self.xs.next();
204 Some(self.x.clone().unwrap())
205 }
206 }
207}
208
209/// Generates all nonzero [`Rational`]s.
210///
211/// The sequence is the same the sequence of positive [`Rational`]s, interleaved with its negative.
212/// See [`exhaustive_positive_rationals`] for details.
213///
214/// The output length is infinite. The absolute values of the numerators and denominators of the
215/// $n$th element are $O(n^\frac{\log \phi}{\log 2})$.
216///
217/// # Worst-case complexity per iteration
218/// $T(i) = O(\log i \log\log i \log\log\log i)$
219///
220/// $M(i) = O(\log i \log\log i)$
221///
222/// where $T$ is time, $M$ is additional memory, and $n$ is the iteration number.
223///
224/// # Examples
225/// ```
226/// use malachite_base::iterators::prefix_to_string;
227/// use malachite_q::exhaustive::exhaustive_nonzero_rationals;
228///
229/// assert_eq!(
230/// prefix_to_string(exhaustive_nonzero_rationals(), 20),
231/// "[1, -1, 1/2, -1/2, 2, -2, 1/3, -1/3, 3/2, -3/2, 2/3, -2/3, 3, -3, 1/4, -1/4, 4/3, -4/3, \
232/// 3/5, -3/5, ...]"
233/// )
234/// ```
235pub const fn exhaustive_nonzero_rationals() -> ExhaustiveNonzeroRationals {
236 ExhaustiveNonzeroRationals {
237 xs: exhaustive_positive_rationals(),
238 x: None,
239 sign: false,
240 }
241}
242
243/// Generates all [`Rational`]s.
244///
245/// The sequence begins with zero and is followed by the sequence of positive [`Rational`]s,
246/// interleaved with its negative. See [`exhaustive_positive_rationals`] for details.
247///
248/// The output length is infinite. The absolute values of the numerators and denominators of the
249/// $n$th element are $O(n^\frac{\log \phi}{\log 2})$.
250///
251/// # Worst-case complexity per iteration
252/// $T(n) = O(\log n \log\log n \log\log\log n)$
253///
254/// $M(i) = O(\log n \log\log n)$
255///
256/// where $T$ is time, $M$ is additional memory, and $n$ is the iteration number.
257///
258/// # Examples
259/// ```
260/// use malachite_base::iterators::prefix_to_string;
261/// use malachite_q::exhaustive::exhaustive_rationals;
262///
263/// assert_eq!(
264/// prefix_to_string(exhaustive_rationals(), 20),
265/// "[0, 1, -1, 1/2, -1/2, 2, -2, 1/3, -1/3, 3/2, -3/2, 2/3, -2/3, 3, -3, 1/4, -1/4, 4/3, \
266/// -4/3, 3/5, ...]"
267/// )
268/// ```
269pub fn exhaustive_rationals() -> Chain<Once<Rational>, ExhaustiveNonzeroRationals> {
270 once(Rational::ZERO).chain(exhaustive_nonzero_rationals())
271}
272
273/// Generates all [`Rational`]s with a specific denominator and with numerators from a given
274/// iterator. Numerators that are not coprime with the denominator are skipped.
275#[derive(Clone, Debug)]
276pub struct RationalsWithDenominator<I: Iterator<Item = Integer>> {
277 pub(crate) numerators: I,
278 pub(crate) denominator: Natural,
279}
280
281impl<I: Iterator<Item = Integer>> Iterator for RationalsWithDenominator<I> {
282 type Item = Rational;
283
284 fn next(&mut self) -> Option<Rational> {
285 loop {
286 let n = self.numerators.next()?;
287 if n.unsigned_abs_ref().coprime_with(&self.denominator) {
288 return Some(Rational {
289 sign: n >= 0u32,
290 numerator: n.unsigned_abs(),
291 denominator: self.denominator.clone(),
292 });
293 }
294 }
295 }
296}
297
298/// Generates all [`Rational`]s greater than or equal to some number $a$ and with a specific
299/// denominator, in order of increasing absolute value.
300///
301/// When two [`Rational`]s have the same absolute value, the positive one comes first.
302///
303/// The output satisfies $(|x_i|, \operatorname{sgn}(-x_i)) <_\mathrm{lex} (|x_j|,
304/// \operatorname{sgn}(-x_j))$ whenever $i < j$.
305///
306/// The output length is infinite.
307///
308/// # Worst-case complexity per iteration
309/// $T(i) = O(\log i (\log \log i)^2 \log\log\log i)$
310///
311/// $M(i) = O(\log i \log \log i)$
312///
313/// where $T$ is time, $M$ is additional memory, and $i$ is the iteration number.
314///
315/// # Panics
316/// Panics if `d` is zero.
317///
318/// # Examples
319/// ```
320/// use malachite_base::iterators::prefix_to_string;
321/// use malachite_nz::natural::Natural;
322/// use malachite_q::exhaustive::exhaustive_rationals_with_denominator_range_to_infinity;
323/// use malachite_q::Rational;
324///
325/// assert_eq!(
326/// prefix_to_string(
327/// exhaustive_rationals_with_denominator_range_to_infinity(
328/// Natural::from(5u32),
329/// Rational::from_signeds(22i32, 7)
330/// ),
331/// 10
332/// ),
333/// "[16/5, 17/5, 18/5, 19/5, 21/5, 22/5, 23/5, 24/5, 26/5, 27/5, ...]"
334/// );
335/// assert_eq!(
336/// prefix_to_string(
337/// exhaustive_rationals_with_denominator_range_to_infinity(
338/// Natural::from(2u32),
339/// Rational::from_signeds(-22i32, 7)
340/// ),
341/// 10
342/// ),
343/// "[1/2, -1/2, 3/2, -3/2, 5/2, -5/2, 7/2, 9/2, 11/2, 13/2, ...]"
344/// );
345/// ```
346pub fn exhaustive_rationals_with_denominator_range_to_infinity(
347 d: Natural,
348 a: Rational,
349) -> RationalsWithDenominator<ExhaustiveIntegerRangeToInfinity> {
350 assert_ne!(d, 0u32);
351 RationalsWithDenominator {
352 numerators: exhaustive_integer_range_to_infinity(
353 Integer::rounding_from(a * Rational::from(&d), Ceiling).0,
354 ),
355 denominator: d,
356 }
357}
358
359/// Generates all [`Rational`]s less than or equal to some number $a$ and with a specific
360/// denominator, in order of increasing absolute value.
361///
362/// When two [`Rational`]s have the same absolute value, the positive one comes first.
363///
364/// The output satisfies $(|x_i|, \operatorname{sgn}(-x_i)) <_\mathrm{lex} (|x_j|,
365/// \operatorname{sgn}(-x_j))$ whenever $i < j$.
366///
367/// The output length is infinite.
368///
369/// # Worst-case complexity per iteration
370/// $T(i) = O(\log i (\log \log i)^2 \log\log\log i)$
371///
372/// $M(i) = O(\log i \log \log i)$
373///
374/// where $T$ is time, $M$ is additional memory, and $i$ is the iteration number.
375///
376/// # Panics
377/// Panics if `d` is zero.
378///
379/// # Examples
380/// ```
381/// use malachite_base::iterators::prefix_to_string;
382/// use malachite_nz::natural::Natural;
383/// use malachite_q::exhaustive::exhaustive_rationals_with_denominator_range_to_negative_infinity;
384/// use malachite_q::Rational;
385///
386/// assert_eq!(
387/// prefix_to_string(
388/// exhaustive_rationals_with_denominator_range_to_negative_infinity(
389/// Natural::from(5u32),
390/// Rational::from_signeds(-22i32, 7)
391/// ),
392/// 10
393/// ),
394/// "[-16/5, -17/5, -18/5, -19/5, -21/5, -22/5, -23/5, -24/5, -26/5, -27/5, ...]"
395/// );
396/// assert_eq!(
397/// prefix_to_string(
398/// exhaustive_rationals_with_denominator_range_to_negative_infinity(
399/// Natural::from(2u32),
400/// Rational::from_signeds(22i32, 7)
401/// ),
402/// 10
403/// ),
404/// "[1/2, -1/2, 3/2, -3/2, 5/2, -5/2, -7/2, -9/2, -11/2, -13/2, ...]"
405/// );
406/// ```
407pub fn exhaustive_rationals_with_denominator_range_to_negative_infinity(
408 d: Natural,
409 a: Rational,
410) -> RationalsWithDenominator<ExhaustiveIntegerRangeToNegativeInfinity> {
411 assert_ne!(d, 0u32);
412 RationalsWithDenominator {
413 numerators: exhaustive_integer_range_to_negative_infinity(
414 Integer::rounding_from(a * Rational::from(&d), Floor).0,
415 ),
416 denominator: d,
417 }
418}
419
420/// Generates all [`Rational`]s in the half-open range $[a, b)$ and with a specific denominator, in
421/// order of increasing absolute value.
422///
423/// When two [`Rational`]s have the same absolute value, the positive one comes first.
424///
425/// The output satisfies $(|x_i|, \operatorname{sgn}(-x_i)) <_\mathrm{lex} (|x_j|,
426/// \operatorname{sgn}(-x_j))$ whenever $i < j$.
427///
428/// The output length is infinite.
429///
430/// # Worst-case complexity per iteration
431/// $T(i) = O(\log i (\log \log i)^2 \log\log\log i)$
432///
433/// $M(i) = O(\log i \log \log i)$
434///
435/// where $T$ is time, $M$ is additional memory, and $i$ is the iteration number.
436///
437/// # Panics
438/// Panics if `d` is zero or if $a \geq b$.
439///
440/// # Examples
441/// ```
442/// use itertools::Itertools;
443/// use malachite_base::strings::ToDebugString;
444/// use malachite_nz::natural::Natural;
445/// use malachite_q::exhaustive::exhaustive_rationals_with_denominator_range;
446/// use malachite_q::Rational;
447///
448/// assert_eq!(
449/// exhaustive_rationals_with_denominator_range(
450/// Natural::from(2u32),
451/// Rational::from_signeds(1i32, 3),
452/// Rational::from_signeds(5i32, 2)
453/// )
454/// .collect_vec()
455/// .to_debug_string(),
456/// "[1/2, 3/2]"
457/// );
458/// assert_eq!(
459/// exhaustive_rationals_with_denominator_range(
460/// Natural::from(2u32),
461/// Rational::from_signeds(-5i32, 3),
462/// Rational::from_signeds(5i32, 2)
463/// )
464/// .collect_vec()
465/// .to_debug_string(),
466/// "[1/2, -1/2, 3/2, -3/2]"
467/// );
468/// assert_eq!(
469/// exhaustive_rationals_with_denominator_range(
470/// Natural::from(10u32),
471/// Rational::try_from_float_simplest(std::f64::consts::E).unwrap(),
472/// Rational::try_from_float_simplest(std::f64::consts::PI).unwrap(),
473/// )
474/// .collect_vec()
475/// .to_debug_string(),
476/// "[29/10, 31/10]"
477/// );
478/// ```
479pub fn exhaustive_rationals_with_denominator_range(
480 d: Natural,
481 a: Rational,
482 b: Rational,
483) -> RationalsWithDenominator<ExhaustiveIntegerRange> {
484 assert_ne!(d, 0u32);
485 assert!(a < b);
486 let q_d = Rational::from(&d);
487 let a_i = Integer::rounding_from(a * &q_d, Ceiling).0;
488 let upper_included = b.denominator_ref() == &d;
489 let mut b_i = Integer::rounding_from(b * q_d, Floor).0;
490 if !upper_included {
491 b_i += Integer::ONE;
492 }
493 RationalsWithDenominator {
494 numerators: exhaustive_integer_range(a_i, b_i),
495 denominator: d,
496 }
497}
498
499/// Generates all [`Rational`]s in the closed range $[a, b]$ and with a specific denominator, in
500/// order of increasing absolute value.
501///
502/// When two [`Rational`]s have the same absolute value, the positive one comes first.
503///
504/// The output satisfies $(|x_i|, \operatorname{sgn}(-x_i)) <_\mathrm{lex} (|x_j|,
505/// \operatorname{sgn}(-x_j))$ whenever $i < j$.
506///
507/// The output length is infinite.
508///
509/// # Worst-case complexity per iteration
510/// $T(i) = O(\log i (\log \log i)^2 \log\log\log i)$
511///
512/// $M(i) = O(\log i \log \log i)$
513///
514/// where $T$ is time, $M$ is additional memory, and $i$ is the iteration number.
515///
516/// # Panics
517/// Panics if `d` is zero or if $a > b$.
518///
519/// # Examples
520/// ```
521/// use itertools::Itertools;
522/// use malachite_base::strings::ToDebugString;
523/// use malachite_nz::natural::Natural;
524/// use malachite_q::exhaustive::exhaustive_rationals_with_denominator_inclusive_range;
525/// use malachite_q::Rational;
526///
527/// assert_eq!(
528/// exhaustive_rationals_with_denominator_inclusive_range(
529/// Natural::from(2u32),
530/// Rational::from_signeds(1i32, 3),
531/// Rational::from_signeds(5i32, 2)
532/// )
533/// .collect_vec()
534/// .to_debug_string(),
535/// "[1/2, 3/2, 5/2]"
536/// );
537/// assert_eq!(
538/// exhaustive_rationals_with_denominator_inclusive_range(
539/// Natural::from(2u32),
540/// Rational::from_signeds(-5i32, 3),
541/// Rational::from_signeds(5i32, 2)
542/// )
543/// .collect_vec()
544/// .to_debug_string(),
545/// "[1/2, -1/2, 3/2, -3/2, 5/2]"
546/// );
547/// assert_eq!(
548/// exhaustive_rationals_with_denominator_inclusive_range(
549/// Natural::from(10u32),
550/// Rational::try_from_float_simplest(std::f64::consts::E).unwrap(),
551/// Rational::try_from_float_simplest(std::f64::consts::PI).unwrap(),
552/// )
553/// .collect_vec()
554/// .to_debug_string(),
555/// "[29/10, 31/10]"
556/// );
557/// ```
558pub fn exhaustive_rationals_with_denominator_inclusive_range(
559 d: Natural,
560 a: Rational,
561 b: Rational,
562) -> RationalsWithDenominator<ExhaustiveIntegerRange> {
563 assert_ne!(d, 0u32);
564 assert!(a <= b);
565 let q_d = Rational::from(&d);
566 let a_i = Integer::rounding_from(a * &q_d, Ceiling).0;
567 let b_i = Integer::rounding_from(b * q_d, Floor).0 + Integer::ONE;
568 RationalsWithDenominator {
569 numerators: exhaustive_integer_range(a_i, b_i),
570 denominator: d,
571 }
572}
573
574#[derive(Clone, Debug)]
575struct ExhaustiveRationalsWithDenominatorRangeToInfinityGenerator {
576 a: Rational,
577}
578
579impl
580 ExhaustiveDependentPairsYsGenerator<
581 Natural,
582 Rational,
583 RationalsWithDenominator<ExhaustiveIntegerRangeToInfinity>,
584 > for ExhaustiveRationalsWithDenominatorRangeToInfinityGenerator
585{
586 #[inline]
587 fn get_ys(&self, d: &Natural) -> RationalsWithDenominator<ExhaustiveIntegerRangeToInfinity> {
588 exhaustive_rationals_with_denominator_range_to_infinity(d.clone(), self.a.clone())
589 }
590}
591
592#[inline]
593const fn exhaustive_rational_range_to_infinity_helper(
594 a: Rational,
595) -> ExhaustiveDependentPairs<
596 Natural,
597 Rational,
598 RulerSequence<usize>,
599 ExhaustiveRationalsWithDenominatorRangeToInfinityGenerator,
600 ExhaustiveNaturalRangeToInfinity,
601 RationalsWithDenominator<ExhaustiveIntegerRangeToInfinity>,
602> {
603 exhaustive_dependent_pairs(
604 ruler_sequence(),
605 exhaustive_positive_naturals(),
606 ExhaustiveRationalsWithDenominatorRangeToInfinityGenerator { a },
607 )
608}
609
610/// Generates all [`Rational`]s greater than or equal to some [`Rational`].
611///
612/// This `struct` is created by [`exhaustive_rational_range_to_infinity`]; see its documentation for
613/// more.
614#[derive(Clone, Debug)]
615pub struct ExhaustiveRationalRangeToInfinity(
616 ExhaustiveDependentPairs<
617 Natural,
618 Rational,
619 RulerSequence<usize>,
620 ExhaustiveRationalsWithDenominatorRangeToInfinityGenerator,
621 ExhaustiveNaturalRangeToInfinity,
622 RationalsWithDenominator<ExhaustiveIntegerRangeToInfinity>,
623 >,
624);
625
626impl Iterator for ExhaustiveRationalRangeToInfinity {
627 type Item = Rational;
628
629 #[inline]
630 fn next(&mut self) -> Option<Rational> {
631 self.0.next().map(|p| p.1)
632 }
633}
634
635/// Generates all [`Rational`]s greater than or equal to some [`Rational`] $a$.
636///
637/// The output length is infinite.
638///
639/// # Worst-case complexity per iteration
640/// $T(i) = O(\log i (\log \log i)^2 \log\log\log i)$
641///
642/// $M(i) = O(\log i \log \log i)$
643///
644/// where $T$ is time, $M$ is additional memory, and $i$ is the iteration number.
645///
646/// # Examples
647/// ```
648/// use malachite_base::iterators::prefix_to_string;
649/// use malachite_base::num::conversion::traits::ExactFrom;
650/// use malachite_q::exhaustive::exhaustive_rational_range_to_infinity;
651/// use malachite_q::Rational;
652///
653/// assert_eq!(
654/// prefix_to_string(
655/// exhaustive_rational_range_to_infinity(Rational::exact_from(std::f64::consts::PI)),
656/// 20
657/// ),
658/// "[4, 7/2, 5, 10/3, 6, 9/2, 7, 13/4, 8, 11/2, 9, 11/3, 10, 13/2, 11, 16/5, 12, 15/2, 13, \
659/// 13/3, ...]"
660/// )
661/// ```
662#[inline]
663pub const fn exhaustive_rational_range_to_infinity(
664 a: Rational,
665) -> ExhaustiveRationalRangeToInfinity {
666 ExhaustiveRationalRangeToInfinity(exhaustive_rational_range_to_infinity_helper(a))
667}
668
669#[derive(Clone, Debug)]
670struct ExhaustiveRationalsWithDenominatorRangeToNegativeInfinityGenerator {
671 a: Rational,
672}
673
674impl
675 ExhaustiveDependentPairsYsGenerator<
676 Natural,
677 Rational,
678 RationalsWithDenominator<ExhaustiveIntegerRangeToNegativeInfinity>,
679 > for ExhaustiveRationalsWithDenominatorRangeToNegativeInfinityGenerator
680{
681 #[inline]
682 fn get_ys(
683 &self,
684 d: &Natural,
685 ) -> RationalsWithDenominator<ExhaustiveIntegerRangeToNegativeInfinity> {
686 exhaustive_rationals_with_denominator_range_to_negative_infinity(d.clone(), self.a.clone())
687 }
688}
689
690#[inline]
691const fn exhaustive_rational_range_to_negative_infinity_helper(
692 a: Rational,
693) -> ExhaustiveDependentPairs<
694 Natural,
695 Rational,
696 RulerSequence<usize>,
697 ExhaustiveRationalsWithDenominatorRangeToNegativeInfinityGenerator,
698 ExhaustiveNaturalRangeToInfinity,
699 RationalsWithDenominator<ExhaustiveIntegerRangeToNegativeInfinity>,
700> {
701 exhaustive_dependent_pairs(
702 ruler_sequence(),
703 exhaustive_positive_naturals(),
704 ExhaustiveRationalsWithDenominatorRangeToNegativeInfinityGenerator { a },
705 )
706}
707
708/// Generates all [`Rational`]s less than or equal to some [`Rational`].
709///
710/// This `struct` is created by [`exhaustive_rational_range_to_negative_infinity`]; see its
711/// documentation for more.
712#[derive(Clone, Debug)]
713pub struct ExhaustiveRationalRangeToNegativeInfinity(
714 ExhaustiveDependentPairs<
715 Natural,
716 Rational,
717 RulerSequence<usize>,
718 ExhaustiveRationalsWithDenominatorRangeToNegativeInfinityGenerator,
719 ExhaustiveNaturalRangeToInfinity,
720 RationalsWithDenominator<ExhaustiveIntegerRangeToNegativeInfinity>,
721 >,
722);
723
724impl Iterator for ExhaustiveRationalRangeToNegativeInfinity {
725 type Item = Rational;
726
727 #[inline]
728 fn next(&mut self) -> Option<Rational> {
729 self.0.next().map(|p| p.1)
730 }
731}
732
733/// Generates all [`Rational`]s less than or equal to some [`Rational`] $a$.
734///
735/// The output length is infinite.
736///
737/// # Worst-case complexity per iteration
738/// $T(i) = O(\log i (\log \log i)^2 \log\log\log i)$
739///
740/// $M(i) = O(\log i \log \log i)$
741///
742/// where $T$ is time, $M$ is additional memory, and $i$ is the iteration number.
743///
744/// # Examples
745/// ```
746/// use malachite_base::iterators::prefix_to_string;
747/// use malachite_base::num::conversion::traits::ExactFrom;
748/// use malachite_q::exhaustive::exhaustive_rational_range_to_negative_infinity;
749/// use malachite_q::Rational;
750///
751/// assert_eq!(
752/// prefix_to_string(
753/// exhaustive_rational_range_to_negative_infinity(Rational::exact_from(
754/// std::f64::consts::PI
755/// )),
756/// 20
757/// ),
758/// "[0, 1/2, 1, 1/3, -1, -1/2, 2, 1/4, -2, 3/2, 3, -1/3, -3, -3/2, -4, 1/5, -5, 5/2, -6, \
759/// 2/3, ...]"
760/// )
761/// ```
762#[inline]
763pub const fn exhaustive_rational_range_to_negative_infinity(
764 a: Rational,
765) -> ExhaustiveRationalRangeToNegativeInfinity {
766 ExhaustiveRationalRangeToNegativeInfinity(
767 exhaustive_rational_range_to_negative_infinity_helper(a),
768 )
769}
770
771#[derive(Clone, Debug)]
772struct ExhaustiveRationalsWithDenominatorRangeGenerator {
773 a: Rational,
774 b: Rational,
775}
776
777impl
778 ExhaustiveDependentPairsYsGenerator<
779 Natural,
780 Rational,
781 RationalsWithDenominator<ExhaustiveIntegerRange>,
782 > for ExhaustiveRationalsWithDenominatorRangeGenerator
783{
784 #[inline]
785 fn get_ys(&self, d: &Natural) -> RationalsWithDenominator<ExhaustiveIntegerRange> {
786 exhaustive_rationals_with_denominator_range(d.clone(), self.a.clone(), self.b.clone())
787 }
788}
789
790#[inline]
791fn exhaustive_rational_range_helper(
792 a: Rational,
793 b: Rational,
794) -> ExhaustiveDependentPairs<
795 Natural,
796 Rational,
797 RulerSequence<usize>,
798 ExhaustiveRationalsWithDenominatorRangeGenerator,
799 DenominatorsInClosedRationalInterval,
800 RationalsWithDenominator<ExhaustiveIntegerRange>,
801> {
802 exhaustive_dependent_pairs(
803 ruler_sequence(),
804 Rational::denominators_in_closed_interval(a.clone(), b.clone()),
805 ExhaustiveRationalsWithDenominatorRangeGenerator { a, b },
806 )
807}
808
809/// Generates all [`Natural`]s in an interval of the form $[a,b)$.
810///
811/// This `struct` is created by [`exhaustive_rational_range`]; see its documentation for more.
812#[allow(private_interfaces, clippy::large_enum_variant)]
813#[derive(Clone, Debug)]
814pub enum ExhaustiveRationalRange {
815 Empty,
816 Nonempty(
817 ExhaustiveDependentPairs<
818 Natural,
819 Rational,
820 RulerSequence<usize>,
821 ExhaustiveRationalsWithDenominatorRangeGenerator,
822 DenominatorsInClosedRationalInterval,
823 RationalsWithDenominator<ExhaustiveIntegerRange>,
824 >,
825 ),
826}
827
828impl Iterator for ExhaustiveRationalRange {
829 type Item = Rational;
830
831 #[inline]
832 fn next(&mut self) -> Option<Rational> {
833 match self {
834 Self::Empty => None,
835 Self::Nonempty(xs) => xs.next().map(|p| p.1),
836 }
837 }
838}
839
840/// Generates all [`Rational`]s in the half-open interval $[a, b)$.
841///
842/// `a` must be less than or equal to `b`. If `a` and `b` are equal, the range is empty. To generate
843/// all [`Rational`]s in an infinite interval, use [`exhaustive_rational_range_to_infinity`] or
844/// [`exhaustive_rational_range_to_negative_infinity`].
845///
846/// The output length is infinite if $a<b$ and 0 if $a=b$.
847///
848/// # Worst-case complexity per iteration
849/// $T(i) = O(\log i (\log \log i)^2 \log\log\log i)$
850///
851/// $M(i) = O(\log i \log \log i)$
852///
853/// where $T$ is time, $M$ is additional memory, and $i$ is the iteration number.
854///
855/// # Panics
856/// Panics if $a>b$.
857///
858/// # Examples
859/// ```
860/// use malachite_base::iterators::prefix_to_string;
861/// use malachite_base::num::conversion::traits::ExactFrom;
862/// use malachite_q::exhaustive::exhaustive_rational_range;
863/// use malachite_q::Rational;
864///
865/// assert_eq!(
866/// prefix_to_string(
867/// exhaustive_rational_range(
868/// Rational::exact_from(std::f64::consts::E),
869/// Rational::exact_from(std::f64::consts::PI)
870/// ),
871/// 20
872/// ),
873/// "[3, 11/4, 14/5, 20/7, 17/6, 23/8, 25/8, 30/11, 25/9, 29/10, 26/9, 31/11, 28/9, 31/10, \
874/// 32/11, 41/15, 34/11, 35/12, 37/12, 39/14, ...]"
875/// )
876/// ```
877#[inline]
878pub fn exhaustive_rational_range(a: Rational, b: Rational) -> ExhaustiveRationalRange {
879 if a == b {
880 ExhaustiveRationalRange::Empty
881 } else {
882 ExhaustiveRationalRange::Nonempty(exhaustive_rational_range_helper(a, b))
883 }
884}
885
886#[derive(Clone, Debug)]
887struct ExhaustiveRationalsWithDenominatorInclusiveRangeGenerator {
888 a: Rational,
889 b: Rational,
890}
891
892impl
893 ExhaustiveDependentPairsYsGenerator<
894 Natural,
895 Rational,
896 RationalsWithDenominator<ExhaustiveIntegerRange>,
897 > for ExhaustiveRationalsWithDenominatorInclusiveRangeGenerator
898{
899 #[inline]
900 fn get_ys(&self, d: &Natural) -> RationalsWithDenominator<ExhaustiveIntegerRange> {
901 exhaustive_rationals_with_denominator_inclusive_range(
902 d.clone(),
903 self.a.clone(),
904 self.b.clone(),
905 )
906 }
907}
908
909#[inline]
910fn exhaustive_rational_inclusive_range_helper(
911 a: Rational,
912 b: Rational,
913) -> ExhaustiveDependentPairs<
914 Natural,
915 Rational,
916 RulerSequence<usize>,
917 ExhaustiveRationalsWithDenominatorInclusiveRangeGenerator,
918 DenominatorsInClosedRationalInterval,
919 RationalsWithDenominator<ExhaustiveIntegerRange>,
920> {
921 exhaustive_dependent_pairs(
922 ruler_sequence(),
923 Rational::denominators_in_closed_interval(a.clone(), b.clone()),
924 ExhaustiveRationalsWithDenominatorInclusiveRangeGenerator { a, b },
925 )
926}
927
928/// Generates all [`Rational`]s in an interval of the form $\[a,b\]$.
929///
930/// This `struct` is created by [`exhaustive_rational_inclusive_range`]; see its documentation for
931/// more.
932#[allow(private_interfaces, clippy::large_enum_variant)]
933#[derive(Clone, Debug)]
934pub enum ExhaustiveRationalInclusiveRange {
935 Single(bool, Rational),
936 Many(
937 ExhaustiveDependentPairs<
938 Natural,
939 Rational,
940 RulerSequence<usize>,
941 ExhaustiveRationalsWithDenominatorInclusiveRangeGenerator,
942 DenominatorsInClosedRationalInterval,
943 RationalsWithDenominator<ExhaustiveIntegerRange>,
944 >,
945 ),
946}
947
948impl Iterator for ExhaustiveRationalInclusiveRange {
949 type Item = Rational;
950
951 #[inline]
952 fn next(&mut self) -> Option<Rational> {
953 match self {
954 Self::Single(done, x) => {
955 if *done {
956 None
957 } else {
958 *done = true;
959 Some(x.clone())
960 }
961 }
962 Self::Many(xs) => xs.next().map(|p| p.1),
963 }
964 }
965}
966
967/// Generates all [`Rational`]s in the closed interval $[a, b]$.
968///
969/// `a` must be less than or equal to `b`. If `a` and `b` are equal, the range contains a single
970/// element. To generate all [`Rational`]s in an infinite interval, use
971/// [`exhaustive_rational_range_to_infinity`] or [`exhaustive_rational_range_to_negative_infinity`].
972///
973/// The output length is infinite if $a<b$ and 1 if $a=b$.
974///
975/// # Worst-case complexity per iteration
976/// $T(i) = O(\log i (\log \log i)^2 \log\log\log i)$
977///
978/// $M(i) = O(\log i \log \log i)$
979///
980/// where $T$ is time, $M$ is additional memory, and $i$ is the iteration number.
981///
982/// # Panics
983/// Panics if $a>b$.
984///
985/// # Examples
986/// ```
987/// use malachite_base::iterators::prefix_to_string;
988/// use malachite_base::num::conversion::traits::ExactFrom;
989/// use malachite_q::exhaustive::exhaustive_rational_inclusive_range;
990/// use malachite_q::Rational;
991///
992/// assert_eq!(
993/// prefix_to_string(
994/// exhaustive_rational_inclusive_range(
995/// Rational::exact_from(std::f64::consts::E),
996/// Rational::exact_from(std::f64::consts::PI)
997/// ),
998/// 20
999/// ),
1000/// "[3, 11/4, 14/5, 20/7, 17/6, 23/8, 25/8, 30/11, 25/9, 29/10, 26/9, 31/11, 28/9, 31/10, \
1001/// 32/11, 41/15, 34/11, 35/12, 37/12, 39/14, ...]"
1002/// )
1003/// ```
1004#[inline]
1005pub fn exhaustive_rational_inclusive_range(
1006 a: Rational,
1007 b: Rational,
1008) -> ExhaustiveRationalInclusiveRange {
1009 if a == b {
1010 ExhaustiveRationalInclusiveRange::Single(false, a)
1011 } else {
1012 ExhaustiveRationalInclusiveRange::Many(exhaustive_rational_inclusive_range_helper(a, b))
1013 }
1014}