relp_num/traits/
factorization.rs

1//! # Number factorization
2//!
3//! Factorize integers and rational numbers into numbers that are often primes.
4use std::fmt::Debug;
5use std::hash::Hash;
6use std::ops::{Add, AddAssign, Sub, SubAssign};
7
8use num_traits::One;
9
10use crate::non_zero::{NonZero, NonZeroSign};
11use crate::Signed;
12
13/// Creating a factorization of an integer or rational number.
14///
15/// This factorization does not necessarily consist of primes, as this can be computationally
16/// expensive.
17pub trait NonZeroFactorizable: NonZero + Clone {
18    /// Some number greater than 1, probably a prime but not necessarily.
19    type Factor: NonZero + Eq + PartialEq + Ord + PartialOrd + Hash + Clone + Debug;
20    /// How often the factor appears in the number.
21    ///
22    /// This is marked Copy, because a 64-bit power already allows for values up to 2^(2^64), which
23    /// has about 5.6 * 10^18 decimal digits. Finding primes that are larger than that is too
24    /// expensive.
25    type Power: Add<Output=Self::Power> + AddAssign + Sub<Output=Self::Power> + SubAssign + One + Signed + Eq + Copy + Clone + Debug;
26
27    /// Decompose into factors.
28    ///
29    /// Note that these factors will often be, but are not guaranteed to be, primes.
30    fn factorize(&self) -> NonZeroFactorization<Self::Factor, Self::Power>;
31}
32
33/// Prime factorization representation of a nonzero rational number.
34///
35/// Includes a sign.
36#[derive(Eq, PartialEq, Clone, Debug)]
37pub struct NonZeroFactorization<Factor, Power> {
38    /// Whether the number is negative.
39    pub sign: NonZeroSign,
40    /// `(prime factor, power)` tuples.
41    ///
42    /// The factors should all be smaller than 64 bits and can have negative powers; that is, appear
43    /// in the denominator. The powers can't be zero, as this is a sparse representation.
44    ///
45    /// When this field is empty, the value `1` or `-1` is represented, depending on `sign`.
46    pub factors: Vec<(Factor, Power)>,
47}