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#[derive(Debug, Clone)]
10#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
11pub struct Polynomial<N: ComplexField> {
12 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 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 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 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 pub fn order(&self) -> usize {
82 self.coefficients.len() - 1
83 }
84
85 pub fn get_coefficients(&self) -> Vec<N> {
87 let mut cln = self.coefficients.clone();
88 cln.reverse();
89 cln
90 }
91
92 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 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 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 pub fn evaluate_derivative(&self, x: N) -> (N, N) {
127 if self.coefficients.len() == 1 {
128 return (self.coefficients[0], N::zero());
129 }
130 let mut acc_eval = *self.coefficients.last().unwrap();
132 let mut acc_deriv = *self.coefficients.last().unwrap();
133 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 acc_eval = x * acc_eval + self.coefficients[0];
140
141 (acc_eval, acc_deriv)
142 }
143
144 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 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 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 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 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 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 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 let order = remainder.coefficients.len() - divisor.coefficients.len();
248 temp.coefficients = vec![N::zero(); order + 1];
250 temp.coefficients[order] =
251 *remainder.coefficients.last().unwrap() / *divisor.coefficients.last().unwrap();
252 quotient += &temp;
254 let padding = temp.coefficients.len() - 1;
256 temp = divisor
258 .coefficients
259 .iter()
260 .map(|c| *c * *temp.coefficients.last().unwrap())
261 .collect();
262 for _ in 0..padding {
264 temp.coefficients.insert(0, N::zero());
265 }
266 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 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 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 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 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 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 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 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
478fn 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
519impl<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 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 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 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 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 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 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 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}