bacon_sci_1/polynomial/
mod.rs

1use crate::roots::newton_polynomial;
2use nalgebra::{ComplexField, RealField};
3use num_complex::Complex;
4use num_traits::{FromPrimitive, One, Zero};
5use std::collections::VecDeque;
6use std::{any::TypeId, f64, iter::FromIterator, ops};
7
8/// Polynomial on a ComplexField.
9#[derive(Debug, Clone)]
10#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
11pub struct Polynomial<N: ComplexField> {
12    // Index 0 is constant, 1 is linear, etc.
13    coefficients: Vec<N>,
14    tolerance: <N as ComplexField>::RealField,
15}
16
17#[macro_export]
18macro_rules! polynomial {
19  ( $( $x:expr ),* ) => {
20    $crate::polynomial::Polynomial::from_slice(&[$($x),*])
21  }
22}
23
24impl<N: ComplexField> Polynomial<N> {
25    /// Returns the zero polynomial on a given field
26    pub fn new() -> Self {
27        Polynomial {
28            coefficients: vec![N::from_f64(0.0).unwrap()],
29            tolerance: N::RealField::from_f64(1e-10).unwrap(),
30        }
31    }
32
33    pub fn with_tolerance(tolerance: <N as ComplexField>::RealField) -> Result<Self, String> {
34        if !tolerance.is_sign_positive() {
35            return Err("Polynomial with_tolerance: Tolerance must be positive".to_owned());
36        }
37        Ok(Polynomial {
38            coefficients: vec![N::from_f64(0.0).unwrap()],
39            tolerance,
40        })
41    }
42
43    /// Returns the zero polynomial on a given field with preallocated memory
44    pub fn with_capacity(capacity: usize) -> Self {
45        let mut coefficients = Vec::with_capacity(capacity);
46        coefficients.push(N::zero());
47        coefficients.iter().copied().collect()
48    }
49
50    /// Create a polynomial from a slice, with the first element of the slice being the highest power
51    pub fn from_slice(data: &[N]) -> Self {
52        if data.is_empty() {
53            return Polynomial {
54                coefficients: vec![N::zero()],
55                tolerance: N::RealField::from_f64(1e-10).unwrap(),
56            };
57        }
58        Polynomial {
59            coefficients: data.iter().rev().copied().collect(),
60            tolerance: N::RealField::from_f64(1e-10).unwrap(),
61        }
62    }
63
64    pub fn set_tolerance(
65        &mut self,
66        tolerance: <N as ComplexField>::RealField,
67    ) -> Result<(), String> {
68        if !tolerance.is_sign_positive() {
69            return Err("Polynomial set_tolerance: tolerance must be positive".to_owned());
70        }
71
72        self.tolerance = tolerance;
73        Ok(())
74    }
75
76    pub fn get_tolerance(&self) -> <N as ComplexField>::RealField {
77        self.tolerance
78    }
79
80    /// Get the order of the polynomial
81    pub fn order(&self) -> usize {
82        self.coefficients.len() - 1
83    }
84
85    /// Returns the coefficients in the correct order to recreate the polynomial with Polynomial::from_slice(data: &[N]);
86    pub fn get_coefficients(&self) -> Vec<N> {
87        let mut cln = self.coefficients.clone();
88        cln.reverse();
89        cln
90    }
91
92    /// Get the coefficient of a power
93    pub fn get_coefficient(&self, ind: usize) -> N {
94        if ind >= self.coefficients.len() {
95            N::zero()
96        } else {
97            self.coefficients[ind]
98        }
99    }
100
101    /// Make a polynomial complex
102    pub fn make_complex(&self) -> Polynomial<Complex<<N as ComplexField>::RealField>> {
103        let mut coefficients: Vec<Complex<N::RealField>> =
104            Vec::with_capacity(self.coefficients.len());
105        for val in &self.coefficients {
106            coefficients.push(Complex::<N::RealField>::new(val.real(), val.imaginary()));
107        }
108        Polynomial {
109            coefficients,
110            tolerance: self.tolerance,
111        }
112    }
113
114    /// Evaluate a polynomial at a value
115    pub fn evaluate(&self, x: N) -> N {
116        let mut acc = *self.coefficients.last().unwrap();
117        for val in self.coefficients.iter().rev().skip(1) {
118            acc *= x;
119            acc += *val;
120        }
121
122        acc
123    }
124
125    /// Evaluate a polynomial and its derivative at a value
126    pub fn evaluate_derivative(&self, x: N) -> (N, N) {
127        if self.coefficients.len() == 1 {
128            return (self.coefficients[0], N::zero());
129        }
130        // Start with biggest coefficients
131        let mut acc_eval = *self.coefficients.last().unwrap();
132        let mut acc_deriv = *self.coefficients.last().unwrap();
133        // For every coefficient except the constant and largest
134        for val in self.coefficients.iter().skip(1).rev().skip(1) {
135            acc_eval = acc_eval * x + *val;
136            acc_deriv = acc_deriv * x + acc_eval;
137        }
138        // Do the constant for the polynomial evaluation
139        acc_eval = x * acc_eval + self.coefficients[0];
140
141        (acc_eval, acc_deriv)
142    }
143
144    /// Set a coefficient of a power in the polynomial
145    pub fn set_coefficient(&mut self, power: u32, coefficient: N) {
146        while (power + 1) > self.coefficients.len() as u32 {
147            self.coefficients.push(N::from_f64(0.0).unwrap());
148        }
149        self.coefficients[power as usize] = coefficient;
150    }
151
152    /// Remove the coefficient of a power in the polynomial
153    pub fn purge_coefficient(&mut self, power: usize) {
154        match self.coefficients.len() {
155            len if len == power && len != 1 => {
156                self.coefficients.pop();
157            }
158            _ => {
159                self.coefficients[power] = N::from_f64(0.0).unwrap();
160            }
161        };
162    }
163
164    /// Remove all leading 0 coefficients
165    pub fn purge_leading(&mut self) {
166        while self.coefficients.len() > 1
167            && self.coefficients.last().unwrap().real().abs() <= self.tolerance
168            && self.coefficients.last().unwrap().imaginary().abs() <= self.tolerance
169        {
170            self.coefficients.pop();
171        }
172    }
173
174    /// Get the derivative of the polynomial
175    pub fn derivative(&self) -> Self {
176        if self.coefficients.len() == 1 {
177            return Polynomial {
178                coefficients: vec![N::from_f64(0.0).unwrap()],
179                tolerance: self.tolerance,
180            };
181        }
182
183        let mut deriv_coeff = Vec::with_capacity(self.coefficients.len() - 1);
184
185        for (i, val) in self.coefficients.iter().enumerate().skip(1) {
186            deriv_coeff.push(N::from_f64(i as f64).unwrap() * *val);
187        }
188
189        Polynomial {
190            coefficients: deriv_coeff,
191            tolerance: self.tolerance,
192        }
193    }
194
195    /// Get the antiderivative of the polynomial with specified constant
196    pub fn antiderivative(&self, constant: N) -> Self {
197        let mut coefficients = Vec::with_capacity(self.coefficients.len() + 1);
198        coefficients.push(constant);
199        for (ind, val) in self.coefficients.iter().enumerate() {
200            coefficients.push(*val * N::from_f64(1.0 / (ind + 1) as f64).unwrap());
201        }
202        Polynomial {
203            coefficients,
204            tolerance: self.tolerance,
205        }
206    }
207
208    /// Integrate this polynomial between to starting points
209    pub fn integrate(&self, lower: N, upper: N) -> N {
210        let poly_anti = self.antiderivative(N::zero());
211        poly_anti.evaluate(upper) - poly_anti.evaluate(lower)
212    }
213
214    /// Divide this polynomial by another, getting a quotient and remainder, using tol to check for 0
215    pub fn divide(&self, divisor: &Polynomial<N>) -> Result<(Self, Self), String> {
216        if divisor.coefficients.len() == 1
217            && divisor.coefficients[0].real().abs() < self.tolerance
218            && divisor.coefficients[0].imaginary().abs() < self.tolerance
219        {
220            return Err("Polynomial division: Can not divide by 0".to_owned());
221        }
222
223        let mut quotient = Polynomial::with_tolerance(self.tolerance)?;
224        let mut remainder = Polynomial::from_iter(self.coefficients.iter().copied());
225        remainder.tolerance = self.tolerance;
226        remainder.purge_leading();
227        let mut temp = Polynomial::new();
228
229        if divisor.coefficients.len() == 1 {
230            let idivisor = N::from_f64(1.0).unwrap() / divisor.coefficients[0];
231            return Ok((
232                remainder
233                    .coefficients
234                    .iter()
235                    .map(|c| *c * idivisor)
236                    .collect(),
237                Polynomial::new(),
238            ));
239        }
240
241        while remainder.coefficients.len() >= divisor.coefficients.len()
242            && !(remainder.coefficients.len() == 1
243                && remainder.coefficients[0].real().abs() < self.tolerance
244                && remainder.coefficients[0].imaginary().abs() < self.tolerance)
245        {
246            // Get the power left over from dividing lead terms
247            let order = remainder.coefficients.len() - divisor.coefficients.len();
248            // Make a vector that is just the lead coefficients divided at the right power
249            temp.coefficients = vec![N::zero(); order + 1];
250            temp.coefficients[order] =
251                *remainder.coefficients.last().unwrap() / *divisor.coefficients.last().unwrap();
252            // Add the division to the quotient
253            quotient += &temp;
254            // Get the amount to shift divisor by
255            let padding = temp.coefficients.len() - 1;
256            // Multiply every coefficient in divisor by temp's coefficient
257            temp = divisor
258                .coefficients
259                .iter()
260                .map(|c| *c * *temp.coefficients.last().unwrap())
261                .collect();
262            // Shift the coefficients to multiply by the right power of x
263            for _ in 0..padding {
264                temp.coefficients.insert(0, N::zero());
265            }
266            // remainder -= temp x d;
267            remainder -= &temp;
268            while remainder.coefficients.len() > 1
269                && remainder.coefficients.last().unwrap().real().abs() < self.tolerance
270                && remainder.coefficients.last().unwrap().imaginary().abs() < self.tolerance
271            {
272                remainder.coefficients.pop();
273            }
274        }
275
276        Ok((quotient, remainder))
277    }
278
279    /// Get the n (possibly including repeats) of the polynomial given n using Laguerre's method
280    pub fn roots(
281        &self,
282        tol: <N as ComplexField>::RealField,
283        n_max: usize,
284    ) -> Result<VecDeque<Complex<<N as ComplexField>::RealField>>, String> {
285        if self.coefficients.len() > 1
286            && self.coefficients.last().unwrap().real().abs() < tol
287            && self.coefficients.last().unwrap().imaginary().abs() < tol
288        {
289            return Err("Polynomial roots: Leading 0 coefficient!".to_owned());
290        }
291
292        match self.coefficients.len() {
293            1 => {
294                // Only constant, root only if constant is 0
295                if self.coefficients[0].real().abs() < tol
296                    && self.coefficients[0].imaginary().abs() < tol
297                {
298                    return Ok(VecDeque::from(vec![Complex::<N::RealField>::zero()]));
299                }
300                return Err("Polynomial roots: Non-zero constant has no root".to_owned());
301            }
302            2 => {
303                // Linear term, root easy
304                let division = -self.coefficients[0] / self.coefficients[1];
305                return Ok(VecDeque::from(vec![Complex::<N::RealField>::new(
306                    division.real(),
307                    division.imaginary(),
308                )]));
309            }
310            3 => {
311                // Use quadratic formula and return in right order
312                let determinant = self.coefficients[1].powi(2)
313                    - N::from_f64(4.0).unwrap() * self.coefficients[2] * self.coefficients[0];
314                let determinant =
315                    Complex::<N::RealField>::new(determinant.real(), determinant.imaginary())
316                        .sqrt();
317                let leading = self.coefficients[2];
318                let leading = Complex::<N::RealField>::new(leading.real(), leading.imaginary());
319                let leading = leading
320                    * Complex::<N::RealField>::new(
321                        N::from_f64(2.0).unwrap().real(),
322                        N::zero().real(),
323                    );
324                let secondary = self.coefficients[1];
325                let secondary =
326                    Complex::<N::RealField>::new(secondary.real(), secondary.imaginary());
327                let positive = (-secondary + determinant) / leading;
328                let negative = (-secondary - determinant) / leading;
329                return Ok(VecDeque::from(vec![positive, negative]));
330            }
331            _ => {}
332        }
333
334        let complex = self.make_complex();
335        let derivative = complex.derivative();
336
337        let mut guess = Complex::<N::RealField>::zero();
338        let mut k = 0;
339        'out: while k < n_max {
340            let val = complex.evaluate(guess);
341            if val.abs() < tol {
342                break 'out;
343            }
344            let (deriv, second_deriv) = derivative.evaluate_derivative(guess);
345            let deriv_quotient = deriv / val;
346            let g_sq = deriv_quotient.powi(2);
347            let second_deriv_quotient = g_sq - second_deriv / val;
348            let order = Complex::<N::RealField>::from_usize(self.coefficients.len() - 1).unwrap();
349            let sqrt = ((order - Complex::<N::RealField>::one())
350                * (order * second_deriv_quotient - g_sq))
351                .sqrt();
352            let plus = deriv_quotient + sqrt;
353            let minus = deriv_quotient - sqrt;
354            let a = if plus.abs() > minus.abs() {
355                order / plus
356            } else {
357                order / minus
358            };
359            guess -= a;
360            k += 1;
361        }
362        if k == n_max {
363            return Err("Polynomial roots: maximum iterations exceeded".to_owned());
364        }
365
366        let divisor = polynomial![Complex::<N::RealField>::one(), -guess];
367        let (quotient, _) = complex.divide(&divisor)?;
368        let mut roots = quotient.roots(tol, n_max)?;
369        roots.push_front(guess);
370
371        let mut corrected_roots = VecDeque::with_capacity(roots.len());
372        for root in roots.iter() {
373            corrected_roots.push_back(newton_polynomial(*root, &complex, tol, n_max)?);
374        }
375
376        Ok(corrected_roots)
377    }
378
379    // Pad to the smallest power of two less than or equal to size
380    fn pad_power_of_two(&mut self, size: usize) {
381        let mut power: usize = 1;
382        while power < size {
383            power <<= 1;
384        }
385        while self.coefficients.len() < power {
386            self.coefficients.push(N::zero());
387        }
388    }
389
390    /// Get the polynomial in point form evaluated at roots of unity at k points
391    /// where k is the smallest power of 2 greater than or equal to size
392    pub fn dft(&self, size: usize) -> Vec<Complex<<N as ComplexField>::RealField>> {
393        let mut poly = self.make_complex();
394        poly.pad_power_of_two(size);
395        let mut working = bit_reverse_copy(&poly.coefficients);
396        let len = working.len();
397        for s in 1..(len as f64).log2() as usize + 1 {
398            let m = 1 << s;
399            let angle = 2.0 * f64::consts::PI / m as f64;
400            let angle = N::RealField::from_f64(angle).unwrap();
401            let root_of_unity = Complex::<N::RealField>::new(angle.cos(), angle.sin());
402            let mut w = Complex::<N::RealField>::new(N::RealField::one(), N::RealField::zero());
403            for j in 0..m / 2 {
404                for k in (j..len).step_by(m) {
405                    let temp = w * working[k + m / 2];
406                    let u = working[k];
407                    working[k] = u + temp;
408                    working[k + m / 2] = u - temp;
409                }
410                w *= root_of_unity;
411            }
412        }
413        working
414    }
415
416    // Assumes power of 2
417    pub fn idft(
418        vec: &[Complex<<N as ComplexField>::RealField>],
419        tol: <N as ComplexField>::RealField,
420    ) -> Self {
421        let mut working = bit_reverse_copy(vec);
422        let len = working.len();
423        for s in 1..(len as f64).log2() as usize + 1 {
424            let m = 1 << s;
425            let angle = -2.0 * f64::consts::PI / m as f64;
426            let angle = N::RealField::from_f64(angle).unwrap();
427            let root_of_unity = Complex::<N::RealField>::new(angle.cos(), angle.sin());
428            let mut w = Complex::<N::RealField>::new(N::RealField::one(), N::RealField::zero());
429            for j in 0..m / 2 {
430                for k in (j..len).step_by(m) {
431                    let temp = w * working[k + m / 2];
432                    let u = working[k];
433                    working[k] = u + temp;
434                    working[k + m / 2] = u - temp;
435                }
436                w *= root_of_unity;
437            }
438        }
439        let ilen = Complex::<N::RealField>::new(
440            N::from_f64(1.0 / len as f64).unwrap().real(),
441            N::zero().real(),
442        );
443        for val in &mut working {
444            *val *= ilen;
445        }
446        let coefficients = if TypeId::of::<N::RealField>() == TypeId::of::<N>() {
447            working
448                .iter()
449                .map(|c| N::from_real(c.re))
450                .collect::<Vec<_>>()
451        } else {
452            working
453                .iter()
454                .map(|c| N::from_real(c.re) + (-N::one()).sqrt() * N::from_real(c.im))
455                .collect::<Vec<_>>()
456        };
457
458        let mut poly = Polynomial {
459            coefficients,
460            tolerance: tol,
461        };
462        poly.purge_leading();
463        poly
464    }
465}
466
467fn bit_reverse(mut k: usize, num_bits: usize) -> usize {
468    let mut result: usize = 0;
469    for _ in 0..num_bits {
470        result |= k & 1;
471        result <<= 1;
472        k >>= 1;
473    }
474    result >>= 1;
475    result
476}
477
478// Assumes vec is a power of 2 length
479fn bit_reverse_copy<N: RealField>(vec: &[Complex<N>]) -> Vec<Complex<N>> {
480    let len = vec.len();
481    let mut result = vec![Complex::new(N::zero(), N::zero()); len];
482    let num_bits = (len as f64).log2() as usize;
483    for k in 0..len {
484        result[bit_reverse(k, num_bits)] = vec[k];
485    }
486    result
487}
488
489impl<N: ComplexField> FromIterator<N> for Polynomial<N> {
490    fn from_iter<I: IntoIterator<Item = N>>(iter: I) -> Polynomial<N> {
491        Polynomial {
492            coefficients: Vec::from_iter(iter),
493            tolerance: N::RealField::from_f64(1e-10).unwrap(),
494        }
495    }
496}
497
498impl<N: ComplexField> Default for Polynomial<N> {
499    fn default() -> Self {
500        Self::new()
501    }
502}
503
504impl<N: ComplexField> Zero for Polynomial<N> {
505    fn zero() -> Polynomial<N> {
506        Polynomial::new()
507    }
508
509    fn is_zero(&self) -> bool {
510        for val in &self.coefficients {
511            if !val.is_zero() {
512                return false;
513            }
514        }
515        true
516    }
517}
518
519// Operator overloading
520
521impl<N: ComplexField> ops::Add<N> for Polynomial<N> {
522    type Output = Polynomial<N>;
523
524    fn add(mut self, rhs: N) -> Polynomial<N> {
525        self.coefficients[0] += rhs;
526        self
527    }
528}
529
530impl<N: ComplexField> ops::Add<N> for &Polynomial<N> {
531    type Output = Polynomial<N>;
532
533    fn add(self, rhs: N) -> Polynomial<N> {
534        let mut coefficients = Vec::from(self.coefficients.as_slice());
535        coefficients[0] += rhs;
536        Polynomial {
537            coefficients,
538            tolerance: self.tolerance,
539        }
540    }
541}
542
543impl<N: ComplexField> ops::Add<Polynomial<N>> for Polynomial<N> {
544    type Output = Polynomial<N>;
545
546    fn add(mut self, rhs: Polynomial<N>) -> Polynomial<N> {
547        let min_order = self.coefficients.len().min(rhs.coefficients.len());
548        for (ind, val) in self.coefficients.iter_mut().take(min_order).enumerate() {
549            *val += rhs.coefficients[ind];
550        }
551
552        for val in rhs.coefficients.iter().skip(min_order) {
553            self.coefficients.push(*val);
554        }
555
556        self
557    }
558}
559
560impl<N: ComplexField> ops::Add<&Polynomial<N>> for Polynomial<N> {
561    type Output = Polynomial<N>;
562
563    fn add(mut self, rhs: &Polynomial<N>) -> Polynomial<N> {
564        let min_order = self.coefficients.len().min(rhs.coefficients.len());
565        for (ind, val) in self.coefficients.iter_mut().take(min_order).enumerate() {
566            *val += rhs.coefficients[ind];
567        }
568
569        // Will only run if rhs has higher order
570        for val in rhs.coefficients.iter().skip(min_order) {
571            self.coefficients.push(*val);
572        }
573
574        self
575    }
576}
577
578impl<N: ComplexField> ops::Add<Polynomial<N>> for &Polynomial<N> {
579    type Output = Polynomial<N>;
580
581    fn add(self, rhs: Polynomial<N>) -> Polynomial<N> {
582        let min_order = self.coefficients.len().min(rhs.coefficients.len());
583        let mut coefficients =
584            Vec::with_capacity(self.coefficients.len().max(rhs.coefficients.len()));
585        for (ind, val) in self.coefficients.iter().take(min_order).enumerate() {
586            coefficients.push(*val + rhs.coefficients[ind]);
587        }
588
589        // Only one loop will run
590        for val in self.coefficients.iter().skip(min_order) {
591            coefficients.push(*val);
592        }
593
594        for val in rhs.coefficients.iter().skip(min_order) {
595            coefficients.push(*val);
596        }
597
598        Polynomial {
599            coefficients,
600            tolerance: self.tolerance,
601        }
602    }
603}
604
605impl<N: ComplexField> ops::Add<&Polynomial<N>> for &Polynomial<N> {
606    type Output = Polynomial<N>;
607
608    fn add(self, rhs: &Polynomial<N>) -> Polynomial<N> {
609        let min_order = self.coefficients.len().min(rhs.coefficients.len());
610        let mut coefficients =
611            Vec::with_capacity(self.coefficients.len().max(rhs.coefficients.len()));
612        for (ind, val) in self.coefficients.iter().take(min_order).enumerate() {
613            coefficients.push(*val + rhs.coefficients[ind]);
614        }
615
616        // Only one loop will run
617        for val in self.coefficients.iter().skip(min_order) {
618            coefficients.push(*val);
619        }
620
621        for val in rhs.coefficients.iter().skip(min_order) {
622            coefficients.push(*val);
623        }
624
625        Polynomial {
626            coefficients,
627            tolerance: self.tolerance,
628        }
629    }
630}
631
632impl<N: ComplexField> ops::AddAssign<N> for Polynomial<N> {
633    fn add_assign(&mut self, rhs: N) {
634        self.coefficients[0] += rhs;
635    }
636}
637
638impl<N: ComplexField> ops::AddAssign<Polynomial<N>> for Polynomial<N> {
639    fn add_assign(&mut self, rhs: Polynomial<N>) {
640        let min_order = self.coefficients.len().min(rhs.coefficients.len());
641        for (ind, val) in self.coefficients.iter_mut().take(min_order).enumerate() {
642            *val += rhs.coefficients[ind];
643        }
644
645        for val in rhs.coefficients.iter().skip(min_order) {
646            self.coefficients.push(*val);
647        }
648    }
649}
650
651impl<N: ComplexField> ops::AddAssign<&Polynomial<N>> for Polynomial<N> {
652    fn add_assign(&mut self, rhs: &Polynomial<N>) {
653        let min_order = self.coefficients.len().min(rhs.coefficients.len());
654        for (ind, val) in self.coefficients.iter_mut().take(min_order).enumerate() {
655            *val += rhs.coefficients[ind];
656        }
657
658        for val in rhs.coefficients.iter().skip(min_order) {
659            self.coefficients.push(*val);
660        }
661    }
662}
663
664impl<N: ComplexField> ops::Sub<N> for Polynomial<N> {
665    type Output = Polynomial<N>;
666
667    fn sub(mut self, rhs: N) -> Polynomial<N> {
668        self.coefficients[0] -= rhs;
669        self
670    }
671}
672
673impl<N: ComplexField> ops::Sub<N> for &Polynomial<N> {
674    type Output = Polynomial<N>;
675
676    fn sub(self, rhs: N) -> Polynomial<N> {
677        let mut coefficients = Vec::from(self.coefficients.as_slice());
678        coefficients[0] -= rhs;
679        Polynomial {
680            coefficients,
681            tolerance: self.tolerance,
682        }
683    }
684}
685
686impl<N: ComplexField> ops::Sub<Polynomial<N>> for Polynomial<N> {
687    type Output = Polynomial<N>;
688
689    fn sub(mut self, rhs: Polynomial<N>) -> Polynomial<N> {
690        let min_order = self.coefficients.len().min(rhs.coefficients.len());
691        for (ind, val) in self.coefficients.iter_mut().take(min_order).enumerate() {
692            *val -= rhs.coefficients[ind];
693        }
694
695        for val in rhs.coefficients.iter().skip(min_order) {
696            self.coefficients.push(-*val);
697        }
698
699        self
700    }
701}
702
703impl<N: ComplexField> ops::Sub<Polynomial<N>> for &Polynomial<N> {
704    type Output = Polynomial<N>;
705
706    fn sub(self, rhs: Polynomial<N>) -> Polynomial<N> {
707        let min_order = self.coefficients.len().min(rhs.coefficients.len());
708        let mut coefficients =
709            Vec::with_capacity(self.coefficients.len().max(rhs.coefficients.len()));
710        for (ind, val) in self.coefficients.iter().take(min_order).enumerate() {
711            coefficients.push(*val - rhs.coefficients[ind]);
712        }
713
714        // Only one for loop runs
715        for val in self.coefficients.iter().skip(min_order) {
716            coefficients.push(*val);
717        }
718
719        for val in rhs.coefficients.iter().skip(min_order) {
720            coefficients.push(-*val);
721        }
722
723        Polynomial {
724            coefficients,
725            tolerance: self.tolerance,
726        }
727    }
728}
729
730impl<N: ComplexField> ops::Sub<&Polynomial<N>> for Polynomial<N> {
731    type Output = Polynomial<N>;
732
733    fn sub(mut self, rhs: &Polynomial<N>) -> Polynomial<N> {
734        let min_order = self.coefficients.len().min(rhs.coefficients.len());
735        for (ind, val) in self.coefficients.iter_mut().take(min_order).enumerate() {
736            *val -= rhs.coefficients[ind];
737        }
738
739        for val in rhs.coefficients.iter().skip(min_order) {
740            self.coefficients.push(-*val);
741        }
742
743        self
744    }
745}
746
747impl<N: ComplexField> ops::Sub<&Polynomial<N>> for &Polynomial<N> {
748    type Output = Polynomial<N>;
749
750    fn sub(self, rhs: &Polynomial<N>) -> Polynomial<N> {
751        let min_order = self.coefficients.len().min(rhs.coefficients.len());
752        let mut coefficients =
753            Vec::with_capacity(self.coefficients.len().max(rhs.coefficients.len()));
754        for (ind, val) in self.coefficients.iter().take(min_order).enumerate() {
755            coefficients.push(*val - rhs.coefficients[ind]);
756        }
757
758        // Only one for loop runs
759        for val in self.coefficients.iter().skip(min_order) {
760            coefficients.push(*val);
761        }
762
763        for val in rhs.coefficients.iter().skip(min_order) {
764            coefficients.push(-*val);
765        }
766
767        Polynomial {
768            coefficients,
769            tolerance: self.tolerance,
770        }
771    }
772}
773
774impl<N: ComplexField> ops::SubAssign<N> for Polynomial<N> {
775    fn sub_assign(&mut self, rhs: N) {
776        self.coefficients[0] -= rhs;
777    }
778}
779
780impl<N: ComplexField> ops::SubAssign<Polynomial<N>> for Polynomial<N> {
781    fn sub_assign(&mut self, rhs: Polynomial<N>) {
782        let min_order = self.coefficients.len().min(rhs.coefficients.len());
783        for (ind, val) in self.coefficients.iter_mut().take(min_order).enumerate() {
784            *val -= rhs.coefficients[ind];
785        }
786
787        for val in rhs.coefficients.iter().skip(min_order) {
788            self.coefficients.push(-*val);
789        }
790    }
791}
792
793impl<N: ComplexField> ops::SubAssign<&Polynomial<N>> for Polynomial<N> {
794    fn sub_assign(&mut self, rhs: &Polynomial<N>) {
795        let min_order = self.coefficients.len().min(rhs.coefficients.len());
796        for (ind, val) in self.coefficients.iter_mut().take(min_order).enumerate() {
797            *val -= rhs.coefficients[ind];
798        }
799
800        for val in rhs.coefficients.iter().skip(min_order) {
801            self.coefficients.push(-*val);
802        }
803    }
804}
805
806impl<N: ComplexField> ops::Mul<N> for Polynomial<N> {
807    type Output = Polynomial<N>;
808
809    fn mul(mut self, rhs: N) -> Polynomial<N> {
810        for val in &mut self.coefficients {
811            *val *= rhs;
812        }
813        self
814    }
815}
816
817impl<N: ComplexField> ops::Mul<N> for &Polynomial<N> {
818    type Output = Polynomial<N>;
819
820    fn mul(self, rhs: N) -> Polynomial<N> {
821        let mut coefficients = Vec::with_capacity(self.coefficients.len());
822        for val in &self.coefficients {
823            coefficients.push(*val * rhs);
824        }
825        Polynomial {
826            coefficients,
827            tolerance: self.tolerance,
828        }
829    }
830}
831
832fn multiply<N: ComplexField>(lhs: &Polynomial<N>, rhs: &Polynomial<N>) -> Polynomial<N> {
833    // Do scalar multiplication if one side has no powers
834    if rhs.coefficients.len() == 1 {
835        return lhs * rhs.coefficients[0];
836    }
837    if lhs.coefficients.len() == 1 {
838        return rhs * lhs.coefficients[0];
839    }
840
841    // Special case linear term multiplication
842    if rhs.coefficients.len() == 2 {
843        let mut shifted = lhs * rhs.coefficients[1];
844        shifted.coefficients.insert(0, N::zero());
845        return shifted + lhs * rhs.coefficients[0];
846    }
847    if lhs.coefficients.len() == 2 {
848        let mut shifted = rhs * lhs.coefficients[1];
849        shifted.coefficients.insert(0, N::zero());
850        return shifted + rhs * lhs.coefficients[0];
851    }
852
853    let bound = lhs.coefficients.len().max(rhs.coefficients.len()) * 2;
854    let left_points = lhs.dft(bound);
855    let right_points = rhs.dft(bound);
856    let product_points: Vec<_> = left_points
857        .iter()
858        .zip(right_points.iter())
859        .map(|(l_p, r_p)| *l_p * r_p)
860        .collect();
861    Polynomial::<N>::idft(&product_points, lhs.tolerance)
862}
863
864impl<N: ComplexField> ops::Mul<Polynomial<N>> for Polynomial<N> {
865    type Output = Polynomial<N>;
866
867    fn mul(self, rhs: Polynomial<N>) -> Polynomial<N> {
868        multiply(&self, &rhs)
869    }
870}
871
872impl<N: ComplexField> ops::Mul<&Polynomial<N>> for Polynomial<N> {
873    type Output = Polynomial<N>;
874
875    fn mul(self, rhs: &Polynomial<N>) -> Polynomial<N> {
876        multiply(&self, &rhs)
877    }
878}
879
880impl<N: ComplexField> ops::Mul<Polynomial<N>> for &Polynomial<N> {
881    type Output = Polynomial<N>;
882
883    fn mul(self, rhs: Polynomial<N>) -> Polynomial<N> {
884        multiply(&self, &rhs)
885    }
886}
887
888impl<N: ComplexField> ops::Mul<&Polynomial<N>> for &Polynomial<N> {
889    type Output = Polynomial<N>;
890
891    fn mul(self, rhs: &Polynomial<N>) -> Polynomial<N> {
892        multiply(&self, &rhs)
893    }
894}
895
896impl<N: ComplexField> ops::MulAssign<N> for Polynomial<N> {
897    fn mul_assign(&mut self, rhs: N) {
898        for val in self.coefficients.iter_mut() {
899            *val *= rhs;
900        }
901    }
902}
903
904impl<N: ComplexField> ops::MulAssign<Polynomial<N>> for Polynomial<N> {
905    fn mul_assign(&mut self, rhs: Polynomial<N>) {
906        self.coefficients = multiply(&self, &rhs).coefficients;
907    }
908}
909
910impl<N: ComplexField> ops::MulAssign<&Polynomial<N>> for Polynomial<N> {
911    fn mul_assign(&mut self, rhs: &Polynomial<N>) {
912        self.coefficients = multiply(&self, &rhs).coefficients;
913    }
914}
915
916impl<N: ComplexField> ops::Div<N> for Polynomial<N> {
917    type Output = Polynomial<N>;
918
919    fn div(mut self, rhs: N) -> Polynomial<N> {
920        for val in &mut self.coefficients {
921            *val /= rhs;
922        }
923        self
924    }
925}
926
927impl<N: ComplexField> ops::Div<N> for &Polynomial<N> {
928    type Output = Polynomial<N>;
929
930    fn div(self, rhs: N) -> Polynomial<N> {
931        let mut coefficients = Vec::from(self.coefficients.as_slice());
932        for val in &mut coefficients {
933            *val /= rhs;
934        }
935        Polynomial {
936            coefficients,
937            tolerance: self.tolerance,
938        }
939    }
940}
941
942impl<N: ComplexField> ops::DivAssign<N> for Polynomial<N> {
943    fn div_assign(&mut self, rhs: N) {
944        for val in &mut self.coefficients {
945            *val /= rhs;
946        }
947    }
948}
949
950impl<N: ComplexField> ops::Neg for Polynomial<N> {
951    type Output = Polynomial<N>;
952
953    fn neg(mut self) -> Polynomial<N> {
954        for val in &mut self.coefficients {
955            *val = -*val;
956        }
957        self
958    }
959}
960
961impl<N: ComplexField> ops::Neg for &Polynomial<N> {
962    type Output = Polynomial<N>;
963
964    fn neg(self) -> Polynomial<N> {
965        Polynomial {
966            coefficients: self.coefficients.iter().map(|c| -*c).collect(),
967            tolerance: self.tolerance,
968        }
969    }
970}
971
972impl<N: ComplexField> From<N> for Polynomial<N> {
973    fn from(n: N) -> Polynomial<N> {
974        polynomial![n]
975    }
976}
977
978impl<N: RealField> From<Polynomial<N>> for Polynomial<Complex<N>> {
979    fn from(poly: Polynomial<N>) -> Polynomial<Complex<N>> {
980        poly.make_complex()
981    }
982}