Skip to main content

feanor_math/rings/fraction/
mod.rs

1use crate::field::Field;
2use crate::ring::*;
3
4///
5/// Contains [`fraction_impl::FractionFieldImpl`], an implementation of the fraction
6/// fields of an arbitrary principal ideal domain.
7/// 
8pub mod fraction_impl;
9
10///
11/// Trait for fields that are the field of fractions over a base ring.
12/// 
13/// Note that a field of fractions is usually the field of fractions of
14/// many rings - in particular, every field is technically its own field
15/// of fractions. However, such cases don't add any value, and this trait
16/// is mainly designed and implemented for fields that have a "canonical" or
17/// "natural" subring whose field of fractions they represent. In many
18/// cases, this is the smallest subring whose fractions generate the whole
19/// field, but this trait can also be implemented in other cases where it
20/// makes sense.
21/// 
22#[stability::unstable(feature = "enable")]
23pub trait FractionField: Field + RingExtension {
24
25    ///
26    /// Returns `a, b` such that the given element is `a/b`.
27    /// 
28    /// The return value does not have to be reduced, i.e. `gcd(a, b)` is not
29    /// guaranteed to be a unit (for rings that are not [`crate::pid::PrincipalIdealRing`], this
30    /// is not even defined). Hence, when you want to convert the result to the base ring, use
31    /// [`crate::divisibility::DivisibilityRing::checked_div()`] as follows:
32    /// ```rust
33    /// # use feanor_math::ring::*;
34    /// # use feanor_math::divisibility::*;
35    /// # use feanor_math::rings::fraction::*;
36    /// # use feanor_math::rings::rational::*;
37    /// # use feanor_math::primitive_int::*;
38    /// fn to_base_ring<R>(ring: R, el: El<R>) -> Option<El<<R::Type as RingExtension>::BaseRing>>
39    ///     where R: RingStore,
40    ///         R::Type: FractionField,
41    ///         <<R::Type as RingExtension>::BaseRing as RingStore>::Type: DivisibilityRing
42    /// {
43    ///     let (a, b) = ring.as_fraction(el);
44    ///     ring.base_ring().checked_div(&a, &b)
45    /// }
46    /// let QQ = RationalField::new(StaticRing::<i64>::RING);
47    /// assert_eq!(Some(3), to_base_ring(QQ, QQ.from_fraction(6, 2)));
48    /// ```
49    /// 
50    fn as_fraction(&self, el: Self::Element) -> (El<Self::BaseRing>, El<Self::BaseRing>);
51
52    ///
53    /// Computes `num / den`.
54    /// 
55    /// This is functionally equivalent, but may be faster than combining
56    /// [`RingExtension::from()`] and [`Field::div()`].
57    /// 
58    fn from_fraction(&self, num: El<Self::BaseRing>, den: El<Self::BaseRing>) -> Self::Element {
59        self.div(&self.from(num), &self.from(den))
60    }
61}
62
63///
64/// [`RingStore`] corresponding to [`FractionField`]
65/// 
66#[stability::unstable(feature = "enable")]
67pub trait FractionFieldStore: RingStore
68    where Self::Type: FractionField
69{
70    delegate!{ FractionField, fn as_fraction(&self, el: El<Self>) -> (El<<Self::Type as RingExtension>::BaseRing>, El<<Self::Type as RingExtension>::BaseRing>) }
71    delegate!{ FractionField, fn from_fraction(&self, num: El<<Self::Type as RingExtension>::BaseRing>, den: El<<Self::Type as RingExtension>::BaseRing>) -> El<Self> }
72}
73
74impl<R: RingStore> FractionFieldStore for R
75    where R::Type: FractionField
76{}