ring_algorithm/
ring_traits.rs1use num_traits::{One, Zero};
2use std::ops::{Add, Div, Mul, Rem, Sub};
3pub trait RingOperation: Sized + Add + Sub + Mul {}
4impl<T> RingOperation for T where T: Sized + Add + Sub + Mul {}
5pub trait RingOperationFrom:
6 Sized
7 + for<'x> From<<&'x Self as Add>::Output>
8 + for<'x> From<<&'x Self as Sub>::Output>
9 + for<'x> From<<&'x Self as Mul>::Output>
10where
11 for<'x> &'x Self: RingOperation,
12{
13}
14impl<T> RingOperationFrom for T
15where
16 T: Sized
17 + for<'x> From<<&'x T as Add>::Output>
18 + for<'x> From<<&'x T as Sub>::Output>
19 + for<'x> From<<&'x T as Mul>::Output>,
20 for<'x> &'x T: RingOperation,
21{
22}
23pub trait EuclideanRingOperation: RingOperation + Div + Rem {}
24impl<T> EuclideanRingOperation for T where T: RingOperation + Div + Rem {}
25pub trait EuclideanRingOperationFrom:
26 RingOperationFrom
27 + for<'x> From<<&'x Self as Div>::Output>
28 + for<'x> From<<&'x Self as Rem>::Output>
29where
30 for<'x> &'x Self: EuclideanRingOperation,
31{
32}
33impl<T> EuclideanRingOperationFrom for T
34where
35 T: RingOperationFrom
36 + for<'x> From<<&'x T as Div>::Output>
37 + for<'x> From<<&'x T as Rem>::Output>,
38 for<'x> &'x T: EuclideanRingOperation,
39{
40}
41pub trait RingNormalize {
47 #[must_use]
48 fn leading_unit(&self) -> Self;
49 fn normalize_mut(&mut self);
50 #[must_use]
51 fn into_normalize(mut self) -> Self
52 where
53 Self: Sized,
54 {
55 self.normalize_mut();
56 self
57 }
58 #[must_use]
59 fn normalize(&self) -> Self
60 where
61 Self: Clone,
62 {
63 self.clone().into_normalize()
64 }
65 fn is_similar(&self, other: &Self) -> bool
66 where
67 Self: Clone + Eq,
68 {
69 self.normalize() == other.normalize()
70 }
71}
72
73macro_rules! ring_normalize {
74 ($t:ty) => {
75 impl RingNormalize for $t {
76 fn leading_unit(&self) -> Self {
77 if self >= &Self::zero() {
78 Self::one()
79 } else {
80 -Self::one()
81 }
82 }
83 fn normalize_mut(&mut self) {
84 *self = self.abs();
85 }
86 }
87 };
88}
89macro_rules! ring_normalize_unsigned {
90 ($t:ty) => {
91 impl RingNormalize for $t {
92 fn leading_unit(&self) -> Self {
93 Self::one()
94 }
95 fn normalize_mut(&mut self) {}
96 }
97 };
98}
99
100ring_normalize!(i8);
101ring_normalize!(i16);
102ring_normalize!(i32);
103ring_normalize!(i64);
104ring_normalize!(i128);
105ring_normalize!(isize);
106ring_normalize_unsigned!(u8);
107ring_normalize_unsigned!(u16);
108ring_normalize_unsigned!(u32);
109ring_normalize_unsigned!(u64);
110ring_normalize_unsigned!(u128);
111ring_normalize_unsigned!(usize);
112
113#[cfg(feature = "num-bigint")]
114impl RingNormalize for num_bigint::BigInt {
115 fn leading_unit(&self) -> Self {
116 if self.sign() == num_bigint::Sign::Minus {
117 -Self::one()
118 } else {
119 Self::one()
120 }
121 }
122 fn normalize_mut(&mut self) {
123 if self.sign() == num_bigint::Sign::Minus {
124 *self = -&*self
125 }
126 }
127}
128#[cfg(feature = "num-bigint")]
129impl RingNormalize for num_bigint::BigUint {
130 fn leading_unit(&self) -> Self {
131 Self::one()
132 }
133 fn normalize_mut(&mut self) {}
134}
135#[cfg(feature = "rug")]
136impl RingNormalize for rug::Integer {
137 fn leading_unit(&self) -> Self {
138 if self < &Self::zero() {
139 -Self::one()
140 } else {
141 Self::one()
142 }
143 }
144 fn normalize_mut(&mut self) {
145 self.abs_mut()
146 }
147}