1use crate::Polynomial;
2
3use core::ops::{Neg, Sub, SubAssign};
4use num::Zero;
5
6impl<T> Sub<Polynomial<T>> for Polynomial<T>
7where
8 T: for<'r> SubAssign<&'r T> + Zero,
9{
10 type Output = Polynomial<T>;
11
12 fn sub(self, rhs: Polynomial<T>) -> Polynomial<T> {
13 let mut ret = self;
14 ret -= &rhs;
15 ret
16 }
17}
18
19impl<T> Sub<&Polynomial<T>> for Polynomial<T>
20where
21 T: for<'r> SubAssign<&'r T> + Zero,
22{
23 type Output = Polynomial<T>;
24
25 fn sub(self, rhs: &Polynomial<T>) -> Polynomial<T> {
26 let mut ret = self;
27 ret -= rhs;
28 ret
29 }
30}
31
32impl<T> Sub<Polynomial<T>> for &Polynomial<T>
33where
34 T: for<'r> SubAssign<&'r T> + Zero + Clone,
35{
36 type Output = Polynomial<T>;
37
38 fn sub(self, rhs: Polynomial<T>) -> Polynomial<T> {
39 let mut ret = self.clone();
40 ret -= &rhs;
41 ret
42 }
43}
44
45impl<T> Sub<&Polynomial<T>> for &Polynomial<T>
46where
47 T: for<'r> SubAssign<&'r T> + Zero + Clone,
48{
49 type Output = Polynomial<T>;
50
51 fn sub(self, rhs: &Polynomial<T>) -> Polynomial<T> {
52 let mut ret = self.clone();
53 ret -= rhs;
54 ret
55 }
56}
57
58impl<T> SubAssign<Polynomial<T>> for Polynomial<T>
59where
60 T: for<'r> SubAssign<&'r T> + Zero,
61{
62 fn sub_assign(&mut self, rhs: Polynomial<T>) {
63 self.sub_assign(&rhs);
64 }
65}
66
67impl<T> SubAssign<&Polynomial<T>> for Polynomial<T>
68where
69 T: for<'r> SubAssign<&'r T> + Zero,
70{
71 fn sub_assign(&mut self, rhs: &Polynomial<T>) {
72 if self.rev_coeffs.len() < rhs.rev_coeffs.len() {
73 #[allow(clippy::suspicious_op_assign_impl)]
75 let num_add = rhs.rev_coeffs.len() - self.rev_coeffs.len();
76 self.rev_coeffs.reserve(num_add);
77 for _ in 0..num_add {
78 self.rev_coeffs.push(T::zero());
79 }
80 }
82 self.rev_coeffs
83 .iter_mut()
84 .zip(rhs.rev_coeffs.iter())
85 .for_each(|(l, r)| *l -= r);
86 self.fixup_coefficients();
87 }
88}
89
90impl<T> Neg for Polynomial<T>
91where
92 T: Zero,
93 for<'l> &'l T: Neg<Output = T>,
94{
95 type Output = Polynomial<T>;
96
97 fn neg(self) -> Polynomial<T> {
98 let mut rev_coeffs = self.rev_coeffs;
99 for c in rev_coeffs.iter_mut() {
100 *c = -&*c;
101 }
102 Polynomial::new_reversed(rev_coeffs)
103 }
104}
105
106impl<T> Neg for &Polynomial<T>
107where
108 T: Zero,
109 for<'l> &'l T: Neg<Output = T>,
110{
111 type Output = Polynomial<T>;
112
113 fn neg(self) -> Polynomial<T> {
114 let rev_coeffs = self.rev_coeffs.iter().map(|c| -c).collect();
115 Polynomial::new_reversed(rev_coeffs)
116 }
117}
118
119#[cfg(test)]
120mod tests {
121 use crate::*;
122
123 #[test]
124 fn test_sub() {
125 let a = Polynomial::new(coefficients![1f32, 3.0, 3.0, 0.0]);
126 let b = Polynomial::new(coefficients![1f32, 0.0, 1.0]);
127
128 let expected = coefficients![1f32, 2.0, 3.0, -1.0];
129
130 let c = a.clone() - b.clone();
132 assert_eq!(c.order(), 3);
133 assert_eq!(c.coeffs(), expected);
134
135 let c = a.clone() - &b;
137 assert_eq!(c.order(), 3);
138 assert_eq!(c.coeffs(), expected);
139
140 let c = &a - b.clone();
142 assert_eq!(c.order(), 3);
143 assert_eq!(c.coeffs(), expected);
144
145 let c = &a - &b;
147 assert_eq!(c.order(), 3);
148 assert_eq!(c.coeffs(), expected);
149
150 let b = Polynomial::new(coefficients![1f32, 3.0, 3.0, -1.0]);
152 let c = a - b;
153 assert_eq!(c.order(), 0);
154 assert_eq!(c.coeffs(), coefficients![1f32]);
155 }
156
157 #[test]
158 fn test_sub_assign() {
159 let a = Polynomial::new(coefficients![1f32, 3.0, 3.0, 0.0]);
160 let b = Polynomial::new(coefficients![1f32, 0.0, 1.0]);
161
162 let expected = coefficients![1f32, 2.0, 3.0, -1.0];
163
164 let mut c = a.clone();
166 c -= b.clone();
167 assert_eq!(c.order(), 3);
168 assert_eq!(c.coeffs(), expected);
169
170 let mut c = a.clone();
172 c -= &b;
173 assert_eq!(c.order(), 3);
174 assert_eq!(c.coeffs(), expected);
175
176 let b = Polynomial::new(coefficients![1f32, 3.0, 3.0, -1.0]);
178 let mut c = a.clone();
179 c -= b;
180 assert_eq!(c.order(), 0);
181 assert_eq!(c.coeffs(), coefficients![1f32]);
182 }
183
184 #[test]
185 fn test_neg() {
186 let a = Polynomial::new(coefficients![1f32, 3.0, 3.0, 0.0]);
187 let expected = coefficients![-1f32, -3.0, -3.0, 0.0];
188
189 let b = -&a;
191 assert_eq!(b.coeffs(), expected);
192
193 let b = -a;
195 assert_eq!(b.coeffs(), expected);
196 }
197}