polynomint/
sub.rs

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                    // if i > deg self, then by the loop condition, i <= deg rhs,
16                    // so the indexing is valid
17                    self.coeffs.push(-rhs.coeffs[i as usize]);
18                } else if i > rhs.degree() {
19                    // if i > deg rhs, then whatever higher coefficients remain in self
20                    // are already correct
21                    break;
22                } else {
23                    // otherwise just sub from self---this makes the subtraction be in-place
24                    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                    // if i > deg self, then by the loop condition, i <= deg rhs,
117                    // so the indexing is valid
118                    self.coeffs.push(-rhs.coeffs[i as usize]);
119                } else if i > rhs.degree() {
120                    // if i > deg rhs, then whatever higher coefficients remain in self
121                    // are already correct
122                    break;
123                } else {
124                    // otherwise just sub from self---this makes the subtraction be in-place
125                    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                    // if i > deg self, then by the loop condition, i <= deg rhs,
141                    // so the indexing is valid
142                    self.coeffs.push(-rhs.coeffs[i as usize]);
143                } else if i > rhs.degree() {
144                    // if i > deg rhs, then whatever higher coefficients remain in self
145                    // are already correct
146                    break;
147                } else {
148                    // otherwise just sub from self---this makes the subtraction be in-place
149                    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}