Skip to content

Commit

Permalink
Add Fraction fields
Browse files Browse the repository at this point in the history
- Remove PartialOrd for ring elements and replace it
  with an internal ordering
  • Loading branch information
benruijl committed Jul 17, 2024
1 parent 9e06cdf commit 24bb31e
Show file tree
Hide file tree
Showing 13 changed files with 647 additions and 83 deletions.
59 changes: 59 additions & 0 deletions src/atom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,20 @@ impl Atom {
}
}

impl std::ops::Add<Atom> for Atom {
type Output = Atom;

fn add(self, mut rhs: Atom) -> Atom {
Workspace::get_local().with(|ws| {
let mut t = ws.new_atom();
self.as_view().add_with_ws_into(ws, rhs.as_view(), &mut t);
std::mem::swap(&mut rhs, &mut t);
});

rhs
}
}

impl std::ops::Add<Atom> for &Atom {
type Output = Atom;

Expand All @@ -779,6 +793,23 @@ impl std::ops::Add<Atom> for &Atom {
}
}

impl std::ops::Sub<Atom> for Atom {
type Output = Atom;

fn sub(self, mut rhs: Atom) -> Atom {
Workspace::get_local().with(|ws| {
let mut t = ws.new_atom();
self.as_view()
.sub_no_norm(ws, rhs.as_view())
.as_view()
.normalize(ws, &mut t);
std::mem::swap(&mut rhs, &mut t);
});

rhs
}
}

impl std::ops::Sub<Atom> for &Atom {
type Output = Atom;

Expand Down Expand Up @@ -810,6 +841,34 @@ impl std::ops::Mul<Atom> for &Atom {
}
}

impl std::ops::Mul<Atom> for Atom {
type Output = Atom;

fn mul(self, mut rhs: Atom) -> Atom {
Workspace::get_local().with(|ws| {
let mut t = ws.new_atom();
self.as_view().mul_with_ws_into(ws, rhs.as_view(), &mut t);
std::mem::swap(&mut rhs, &mut t);
});

rhs
}
}

impl std::ops::Div<Atom> for Atom {
type Output = Atom;

fn div(self, mut rhs: Atom) -> Atom {
Workspace::get_local().with(|ws| {
let mut t = ws.new_atom();
self.as_view().div_with_ws_into(ws, rhs.as_view(), &mut t);
std::mem::swap(&mut rhs, &mut t);
});

rhs
}
}

impl std::ops::Div<Atom> for &Atom {
type Output = Atom;

Expand Down
49 changes: 48 additions & 1 deletion src/domains.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,55 @@ use integer::Integer;

use crate::printer::PrintOptions;

pub trait InternalOrdering {
/// Compare two elements using an internal ordering.
fn internal_cmp(&self, other: &Self) -> std::cmp::Ordering;
}

macro_rules! impl_internal_ordering {
($($t:ty),*) => {
$(
impl InternalOrdering for $t {
fn internal_cmp(&self, other: &Self) -> std::cmp::Ordering {
self.cmp(other)
}
}
)*
};
}

impl_internal_ordering!(u8);
impl_internal_ordering!(u64);

macro_rules! impl_internal_ordering_range {
($($t:ty),*) => {
$(
impl<T: InternalOrdering> InternalOrdering for $t {
fn internal_cmp(&self, other: &Self) -> std::cmp::Ordering {
match self.len().cmp(&other.len()) {
std::cmp::Ordering::Equal => (),
ord => return ord,
}

for (i, j) in self.iter().zip(other) {
match i.internal_cmp(&j) {
std::cmp::Ordering::Equal => {}
ord => return ord,
}
}

std::cmp::Ordering::Equal
}
}
)*
};
}

impl_internal_ordering_range!([T]);
impl_internal_ordering_range!(Vec<T>);

pub trait Ring: Clone + PartialEq + Eq + Hash + Debug + Display {
type Element: Clone + PartialEq + Eq + Hash + PartialOrd + Debug;
type Element: Clone + PartialEq + Eq + Hash + InternalOrdering + Debug;

fn add(&self, a: &Self::Element, b: &Self::Element) -> Self::Element;
fn sub(&self, a: &Self::Element, b: &Self::Element) -> Self::Element;
Expand Down
10 changes: 5 additions & 5 deletions src/domains/algebraic_number.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ use super::{
},
integer::Integer,
rational::Rational,
EuclideanDomain, Field, Ring,
EuclideanDomain, Field, InternalOrdering, Ring,
};

/// An algebraic number ring, with a monic, irreducible defining polynomial.
// TODO: make special case for degree two and three and hardcode the multiplication table
#[derive(Clone, PartialEq, Eq, PartialOrd, Hash)]
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct AlgebraicExtension<R: Ring> {
poly: Arc<MultivariatePolynomial<R, u16>>, // TODO: convert to univariate polynomial
}
Expand Down Expand Up @@ -334,9 +334,9 @@ pub struct AlgebraicNumber<R: Ring> {
pub(crate) poly: MultivariatePolynomial<R, u16>,
}

impl<R: Ring> PartialOrd for AlgebraicNumber<R> {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
self.poly.partial_cmp(&other.poly)
impl<R: Ring> InternalOrdering for AlgebraicNumber<R> {
fn internal_cmp(&self, other: &Self) -> std::cmp::Ordering {
self.poly.internal_cmp(&other.poly)
}
}

Expand Down
8 changes: 7 additions & 1 deletion src/domains/atom.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::atom::{Atom, AtomView};

use super::{integer::Integer, EuclideanDomain, Field, Ring};
use super::{integer::Integer, EuclideanDomain, Field, InternalOrdering, Ring};

use rand::Rng;

Expand Down Expand Up @@ -31,6 +31,12 @@ impl std::fmt::Debug for AtomField {
}
}

impl InternalOrdering for Atom {
fn internal_cmp(&self, other: &Self) -> std::cmp::Ordering {
self.cmp(other)
}
}

impl Ring for AtomField {
type Element = Atom;

Expand Down
6 changes: 3 additions & 3 deletions src/domains/factorized_rational_polynomial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use super::{
finite_field::{FiniteField, FiniteFieldCore, FiniteFieldWorkspace, ToFiniteField},
integer::{Integer, IntegerRing, Z},
rational::RationalField,
EuclideanDomain, Field, Ring,
EuclideanDomain, Field, InternalOrdering, Ring,
};

#[derive(Clone, PartialEq, Eq, Hash, Debug)]
Expand Down Expand Up @@ -71,9 +71,9 @@ pub struct FactorizedRationalPolynomial<R: Ring, E: Exponent> {
pub denominators: Vec<(MultivariatePolynomial<R, E>, usize)>, // TODO: sort factors?
}

impl<R: Ring, E: Exponent> PartialOrd for FactorizedRationalPolynomial<R, E> {
impl<R: Ring, E: Exponent> InternalOrdering for FactorizedRationalPolynomial<R, E> {
/// An ordering of rational polynomials that has no intuitive meaning.
fn partial_cmp(&self, _other: &Self) -> Option<Ordering> {
fn internal_cmp(&self, _other: &Self) -> Ordering {
todo!()
}
}
Expand Down
8 changes: 7 additions & 1 deletion src/domains/finite_field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::printer::PrintOptions;

use super::algebraic_number::AlgebraicExtension;
use super::integer::Z;
use super::{EuclideanDomain, Field, Ring};
use super::{EuclideanDomain, Field, InternalOrdering, Ring};

const HENSEL_LIFTING_MASK: [u8; 128] = [
255, 85, 51, 73, 199, 93, 59, 17, 15, 229, 195, 89, 215, 237, 203, 33, 31, 117, 83, 105, 231,
Expand Down Expand Up @@ -145,6 +145,12 @@ where
#[derive(Debug, Copy, Clone, Hash, PartialEq, PartialOrd, Eq)]
pub struct FiniteFieldElement<UField>(pub(crate) UField);

impl<UField: PartialOrd> InternalOrdering for FiniteFieldElement<UField> {
fn internal_cmp(&self, other: &Self) -> std::cmp::Ordering {
self.partial_cmp(other).unwrap_or(std::cmp::Ordering::Equal)
}
}

pub trait FiniteFieldWorkspace: Clone + Display + Eq + Hash {
/// Convert to u64.
fn to_u64(&self) -> u64;
Expand Down
16 changes: 14 additions & 2 deletions src/domains/integer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use super::{
Zp64, Z2,
},
rational::Rational,
EuclideanDomain, Ring,
EuclideanDomain, InternalOrdering, Ring,
};

pub const SMALL_PRIMES: [i64; 100] = [
Expand Down Expand Up @@ -59,6 +59,12 @@ pub enum Integer {
Large(MultiPrecisionInteger),
}

impl InternalOrdering for Integer {
fn internal_cmp(&self, other: &Self) -> std::cmp::Ordering {
Ord::cmp(self, &other)
}
}

macro_rules! from_with_cast {
($base: ty) => {
impl From<$base> for Integer {
Expand Down Expand Up @@ -478,7 +484,7 @@ impl Integer {
.as_abs()
.partial_cmp(&n2.unsigned_abs())
.unwrap_or(Ordering::Equal),
(_, _) => self.abs().cmp(&other.abs()),
(_, _) => Ord::cmp(&self.abs(), &other.abs()),
}
}

Expand Down Expand Up @@ -1871,6 +1877,12 @@ impl MultiPrecisionIntegerRing {
}
}

impl InternalOrdering for MultiPrecisionInteger {
fn internal_cmp(&self, other: &Self) -> std::cmp::Ordering {
Ord::cmp(self, &other)
}
}

impl Ring for MultiPrecisionIntegerRing {
type Element = MultiPrecisionInteger;

Expand Down
Loading

0 comments on commit 24bb31e

Please sign in to comment.