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