1use crate::{polynomial, Polynomial, Sized};
2use auto_impl_ops::auto_ops;
3use num_traits::{One, Zero};
4use ring_algorithm::RingNormalize;
5use std::{
6 iter::{Product, Sum},
7 ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, SubAssign},
8};
9
10#[auto_ops]
12impl<M> AddAssign<&Polynomial<M>> for Polynomial<M>
13where
14 M: Sized + Zero + for<'x> AddAssign<&'x M>,
15{
16 fn add_assign(&mut self, other: &Self) {
17 let len = self.len();
18 self.extend(other.len());
19 self.coeff
20 .iter_mut()
21 .zip(other.coeff.iter())
22 .for_each(|(l, r)| *l += r);
23 if len == other.len() {
24 self.trim_zero()
25 }
26 }
27}
28
29impl<M> Zero for Polynomial<M>
30where
31 M: Sized + Zero + for<'x> AddAssign<&'x M>,
32{
33 fn zero() -> Self {
34 Self { coeff: Vec::new() }
35 }
36 fn is_zero(&self) -> bool {
37 self.deg().is_none()
38 }
39}
40
41impl<M> Sum for Polynomial<M>
42where
43 M: Sized + Zero + for<'x> AddAssign<&'x M>,
44{
45 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
46 iter.fold(Self::zero(), Add::add)
47 }
48}
49
50impl<G> Neg for Polynomial<G>
52where
53 G: Sized + Neg<Output = G>,
54{
55 type Output = Self;
56 fn neg(self) -> Self::Output {
57 Polynomial {
58 coeff: self.coeff.into_iter().map(|v| -v).collect(),
59 }
60 }
61}
62
63impl<G> Neg for &Polynomial<G>
64where
65 G: Sized + for<'x> From<<&'x G as Neg>::Output>,
66 for<'x> &'x G: Neg,
67{
68 type Output = Polynomial<G>;
69 fn neg(self) -> Self::Output {
70 Polynomial {
71 coeff: self.coeff.iter().map(|v| G::from(-v)).collect(),
72 }
73 }
74}
75
76#[auto_ops]
77impl<G> SubAssign<&Polynomial<G>> for Polynomial<G>
78where
79 G: Sized + Zero + for<'x> SubAssign<&'x G>,
80{
81 fn sub_assign(&mut self, other: &Self) {
82 let len = self.len();
83 self.extend(other.len());
84 self.coeff
85 .iter_mut()
86 .zip(other.coeff.iter())
87 .for_each(|(l, r)| *l -= r);
88 if len == other.len() {
89 self.trim_zero()
90 }
91 }
92}
93
94fn mul_aux<R>(sum: &mut [R], coeff: &R, vec: &[R])
96where
97 R: Sized + Clone + for<'x> AddAssign<&'x R> + for<'x> MulAssign<&'x R>,
98{
99 sum.iter_mut().zip(vec.iter()).for_each(|(l, r)| {
100 let mut t = coeff.clone();
101 t *= r;
102 *l += &t
103 });
104}
105#[auto_ops]
106impl<R> Mul for &Polynomial<R>
107where
108 R: Sized + Clone + Zero + for<'x> AddAssign<&'x R> + for<'x> MulAssign<&'x R>,
109{
110 type Output = Polynomial<R>;
111 fn mul(self, other: Self) -> Self::Output {
112 if self.is_zero() || other.is_zero() {
113 return Polynomial::<R>::zero();
114 }
115 let mut coeff = vec![R::zero(); self.len() + other.len() - 1];
116 self.coeff
117 .iter()
118 .enumerate()
119 .for_each(|(i, c)| mul_aux::<R>(&mut coeff[i..], c, &other.coeff));
120 Polynomial::<R>::new(coeff) }
122}
123
124impl<R> One for Polynomial<R>
125where
126 R: Sized + Clone + Zero + for<'x> AddAssign<&'x R> + One + for<'x> MulAssign<&'x R>,
127{
128 fn one() -> Self {
129 polynomial![R::one()]
130 }
131}
132
133impl<R> Product for Polynomial<R>
134where
135 R: Sized + Clone + Zero + for<'x> AddAssign<&'x R> + One + for<'x> MulAssign<&'x R>,
136{
137 fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
138 iter.fold(Self::one(), Mul::<Polynomial<R>>::mul)
139 }
140}
141
142#[auto_ops]
144impl<K> Div for &Polynomial<K>
145where
146 K: Sized
147 + Clone
148 + Zero
149 + for<'x> AddAssign<&'x K>
150 + for<'x> SubAssign<&'x K>
151 + for<'x> MulAssign<&'x K>
152 + for<'x> DivAssign<&'x K>,
153{
154 type Output = Polynomial<K>;
155 fn div(self, other: Self) -> Self::Output {
156 let mut f = self.clone();
157 f.division(other)
158 }
159}
160
161#[auto_ops]
162impl<K> RemAssign<&Polynomial<K>> for Polynomial<K>
163where
164 K: Sized
165 + Clone
166 + Zero
167 + for<'x> AddAssign<&'x K>
168 + for<'x> SubAssign<&'x K>
169 + for<'x> MulAssign<&'x K>
170 + for<'x> DivAssign<&'x K>,
171{
172 fn rem_assign(&mut self, other: &Self) {
173 self.division(other);
174 }
175}
176
177#[auto_ops]
179impl<R> MulAssign<&R> for Polynomial<R>
180where
181 R: Sized + Zero + for<'x> MulAssign<&'x R>,
182{
183 fn mul_assign(&mut self, alpha: &R) {
184 self.coeff.iter_mut().for_each(|c| *c *= alpha);
185 self.trim_zero();
186 }
187}
188
189#[auto_ops]
190impl<R> DivAssign<&R> for Polynomial<R>
191where
192 R: Sized + for<'x> DivAssign<&'x R>,
193{
194 fn div_assign(&mut self, alpha: &R) {
195 self.coeff.iter_mut().for_each(|c| *c /= alpha);
196 }
197}
198
199impl<K> RingNormalize for Polynomial<K>
200where
201 K: Sized
202 + Clone
203 + Zero
204 + One
205 + for<'x> AddAssign<&'x K>
206 + for<'x> MulAssign<&'x K>
207 + for<'x> DivAssign<&'x K>,
208{
209 fn leading_unit(&self) -> Self {
210 if let Some(x) = self.lc() {
211 Self::from_monomial(x.clone(), 0)
212 } else {
213 Self::one()
214 }
215 }
216 fn normalize_mut(&mut self) {
217 self.monic();
218 }
219}