1use std::ops::{Neg, Sub, SubAssign};
2
3use crate::Polynomial;
4
5impl Sub for Polynomial {
6 type Output = Self;
7 fn sub(mut self, rhs: Self) -> Self::Output {
8 if self.is_zero() {
9 rhs
10 } else if rhs.is_zero() {
11 self
12 } else {
13 for i in 0..=(std::cmp::max(self.degree(), rhs.degree())) {
14 if i > self.degree() {
15 self.coeffs.push(-rhs.coeffs[i as usize]);
18 } else if i > rhs.degree() {
19 break;
22 } else {
23 self.coeffs[i as usize] -= rhs.coeffs[i as usize];
25 }
26 }
27 self.reduce();
28 self
29 }
30 }
31}
32
33impl<'a> Sub<&'a Polynomial> for &'a Polynomial {
34 type Output = Polynomial;
35 fn sub(self, rhs: Self) -> Self::Output {
36 let mut coeffs = Vec::new();
37 for i in 0..=(std::cmp::max(self.degree(), rhs.degree())) {
38 if i > self.degree() {
39 coeffs.push(-rhs.coeffs[i as usize]);
40 } else if i > rhs.degree() {
41 coeffs.push(self.coeffs[i as usize]);
42 } else {
43 coeffs.push(self.coeffs[i as usize] - rhs.coeffs[i as usize]);
44 }
45 }
46 let mut output = Polynomial::new(coeffs);
47 output.reduce();
48 output
49 }
50}
51
52impl Sub<isize> for Polynomial {
53 type Output = Self;
54 fn sub(mut self, rhs: isize) -> Self::Output {
55 if self.is_zero() {
56 Polynomial::constant(-rhs)
57 } else if rhs == 0 {
58 self
59 } else {
60 self.coeffs[0] -= rhs;
61 self.reduce();
62 self
63 }
64 }
65}
66
67impl<'a> Sub<isize> for &'a Polynomial {
68 type Output = Polynomial;
69 fn sub(self, rhs: isize) -> Self::Output {
70 if self.is_zero() {
71 Polynomial::constant(-rhs)
72 } else if rhs == 0 {
73 self.clone()
74 } else {
75 let mut coeffs = self.coeffs.clone();
76 coeffs[0] -= rhs;
77 let mut output = Polynomial { coeffs };
78 output.reduce();
79 output
80 }
81 }
82}
83
84impl Neg for Polynomial {
85 type Output = Self;
86
87 fn neg(mut self) -> Self::Output {
88 for i in self.coeffs.iter_mut() {
89 *i = -*i;
90 }
91 self
92 }
93}
94
95impl Neg for &Polynomial {
96 type Output = Polynomial;
97
98 fn neg(self) -> Self::Output {
99 let mut coeffs = self.coeffs.clone();
100 for i in coeffs.iter_mut() {
101 *i = -*i;
102 }
103 let mut output = Polynomial { coeffs };
104 output.reduce();
105 output
106 }
107}
108
109impl SubAssign for Polynomial {
110 fn sub_assign(&mut self, rhs: Self) {
111 if self.is_zero() {
112 *self = -rhs;
113 } else if !rhs.is_zero() {
114 for i in 0..=(std::cmp::max(self.degree(), rhs.degree())) {
115 if i > self.degree() {
116 self.coeffs.push(-rhs.coeffs[i as usize]);
119 } else if i > rhs.degree() {
120 break;
123 } else {
124 self.coeffs[i as usize] -= rhs.coeffs[i as usize];
126 }
127 }
128 self.reduce();
129 }
130 }
131}
132
133impl<'a> SubAssign<&'a Polynomial> for Polynomial {
134 fn sub_assign(&mut self, rhs: &Self) {
135 if self.is_zero() {
136 *self = -rhs;
137 } else if !rhs.is_zero() {
138 for i in 0..=(std::cmp::max(self.degree(), rhs.degree())) {
139 if i > self.degree() {
140 self.coeffs.push(-rhs.coeffs[i as usize]);
143 } else if i > rhs.degree() {
144 break;
147 } else {
148 self.coeffs[i as usize] -= rhs.coeffs[i as usize];
150 }
151 }
152 self.reduce();
153 }
154 }
155}
156
157impl SubAssign<isize> for Polynomial {
158 fn sub_assign(&mut self, rhs: isize) {
159 if self.is_zero() {
160 self.coeffs.push(-rhs);
161 } else if rhs != 0 {
162 self.coeffs[0] -= rhs;
163 self.reduce();
164 }
165 }
166}