qfall_math/integer/poly_over_z/arithmetic/
add.rs1use super::super::PolyOverZ;
12use crate::integer::Z;
13use crate::macros::arithmetics::{
14 arithmetic_assign_trait_borrowed_to_owned, arithmetic_trait_borrowed_to_owned,
15 arithmetic_trait_mixed_borrowed_owned,
16};
17use flint_sys::{fmpz::fmpz_add, fmpz_poly::fmpz_poly_add};
18use std::ops::{Add, AddAssign};
19
20impl AddAssign<&PolyOverZ> for PolyOverZ {
21 fn add_assign(&mut self, other: &Self) {
41 unsafe { fmpz_poly_add(&mut self.poly, &self.poly, &other.poly) };
42 }
43}
44
45arithmetic_assign_trait_borrowed_to_owned!(AddAssign, add_assign, PolyOverZ, PolyOverZ);
46
47impl Add for &PolyOverZ {
48 type Output = PolyOverZ;
49 fn add(self, other: Self) -> Self::Output {
71 let mut out = PolyOverZ::default();
72 unsafe {
73 fmpz_poly_add(&mut out.poly, &self.poly, &other.poly);
74 }
75 out
76 }
77}
78
79arithmetic_trait_borrowed_to_owned!(Add, add, PolyOverZ, PolyOverZ, PolyOverZ);
80arithmetic_trait_mixed_borrowed_owned!(Add, add, PolyOverZ, PolyOverZ, PolyOverZ);
81
82impl Add<&Z> for &PolyOverZ {
83 type Output = PolyOverZ;
84 fn add(self, other: &Z) -> Self::Output {
107 if self.is_zero() {
110 PolyOverZ::from(other)
111 } else {
112 let out = self.clone();
113 unsafe {
114 fmpz_add(out.poly.coeffs, &other.value, out.poly.coeffs);
115 }
116 out
117 }
118 }
119}
120
121arithmetic_trait_borrowed_to_owned!(Add, add, PolyOverZ, Z, PolyOverZ);
122arithmetic_trait_mixed_borrowed_owned!(Add, add, PolyOverZ, Z, PolyOverZ);
123
124#[cfg(test)]
125mod test_add_assign {
126 use super::PolyOverZ;
127 use std::str::FromStr;
128
129 #[test]
131 fn correct_small() {
132 let mut a = PolyOverZ::from_str("3 -1 2 -3").unwrap();
133 let b = PolyOverZ::from_str("5 1 2 5 1 2").unwrap();
134 let cmp = PolyOverZ::from_str("5 0 4 2 1 2").unwrap();
135
136 a += b;
137
138 assert_eq!(cmp, a);
139 }
140
141 #[test]
143 fn correct_large() {
144 let mut a =
145 PolyOverZ::from_str(&format!("3 {} {} {}", u32::MAX, i32::MIN, i32::MAX)).unwrap();
146 let b = PolyOverZ::from_str(&format!("2 {} {}", u32::MAX, i32::MAX)).unwrap();
147 let cmp = PolyOverZ::from_str(&format!("3 {} -1 {}", u64::from(u32::MAX) * 2, i32::MAX))
148 .unwrap();
149
150 a += b;
151
152 assert_eq!(cmp, a);
153 }
154
155 #[test]
157 fn availability() {
158 let mut a = PolyOverZ::from_str("3 1 2 -3").unwrap();
159 let b = PolyOverZ::from_str("3 -1 -2 3").unwrap();
160
161 a += &b;
162 a += b;
163 }
164}
165
166#[cfg(test)]
167mod test_add {
168 use super::PolyOverZ;
169 use std::str::FromStr;
170
171 #[test]
173 fn add() {
174 let a: PolyOverZ = PolyOverZ::from_str("3 1 2 -3").unwrap();
175 let b: PolyOverZ = PolyOverZ::from_str("5 1 2 5 1 2").unwrap();
176 let c: PolyOverZ = a + b;
177 assert_eq!(c, PolyOverZ::from_str("5 2 4 2 1 2").unwrap());
178 }
179
180 #[test]
182 fn add_borrow() {
183 let a: PolyOverZ = PolyOverZ::from_str("3 1 2 -3").unwrap();
184 let b: PolyOverZ = PolyOverZ::from_str("5 1 2 5 1 2").unwrap();
185 let c: PolyOverZ = &a + &b;
186 assert_eq!(c, PolyOverZ::from_str("5 2 4 2 1 2").unwrap());
187 }
188
189 #[test]
191 fn add_first_borrowed() {
192 let a: PolyOverZ = PolyOverZ::from_str("3 1 2 -3").unwrap();
193 let b: PolyOverZ = PolyOverZ::from_str("5 1 2 5 1 2").unwrap();
194 let c: PolyOverZ = &a + b;
195 assert_eq!(c, PolyOverZ::from_str("5 2 4 2 1 2").unwrap());
196 }
197
198 #[test]
200 fn add_second_borrowed() {
201 let a: PolyOverZ = PolyOverZ::from_str("3 1 2 -3").unwrap();
202 let b: PolyOverZ = PolyOverZ::from_str("5 1 2 5 1 2").unwrap();
203 let c: PolyOverZ = a + &b;
204 assert_eq!(c, PolyOverZ::from_str("5 2 4 2 1 2").unwrap());
205 }
206
207 #[test]
209 fn add_eliminating_coefficients() {
210 let a: PolyOverZ = PolyOverZ::from_str("3 1 2 -3").unwrap();
211 let b: PolyOverZ = PolyOverZ::from_str("3 -1 -2 3").unwrap();
212 let c: PolyOverZ = a + b;
213 assert_eq!(c, PolyOverZ::default());
214 }
215
216 #[test]
218 fn add_large_numbers() {
219 let a: PolyOverZ =
220 PolyOverZ::from_str(&format!("3 {} {} {}", u32::MAX, i32::MIN, i32::MAX)).unwrap();
221 let b: PolyOverZ = PolyOverZ::from_str(&format!("2 {} {}", u32::MAX, i32::MAX)).unwrap();
222 let c: PolyOverZ = a + b;
223 assert_eq!(
224 c,
225 PolyOverZ::from_str(&format!("3 {} -1 {}", u64::from(u32::MAX) * 2, i32::MAX))
226 .unwrap()
227 );
228 }
229}
230
231#[cfg(test)]
232mod test_add_between_z_and_poly_over_z {
233 use crate::integer::PolyOverZ;
234 use crate::integer::Z;
235 use std::str::FromStr;
236
237 #[test]
239 fn add() {
240 let a: PolyOverZ = PolyOverZ::from_str("4 1 1 2 3").unwrap();
241 let b: Z = Z::from(9);
242 let c: PolyOverZ = a + b;
243 assert_eq!(c, PolyOverZ::from_str("4 10 1 2 3").unwrap());
244 }
245
246 #[test]
248 fn add_borrow() {
249 let a: PolyOverZ = PolyOverZ::from_str("4 1 1 2 3").unwrap();
250 let b: Z = Z::from(9);
251 let c: PolyOverZ = &a + &b;
252 assert_eq!(c, PolyOverZ::from_str("4 10 1 2 3").unwrap());
253 }
254
255 #[test]
257 fn add_first_borrowed() {
258 let a: PolyOverZ = PolyOverZ::from_str("4 1 1 2 3").unwrap();
259 let b: Z = Z::from(9);
260 let c: PolyOverZ = &a + b;
261 assert_eq!(c, PolyOverZ::from_str("4 10 1 2 3").unwrap());
262 }
263
264 #[test]
266 fn add_second_borrowed() {
267 let a: PolyOverZ = PolyOverZ::from_str("4 1 1 2 3").unwrap();
268 let b: Z = Z::from(9);
269 let c: PolyOverZ = a + &b;
270 assert_eq!(c, PolyOverZ::from_str("4 10 1 2 3").unwrap());
271 }
272
273 #[test]
275 fn add_large_numbers() {
276 let a: PolyOverZ =
277 PolyOverZ::from_str(&format!("3 {} {} {}", i64::MAX, u64::MAX, i32::MAX)).unwrap();
278 let b: Z = Z::from(i64::MAX);
279 let c: PolyOverZ = a + b;
280 assert_eq!(
281 c,
282 PolyOverZ::from_str(&format!("3 {} {} {}", u64::MAX - 1, u64::MAX, i32::MAX)).unwrap()
283 );
284 }
285
286 #[test]
288 fn add_zero() {
289 let a: PolyOverZ = PolyOverZ::default();
290 let b: Z = Z::from(15);
291 let c: PolyOverZ = a + b;
292 assert_eq!(c, PolyOverZ::from_str("1 15").unwrap());
293
294 let d: PolyOverZ = PolyOverZ::from_str("1 15").unwrap();
295 let e: Z = Z::ZERO;
296 let f: PolyOverZ = d + e;
297 assert_eq!(f, PolyOverZ::from_str("1 15").unwrap());
298 }
299}