poly/
sub.rs

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			// the following line causes clippy to emit a spurious warning (using - in an SubAssign-implementation)
74			#[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			//self.rev_coeffs.resize_with(rhs.rev_coeffs.len(), T::zero); // SmallVec doesn't have resize_with :(
81		}
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		// Polynomial - Polynomial
131		let c = a.clone() - b.clone();
132		assert_eq!(c.order(), 3);
133		assert_eq!(c.coeffs(), expected);
134
135		// Polynomial - &Polynomial
136		let c = a.clone() - &b;
137		assert_eq!(c.order(), 3);
138		assert_eq!(c.coeffs(), expected);
139
140		// &Polynomial - Polynomial
141		let c = &a - b.clone();
142		assert_eq!(c.order(), 3);
143		assert_eq!(c.coeffs(), expected);
144
145		// &Polynomial - &Polynomial
146		let c = &a - &b;
147		assert_eq!(c.order(), 3);
148		assert_eq!(c.coeffs(), expected);
149
150		// Removal of leading zeros
151		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		// Polynomial -= Polynomial
165		let mut c = a.clone();
166		c -= b.clone();
167		assert_eq!(c.order(), 3);
168		assert_eq!(c.coeffs(), expected);
169
170		// Polynomial -= &Polynomial
171		let mut c = a.clone();
172		c -= &b;
173		assert_eq!(c.order(), 3);
174		assert_eq!(c.coeffs(), expected);
175
176		// Removal of leading zeros
177		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		// &Polynomial
190		let b = -&a;
191		assert_eq!(b.coeffs(), expected);
192
193		// -Polynomial
194		let b = -a;
195		assert_eq!(b.coeffs(), expected);
196	}
197}