1#![allow(clippy::suspicious_op_assign_impl)]
2#![doc = include_str!("../Readme.md")]
3pub mod inner_series;
4pub mod ops;
5pub mod poly;
6pub mod poly_in;
7pub mod poly_slice;
8pub mod poly_slice_in;
9pub mod series;
10pub mod series_in;
11pub mod series_slice;
12pub mod series_slice_in;
13mod zero_ref;
14
15pub use self::inner_series::InnerSeries;
16pub use self::ops::{Exp, Ln, Pow};
17pub use self::poly::{Polynomial, PolynomialParts};
18pub use self::poly_in::{PolynomialIn, PolynomialInParts};
19pub use self::poly_slice::PolynomialSlice;
20pub use self::poly_slice_in::PolynomialSliceIn;
21pub use self::series::{Series, SeriesParts};
22pub use self::series_in::{SeriesIn, SeriesInParts};
23pub use self::series_slice::SeriesSlice;
24pub use self::series_slice_in::SeriesSliceIn;
25mod traits;
26pub use self::traits::{AsSlice, KaratsubaMul, MulInverse};
27mod util;
28
29use std::iter::Zip;
30use std::ops::RangeFrom;
31
32use num_traits::{One, Zero};
33
34pub trait Coeff: Zero + One + PartialEq {}
36impl<T: Zero + One + PartialEq> Coeff for T {}
37
38pub type Iter<'a, C> = Zip<RangeFrom<isize>, std::slice::Iter<'a, C>>;
42pub type IntoIter<C> = Zip<RangeFrom<isize>, std::vec::IntoIter<C>>;
46
47#[doc = include_str!("../Readme.md")]
49#[cfg(doctest)]
50pub struct ReadmeDoctests;
51
52#[cfg(test)]
53mod tests {
54 use super::*;
55
56 #[test]
57 fn tst_series() {
58 let var = String::from("x");
59 let min_pow = -10;
60 let coeffs = vec![];
61 let s = SeriesIn::new(var.clone(), min_pow, coeffs);
62 assert_eq!(s.min_pow(), min_pow);
63 assert_eq!(s.coeff(-11), Some(&0));
64 assert_eq!(s.coeff(-10), None);
65
66 let min_pow = -3;
67 let coeffs = vec![1., 2., 3.];
68 let s = SeriesIn::new(var.clone(), min_pow, coeffs);
69 assert_eq!(s.min_pow(), min_pow);
70 assert_eq!(s.coeff(-4), Some(&0.));
71 assert_eq!(s.coeff(-3), Some(&1.));
72 assert_eq!(s.coeff(-2), Some(&2.));
73 assert_eq!(s.coeff(-1), Some(&3.));
74 assert_eq!(s.coeff(0), None);
75
76 let min_pow = -2;
77 let coeffs = vec![0., 0., 3.];
78 let s = SeriesIn::new(var.clone(), min_pow, coeffs);
79 assert_eq!(s.min_pow(), min_pow + 2);
80 assert_eq!(s.coeff(-2), Some(&0.));
81 assert_eq!(s.coeff(-1), Some(&0.));
82 assert_eq!(s.coeff(0), Some(&3.));
83 assert_eq!(s.coeff(1), None);
84
85 let s = SeriesIn::new(var.clone(), -2, vec![0., 0., 1.]);
86 let t = SeriesIn::new(var.clone(), 0, vec![1.]);
87 assert_eq!(s, t);
88
89 let s = SeriesIn::new(var.clone(), -3, vec![0., 0., 0.]);
90 let t = SeriesIn::new(var.clone(), 0, vec![]);
91 assert_eq!(s, t);
92 }
93
94 #[test]
95 fn tst_series_with_cutoff() {
96 let s = SeriesIn::with_cutoff("x", -10, 1, Vec::<i32>::new());
97 let t = SeriesIn::new("x", 1, vec![]);
98 assert_eq!(s, t);
99
100 let s = SeriesIn::with_cutoff("x", 0, 5, vec![1, 2, 3]);
101 let t = SeriesIn::new("x", 0, vec![1, 2, 3, 0, 0]);
102 assert_eq!(s, t);
103
104 let s = SeriesIn::with_cutoff("x", 0, 2, vec![1, 2, 3]);
105 let t = SeriesIn::new("x", 0, vec![1, 2]);
106 assert_eq!(s, t);
107 }
108 #[test]
109 #[should_panic]
110 fn tst_bad_cutoff() {
111 let _ = SeriesIn::with_cutoff("x", 0, -2, vec![1, 2, 3]);
112 }
113
114 #[test]
115 fn tst_display() {
116 let s = SeriesIn::new("x", -3, vec![1., 0., -3.]);
119 assert_eq!(format!("{}", s), "(1)*x^-3 + (-3)*x^-1 + O(x^0)");
120 let s = SeriesIn::new("x", -1, vec![1., 2., -3.]);
121 assert_eq!(format!("{}", s), "(1)*x^-1 + (2) + (-3)*x + O(x^2)");
122 }
123
124 #[test]
125 fn tst_neg() {
126 let s = SeriesIn::new("x", -3, vec![1., 0., -3.]);
127 let res = SeriesIn::new("x", -3, vec![-1., 0., 3.]);
128 assert_eq!(res, -&s);
129 assert_eq!(res, -s);
130 }
131
132 #[test]
133 fn tst_add() {
134 let s = SeriesIn::new("x", -3, vec![1., 0., -3.]);
135 let res = SeriesIn::new("x", -3, vec![2., 0., -6.]);
136 assert_eq!(res, &s + &s);
137 assert_eq!(res, &s + s.clone());
138 assert_eq!(res, s.clone() + &s);
139 assert_eq!(res, s.clone() + s.clone());
140
141 let s = SeriesIn::new("x", -3, vec![1., 0., -3.]);
142 let t = SeriesIn::new("x", -1, vec![3., 4., 5.]);
143 let res = SeriesIn::new("x", -3, vec![1., 0., 0.]);
144 assert_eq!(res, &s + &t);
145 assert_eq!(res, &t + &s);
146 assert_eq!(res, &s + t.clone());
147 assert_eq!(res, &t + s.clone());
148 assert_eq!(res, s.clone() + &t);
149 assert_eq!(res, t.clone() + &s);
150 assert_eq!(res, s.clone() + t.clone());
151 assert_eq!(res, t.clone() + s.clone());
152
153 let s = SeriesIn::new("x", -3, vec![1., 0., -3.]);
154 let t = SeriesIn::new("x", 1, vec![3., 4., 5.]);
155 assert_eq!(s, &s + &t);
156 assert_eq!(s, &t + &s);
157 assert_eq!(s, &s + t.clone());
158 assert_eq!(s, &t + s.clone());
159 assert_eq!(s, s.clone() + &t);
160 assert_eq!(s, t.clone() + &s);
161 assert_eq!(s, s.clone() + t.clone());
162 assert_eq!(s, t.clone() + s.clone());
163
164 let s = SeriesIn::new("x", -3, vec![1., 0., -3.]);
165 let t = SeriesIn::new("x", -3, vec![-1., 0., 3.]);
166 let res = SeriesIn::new("x", 0, vec![]);
167 assert_eq!(res, &s + &t);
168 assert_eq!(res, &t + &s);
169 assert_eq!(res, &s + t.clone());
170 assert_eq!(res, &t + s.clone());
171 assert_eq!(res, s.clone() + &t);
172 assert_eq!(res, t.clone() + &s);
173 assert_eq!(res, s.clone() + t.clone());
174 assert_eq!(res, t.clone() + s.clone());
175 }
176
177 #[test]
178 fn tst_add_assign() {
179 let mut s = SeriesIn::new("x", -3, vec![1., 0., -3.]);
180 let res = SeriesIn::new("x", -3, vec![2., 0., -6.]);
181 s += s.clone();
182 assert_eq!(res, s);
183
184 let mut s = SeriesIn::new("x", -3, vec![1., 0., -3.]);
185 let t = SeriesIn::new("x", -1, vec![3., 4., 5.]);
186 let res = SeriesIn::new("x", -3, vec![1., 0., 0.]);
187 s += &t;
188 assert_eq!(res, s);
189 let mut s = SeriesIn::new("x", -3, vec![1., 0., -3.]);
190 s += t;
191 assert_eq!(res, s);
192 let mut s = SeriesIn::new("x", -1, vec![3., 4., 5.]);
193 let t = SeriesIn::new("x", -3, vec![1., 0., -3.]);
194 s += t;
195 assert_eq!(res, s);
196
197 let mut s = SeriesIn::new("x", -3, vec![1., 0., -3.]);
198 let res = s.clone();
199 let t = SeriesIn::new("x", 1, vec![3., 4., 5.]);
200 s += &t;
201 assert_eq!(s, res);
202 let mut s = SeriesIn::new("x", -3, vec![1., 0., -3.]);
203 s += t;
204 assert_eq!(s, res);
205
206 let mut s = SeriesIn::new("x", -3, vec![1., 0., -3.]);
207 let t = SeriesIn::new("x", -3, vec![-1., 0., 3.]);
208 let res = SeriesIn::new("x", 0, vec![]);
209 s += &t;
210 assert_eq!(res, s);
211 let mut s = SeriesIn::new("x", -3, vec![1., 0., -3.]);
212 s += t;
213 assert_eq!(res, s);
214 }
215
216 #[test]
217 fn tst_sub() {
218 let s = SeriesIn::new("x", -3, vec![1., 0., -3.]);
219 let res = SeriesIn::new("x", 0, vec![]);
220 assert_eq!(res, &s - &s);
221 assert_eq!(res, &s - s.clone());
222 assert_eq!(res, s.clone() - &s);
223 assert_eq!(res, s.clone() - s.clone());
224
225 let s = SeriesIn::new("x", -3, vec![1., 0., -3.]);
226 let t = SeriesIn::new("x", -1, vec![-3., 4., 5.]);
227 let res = SeriesIn::new("x", -3, vec![1., 0., 0.]);
228 assert_eq!(res, &s - &t);
229 assert_eq!(res, &s - t.clone());
230 assert_eq!(res, s.clone() - &t);
231 assert_eq!(res, s - t);
232
233 let s = SeriesIn::new("x", -3, vec![1., 0., -3.]);
234 let t = SeriesIn::new("x", 1, vec![3., 4., 5.]);
235 assert_eq!(s, &s - &t);
236 assert_eq!(s, &s - t.clone());
237 assert_eq!(s, s.clone() - &t);
238 assert_eq!(s, s.clone() - t);
239 }
240
241 #[test]
242 fn tst_sub_assign() {
243 let mut s = SeriesIn::new("x", -3, vec![1., 0., -3.]);
244 let res = SeriesIn::new("x", 0, vec![]);
245 s -= s.clone();
246 assert_eq!(res, s);
247
248 let mut s = SeriesIn::new("x", -3, vec![1., 0., -3.]);
249 let t = SeriesIn::new("x", -1, vec![-3., 4., 5.]);
250 let res = SeriesIn::new("x", -3, vec![1., 0., 0.]);
251 s -= &t;
252 assert_eq!(res, s);
253 let mut s = SeriesIn::new("x", -3, vec![1., 0., -3.]);
254 s -= t;
255 assert_eq!(res, s);
256
257 let mut s = SeriesIn::new("x", -3, vec![1., 0., -3.]);
258 let res = s.clone();
259 let t = SeriesIn::new("x", 1, vec![3., 4., 5.]);
260 s -= &t;
261 assert_eq!(res, s);
262 let mut s = SeriesIn::new("x", -3, vec![1., 0., -3.]);
263 s -= t;
264 assert_eq!(res, s);
265 }
266
267 #[test]
268 fn tst_mul() {
269 let s = SeriesIn::new("x", -3, vec![1., 0., -3.]);
270 let res = SeriesIn::new("x", -6, vec![1., 0., -6.]);
271 assert_eq!(res, &s * &s);
272 assert_eq!(res, &s * s.clone());
273 assert_eq!(res, s.clone() * &s);
274 assert_eq!(res, s.clone() * s.clone());
275
276 let s = SeriesIn::new("x", -3, vec![1., 0., -3.]);
277 let t = SeriesIn::new("x", -1, vec![3., 4., 5., 7.]);
278 let res = SeriesIn::new("x", -4, vec![3., 4., -4.]);
279 assert_eq!(res, &s * &t);
280 assert_eq!(res, &t * &s);
281 assert_eq!(res, &s * t.clone());
282 assert_eq!(res, &t * s.clone());
283 assert_eq!(res, &s * t.clone());
284 assert_eq!(res, &t * s.clone());
285 assert_eq!(res, t.clone() * s.clone());
286 assert_eq!(res, s * t);
287
288 let s = SeriesIn::new("x", -3, vec![1., 7., -3.]);
289 let t = SeriesIn::new("x", 3, vec![1., -7., 52.]);
290 let res = SeriesIn::new("x", 0, vec![1., 0., 0.]);
291 assert_eq!(res, &s * &t);
292 assert_eq!(res, &t * &s);
293 assert_eq!(res, &s * t.clone());
294 assert_eq!(res, &t * s.clone());
295 assert_eq!(res, s.clone() * &t);
296 assert_eq!(res, t.clone() * &s);
297 assert_eq!(res, t.clone() * s.clone());
298 assert_eq!(res, s * t);
299 }
300
301 #[test]
302 fn tst_mul_assign() {
303 let mut s = SeriesIn::new("x", -3, vec![1., 0., -3.]);
304 s *= s.clone();
305 let res = SeriesIn::new("x", -6, vec![1., 0., -6.]);
306 assert_eq!(res, s);
307
308 let mut s = SeriesIn::new("x", -3, vec![1., 0., -3.]);
309 let t = SeriesIn::new("x", -1, vec![3., 4., 5., 7.]);
310 s *= &t;
311 let res = SeriesIn::new("x", -4, vec![3., 4., -4.]);
312 assert_eq!(res, s);
313 let mut s = SeriesIn::new("x", -3, vec![1., 0., -3.]);
314 s *= t;
315 assert_eq!(res, s);
316
317 let mut s = SeriesIn::new("x", -3, vec![1., 7., -3.]);
318 let t = SeriesIn::new("x", 3, vec![1., -7., 52.]);
319 s *= &t;
320 let res = SeriesIn::new("x", 0, vec![1., 0., 0.]);
321 assert_eq!(res, s);
322 let mut s = SeriesIn::new("x", -3, vec![1., 7., -3.]);
323 s *= t;
324 assert_eq!(res, s);
325 }
326
327 #[test]
328 fn tst_div() {
329 let s = SeriesIn::new("x", -3, vec![1., 0., -3.]);
330 let res = SeriesIn::new("x", 0, vec![1., 0., 0.]);
331 assert_eq!(res, &s / &s);
332 assert_eq!(res, &s / s.clone());
333 assert_eq!(res, s.clone() / &s);
334 assert_eq!(res, s.clone() / s.clone());
335
336 let s = SeriesIn::new("x", -3, vec![1., 7., -3.]);
345 let t = SeriesIn::new("x", 3, vec![1., -7., 52.]);
346 let res = SeriesIn::new("x", -6, vec![1., 14., 43.]);
347 assert_eq!(res, &s / &t);
348 assert_eq!(res, s.clone() / &t);
349 assert_eq!(res, &s / t.clone());
350 assert_eq!((&res).mul_inverse(), &t / &s);
351 assert_eq!(res, s / t);
352
353 let s = SeriesIn::new("x", 1, vec![1., 7., -3.]);
354 let t = SeriesIn::new("x", 5, vec![]);
355 let res = SeriesIn::new("x", -4, vec![]);
356 assert_eq!(res, &s / &t);
357 assert_eq!(res, s.clone() / &t);
358 assert_eq!(res, &s / t.clone());
359 assert_eq!((&res).mul_inverse(), &t / &s);
360 assert_eq!(res, s / t);
361 }
362
363 #[test]
364 fn tst_div_assign() {
365 let mut s = SeriesIn::new("x", -3, vec![1., 0., -3.]);
366 s /= s.clone();
367 let res = SeriesIn::new("x", 0, vec![1., 0., 0.]);
368 assert_eq!(res, s);
369
370 let mut s = SeriesIn::new("x", -3, vec![1., 7., -3.]);
371 let t = SeriesIn::new("x", 3, vec![1., -7., 52.]);
372 s /= &t;
373 let res = SeriesIn::new("x", -6, vec![1., 14., 43.]);
374 assert_eq!(res, s);
375 let mut s = SeriesIn::new("x", -3, vec![1., 7., -3.]);
376 s /= t;
377 assert_eq!(res, s);
378
379 let mut s = SeriesIn::new("x", 1, vec![1., 7., -3.]);
380 let t = SeriesIn::new("x", 5, vec![]);
381 s /= &t;
382 let res = SeriesIn::new("x", -4, vec![]);
383 assert_eq!(res, s);
384 let mut s = SeriesIn::new("x", 1, vec![1., 7., -3.]);
385 s /= t;
386 assert_eq!(res, s);
387 }
388
389 #[test]
390 fn tst_var() {
391 let _ = SeriesIn::new(String::from("x"), -3, vec![1., 0., -3.]);
392 let _ = SeriesIn::new('j', -3, vec![1., 0., -3.]);
393 let _ = SeriesIn::new(8, -3, vec![1., 0., -3.]);
394 }
395
396 #[derive(Debug, Clone, PartialEq)]
397 struct Mystr<'a>(&'a str);
398
399 impl<'a> From<Mystr<'a>> for f64 {
400 fn from(_s: Mystr<'a>) -> f64 {
401 panic!("can't turn str to f64")
402 }
403 }
404
405 #[test]
406 fn tst_ln() {
407 let s = SeriesIn::new(Mystr("x"), 0, vec![1., 7., -3.]);
408 let res = SeriesIn::new(Mystr("x"), 1, vec![7., -55. / 2.]);
409 assert_eq!(res, (&s).ln());
410 assert_eq!(res, s.ln());
411
412 let s = SeriesIn::new(Mystr("x"), 0, vec![4., 7., -3.]);
413 let res =
414 SeriesIn::new(Mystr("x"), 0, vec![4_f64.ln(), 7. / 4., -73. / 32.]);
415 assert_eq!(res, (&s).ln());
416 assert_eq!(res, s.ln());
417 }
418
419 #[test]
420 fn tst_exp() {
421 let s = SeriesIn::new("x", 1, vec![7., -3.]);
422 let res = SeriesIn::new("x", 0, vec![1., 7., 43. / 2.]);
423 assert_eq!(res, (&s).exp());
424 assert_eq!(res, s.exp());
425
426 let s = SeriesIn::new("x", 2, vec![0.]);
427 let res = SeriesIn::new("x", 0, vec![1., 0., 0.]);
428 assert_eq!(res, (&s).exp());
429 assert_eq!(res, s.exp());
430
431 let s = SeriesIn::new("x", 0, vec![5., 11., -7.]);
432 let e5 = 5_f64.exp();
433 let res = SeriesIn::new("x", 0, vec![e5, e5 * 11., e5 * 107. / 2.]);
434 assert_eq!(res, (&s).exp());
435 assert_eq!(res, s.exp());
436 }
437
438 #[test]
439 fn tst_pow() {
440 let base = SeriesIn::new(Mystr("x"), 0, vec![1., 7., 0.]);
441 let exp = SeriesIn::new(Mystr("x"), -1, vec![1., -5., 43.]);
442 let e7 = 7_f64.exp();
443 let res = SeriesIn::new(Mystr("x"), 0, vec![e7, -119. / 2. * e7]);
444 assert_eq!(res, (&base).pow(&exp));
445 assert_eq!(res, (&base).pow(exp.clone()));
446 assert_eq!(res, base.clone().pow(&exp));
447 assert_eq!(res, base.pow(exp));
448
449 let base = SeriesIn::new(Mystr("x"), 0, vec![2., 7., 0.]);
450 let exp = SeriesIn::new(Mystr("x"), 0, vec![3., -5., 11.]);
451 let rescale = SeriesIn::new(Mystr("x"), 0, vec![1e13, 0., 0., 0.]);
453 let test = &rescale * &base.pow(exp);
454 let ln2 = 2_f64.ln();
455 let res = SeriesIn::new(
456 Mystr("x"),
457 0,
458 vec![8., 84. - 40. * ln2, 154. + ln2 * (-332. + 100. * ln2)],
459 );
460 let res = rescale * res;
461 assert_eq!(res.min_pow(), test.min_pow());
462 assert_eq!(res.cutoff_pow(), test.cutoff_pow());
463 for i in res.min_pow()..res.cutoff_pow() {
464 assert_eq!(
465 res.coeff(i).unwrap().round(),
466 test.coeff(i).unwrap().round()
467 );
468 }
469 }
470
471 #[test]
472 fn tst_scalar() {
473 let s = SeriesIn::new("x", -3, vec![1., 0., -2.]);
474 let res = SeriesIn::new("x", -3, vec![1. / 2., 0., -1.]);
475 assert_eq!(res, &s / 2.);
476 let mut s = s;
477 s /= 2.;
478 assert_eq!(res, s);
479
480 let s = SeriesIn::new("x", -3, vec![1. / 2., 0., -1.]);
481 let res = SeriesIn::new("x", -3, vec![1., 0., -2.]);
482 assert_eq!(res, &s * 2.);
483 let mut s = s;
484 s *= 2.;
485 assert_eq!(res, s);
486
487 let s = SeriesIn::new("x", -3, vec![1. / 2., 0., -1.]);
488 assert_eq!(s, &s + 0.);
489 assert_eq!(s, &s + 2.);
490 let s = SeriesIn::new("x", -2, vec![1. / 2., 0., -1.]);
491 let res = SeriesIn::new("x", -2, vec![1. / 2., 0., 1.]);
492 assert_eq!(s, &s + 0.);
493 assert_eq!(res, s + 2.);
494 let s = SeriesIn::new("x", 2, vec![1. / 2., 0., -1.]);
495 let res = SeriesIn::new("x", 0, vec![2., 0., 1. / 2., 0., -1.]);
496 assert_eq!(s, &s + 0.);
497 assert_eq!(res, s + 2.);
498 let s = SeriesIn::new("x", 0, vec![-2., 0., -1.]);
499 let res = SeriesIn::new("x", 2, vec![-1.]);
500 assert_eq!(res, s + 2.);
501
502 let s = SeriesIn::new("x", -3, vec![1. / 2., 0., -1.]);
503 assert_eq!(s, &s - 0.);
504 assert_eq!(s, &s - 2.);
505 let s = SeriesIn::new("x", -2, vec![1. / 2., 0., -1.]);
506 let res = SeriesIn::new("x", -2, vec![1. / 2., 0., -3.]);
507 assert_eq!(s, &s - 0.);
508 assert_eq!(res, s - 2.);
509 let s = SeriesIn::new("x", 2, vec![1. / 2., 0., -1.]);
510 let res = SeriesIn::new("x", 0, vec![-2., 0., 1. / 2., 0., -1.]);
511 assert_eq!(s, &s - 0.);
512 assert_eq!(res, s - 2.);
513 let s = SeriesIn::new("x", 0, vec![2., 0., -1.]);
514 let res = SeriesIn::new("x", 2, vec![-1.]);
515 assert_eq!(res, s - 2.);
516
517 let base = SeriesIn::new(Mystr("x"), 0, vec![1., 7., 0.]);
518 assert_eq!(base, (&base).pow(1.));
519 assert_eq!(base, (&base).pow(&1.));
520 let res = SeriesIn::new(Mystr("x"), 0, vec![1., 21., 147.]);
521 assert_eq!(res, (&base).pow(3.));
522 assert_eq!(res, base.pow(&3.));
523 }
524
525 #[test]
526 #[should_panic]
527 fn tst_bad_add() {
528 let s = SeriesIn::new("x", -3, vec![1., 0., -3.]);
529 let t = SeriesIn::new("y", -3, vec![1., 0., -3.]);
530 let _ = s + t;
531 }
532
533 #[test]
534 #[should_panic]
535 fn tst_bad_sub() {
536 let s = SeriesIn::new("x", -3, vec![1., 0., -3.]);
537 let t = SeriesIn::new("y", -3, vec![1., 0., -3.]);
538 let _ = s - t;
539 }
540
541 #[test]
542 #[should_panic]
543 fn tst_bad_mul() {
544 let s = SeriesIn::new("x", -3, vec![1., 0., -3.]);
545 let t = SeriesIn::new("y", -3, vec![1., 0., -3.]);
546 let _ = s * t;
547 }
548
549 #[test]
550 #[should_panic]
551 fn tst_bad_div() {
552 let s = SeriesIn::new("x", -3, vec![1., 0., -3.]);
553 let t = SeriesIn::new("y", -3, vec![1., 0., -3.]);
554 let _ = s / t;
555 }
556
557 #[test]
558 fn tst_poly() {
559 let var = String::from("x");
560 let min_pow = -10;
561 let coeffs = vec![0];
562 let s = PolynomialIn::new(var.clone(), min_pow, coeffs);
563 assert_eq!(s.min_pow(), None);
564 assert_eq!(s.coeff(-11), (&0));
565 assert_eq!(s.coeff(-10), (&0));
566
567 let min_pow = -3;
568 let coeffs = vec![1., 2., 3.];
569 let s = PolynomialIn::new(var.clone(), min_pow, coeffs);
570 assert_eq!(s.min_pow(), Some(min_pow));
571 assert_eq!(s.coeff(-4), (&0.));
572 assert_eq!(s.coeff(-3), (&1.));
573 assert_eq!(s.coeff(-2), (&2.));
574 assert_eq!(s.coeff(-1), (&3.));
575 assert_eq!(s.coeff(0), (&0.));
576
577 let min_pow = -2;
578 let coeffs = vec![0., 0., 3.];
579 let s = PolynomialIn::new(var.clone(), min_pow, coeffs);
580 assert_eq!(s.min_pow(), Some(min_pow + 2));
581 assert_eq!(s.coeff(-2), (&0.));
582 assert_eq!(s.coeff(-1), (&0.));
583 assert_eq!(s.coeff(0), (&3.));
584 assert_eq!(s.coeff(1), (&0.));
585
586 let s = PolynomialIn::new(var.clone(), -2, vec![0., 0., 1.]);
587 let t = PolynomialIn::new(var.clone(), 0, vec![1.]);
588 assert_eq!(s, t);
589
590 let s = PolynomialIn::new(var.clone(), -3, vec![0., 0., 0.]);
591 let t = PolynomialIn::new(var.clone(), 0, vec![]);
592 assert_eq!(s, t);
593 }
594
595 #[test]
596 fn tst_poly_display() {
597 let s = PolynomialIn::new("x", -10, vec![0]);
598 assert_eq!(format!("{}", s), "");
599 let s = PolynomialIn::new("x", -3, vec![1., 0., -3.]);
600 assert_eq!(format!("{}", s), "(1)*x^-3 + (-3)*x^-1");
601 let s = PolynomialIn::new("x", -1, vec![1., 2., -3.]);
602 assert_eq!(format!("{}", s), "(1)*x^-1 + (2) + (-3)*x");
603 }
604
605 #[test]
606 fn tst_poly_neg() {
607 let s = PolynomialIn::new("x", -3, vec![1., 0., -3.]);
608 let res = PolynomialIn::new("x", -3, vec![-1., 0., 3.]);
609 assert_eq!(res, -&s);
610 assert_eq!(res, -s);
611 }
612
613 #[test]
614 fn tst_poly_add() {
615 let s = PolynomialIn::new("x", -3, vec![1., 0., -3.]);
616 let res = PolynomialIn::new("x", -3, vec![2., 0., -6.]);
617 assert_eq!(res, &s + &s);
618 assert_eq!(res, &s + s.clone());
619 assert_eq!(res, s.clone() + &s);
620 assert_eq!(res, s.clone() + s.clone());
621
622 let s = PolynomialIn::new("x", -3, vec![1., 0., -3.]);
623 let t = PolynomialIn::new("x", -1, vec![3., 4., 5.]);
624 let res = PolynomialIn::new("x", -3, vec![1., 0., 0., 4., 5.]);
625 assert_eq!(res, &s + &t);
626 assert_eq!(res, &t + &s);
627 assert_eq!(res, &s + t.clone());
628 assert_eq!(res, &t + s.clone());
629 assert_eq!(res, s.clone() + &t);
630 assert_eq!(res, t.clone() + &s);
631 assert_eq!(res, s.clone() + t.clone());
632 assert_eq!(res, t.clone() + s.clone());
633
634 let s = PolynomialIn::new("x", -3, vec![1., 0., -3.]);
635 let t = PolynomialIn::new("x", 1, vec![3., 4., 5.]);
636 let res = PolynomialIn::new("x", -3, vec![1., 0., -3., 0., 3., 4., 5.]);
637 assert_eq!(res, &s + &t);
638 assert_eq!(res, &t + &s);
639 assert_eq!(res, &s + t.clone());
640 assert_eq!(res, &t + s.clone());
641 assert_eq!(res, s.clone() + &t);
642 assert_eq!(res, t.clone() + &s);
643 assert_eq!(res, s.clone() + t.clone());
644 assert_eq!(res, t.clone() + s.clone());
645
646 let s = PolynomialIn::new("x", -3, vec![1., 0., -3.]);
647 let t = PolynomialIn::new("x", -3, vec![-1., 0., 3.]);
648 let res = PolynomialIn::new("x", 0, vec![]);
649 assert_eq!(res, &s + &t);
650 assert_eq!(res, &t + &s);
651 assert_eq!(res, &s + t.clone());
652 assert_eq!(res, &t + s.clone());
653 assert_eq!(res, s.clone() + &t);
654 assert_eq!(res, t.clone() + &s);
655 assert_eq!(res, s.clone() + t.clone());
656 assert_eq!(res, t.clone() + s.clone());
657 }
658
659 #[test]
660 fn tst_poly_add_assign() {
661 let mut s = PolynomialIn::new("x", -3, vec![1., 0., -3.]);
662 let res = PolynomialIn::new("x", -3, vec![2., 0., -6.]);
663 s += s.clone();
664 assert_eq!(res, s);
665
666 let mut s = PolynomialIn::new("x", -3, vec![1., 0., -3.]);
667 let t = PolynomialIn::new("x", -1, vec![3., 4., 5.]);
668 let res = PolynomialIn::new("x", -3, vec![1., 0., 0., 4., 5.]);
669 s += &t;
670 assert_eq!(res, s);
671 let mut s = PolynomialIn::new("x", -3, vec![1., 0., -3.]);
672 s += t;
673 assert_eq!(res, s);
674 let mut s = PolynomialIn::new("x", -1, vec![3., 4., 5.]);
675 let t = PolynomialIn::new("x", -3, vec![1., 0., -3.]);
676 let res = PolynomialIn::new("x", -3, vec![1., 0., 0., 4., 5.]);
677 s += &t;
678 assert_eq!(res, s);
679 let mut s = PolynomialIn::new("x", -1, vec![3., 4., 5.]);
680 s += t;
681 assert_eq!(res, s);
682
683 let mut s = PolynomialIn::new("x", -3, vec![1., 0., -3.]);
684 let t = PolynomialIn::new("x", 1, vec![3., 4., 5.]);
685 let res = PolynomialIn::new("x", -3, vec![1., 0., -3., 0., 3., 4., 5.]);
686 s += &t;
687 assert_eq!(s, res);
688 let mut s = PolynomialIn::new("x", -3, vec![1., 0., -3.]);
689 s += t;
690 assert_eq!(s, res);
691
692 let mut s = PolynomialIn::new("x", -3, vec![1., 0., -3.]);
693 let t = PolynomialIn::new("x", -3, vec![-1., 0., 3.]);
694 let res = PolynomialIn::new("x", 0, vec![]);
695 s += &t;
696 assert_eq!(res, s);
697 let mut s = PolynomialIn::new("x", -3, vec![1., 0., -3.]);
698 s += t;
699 assert_eq!(res, s);
700 }
701
702 #[test]
703 fn tst_poly_sub() {
704 let s = PolynomialIn::new("x", -3, vec![1., 0., -3.]);
705 let res = PolynomialIn::new("x", 0, vec![]);
706 assert_eq!(res, &s - &s);
707 assert_eq!(res, &s - s.clone());
708 assert_eq!(res, s.clone() - &s);
709 assert_eq!(res, s.clone() - s.clone());
710
711 let s = PolynomialIn::new("x", -3, vec![1., 0., -3.]);
712 let t = PolynomialIn::new("x", -1, vec![-3., 4., 5.]);
713 let res = PolynomialIn::new("x", -3, vec![1., 0., 0., -4., -5.]);
714 assert_eq!(res, &s - &t);
715 assert_eq!(res, &s - t.clone());
716 assert_eq!(res, s.clone() - &t);
717 assert_eq!(res, s - t);
718
719 let s = PolynomialIn::new("x", -3, vec![1., 0., -3.]);
720 let t = PolynomialIn::new("x", 1, vec![3., 4., 5.]);
721 let res =
722 PolynomialIn::new("x", -3, vec![1., 0., -3., 0., -3., -4., -5.]);
723 assert_eq!(res, &s - &t);
724 assert_eq!(res, &s - t.clone());
725 assert_eq!(res, s.clone() - &t);
726 assert_eq!(res, s.clone() - t);
727 }
728
729 #[test]
730 fn tst_poly_sub_assign() {
731 let mut s = PolynomialIn::new("x", -3, vec![1., 0., -3.]);
732 let res = PolynomialIn::new("x", 0, vec![]);
733 s -= s.clone();
734 assert_eq!(res, s);
735
736 let mut s = PolynomialIn::new("x", -3, vec![1., 0., -3.]);
737 let t = PolynomialIn::new("x", -1, vec![-3., 4., 5.]);
738 let res = PolynomialIn::new("x", -3, vec![1., 0., 0., -4., -5.]);
739 s -= &t;
740 assert_eq!(res, s);
741 let mut s = PolynomialIn::new("x", -3, vec![1., 0., -3.]);
742 s -= t;
743 assert_eq!(res, s);
744
745 let mut s = PolynomialIn::new("x", -3, vec![1., 0., -3.]);
746 let t = PolynomialIn::new("x", 1, vec![3., 4., 5.]);
747 let res =
748 PolynomialIn::new("x", -3, vec![1., 0., -3., 0., -3., -4., -5.]);
749 s -= &t;
750 assert_eq!(res, s);
751 let mut s = PolynomialIn::new("x", -3, vec![1., 0., -3.]);
752 s -= t;
753 assert_eq!(res, s);
754 }
755
756 #[test]
757 fn tst_poly_mul() {
758 let s = PolynomialIn::new("x", -3, vec![1., 0., -3.]);
759 let res = PolynomialIn::new("x", -6, vec![1., 0., -6., 0., 9.]);
760 assert_eq!(res, &s * &s);
761 assert_eq!(res, &s * s.clone());
762 assert_eq!(res, s.clone() * &s);
763 assert_eq!(res, s.clone() * s.clone());
764
765 let s = PolynomialIn::new("x", -3, vec![1., 0., -3.]);
766 let t = PolynomialIn::new("x", -1, vec![3., 4., 5., 7.]);
767 let res =
768 PolynomialIn::new("x", -4, vec![3., 4., -4., -5., -15., -21.]);
769 assert_eq!(res, &s * &t);
770 assert_eq!(res, &t * &s);
771 assert_eq!(res, &s * t.clone());
772 assert_eq!(res, &t * s.clone());
773 assert_eq!(res, &s * t.clone());
774 assert_eq!(res, &t * s.clone());
775 assert_eq!(res, t.clone() * s.clone());
776 assert_eq!(res, s * t);
777
778 let s = PolynomialIn::new("x", -3, vec![1., 7., -3.]);
779 let t = PolynomialIn::new("x", 3, vec![1., -7., 52.]);
780 let res = PolynomialIn::new("x", 0, vec![1., 0., 0., 385., -156.]);
781 assert_eq!(res, &s * &t);
782 assert_eq!(res, &t * &s);
783 assert_eq!(res, &s * t.clone());
784 assert_eq!(res, &t * s.clone());
785 assert_eq!(res, s.clone() * &t);
786 assert_eq!(res, t.clone() * &s);
787 assert_eq!(res, t.clone() * s.clone());
788 assert_eq!(res, s * t);
789 }
790
791 #[test]
792 fn tst_poly_mul_karatsuba() {
793 let s = PolynomialIn::new("x", -3, (0..=100).collect());
794 let res = s.karatsuba_mul(&s, 200);
795 assert_eq!(res.min_pow(), Some(-4));
796 let res2 = s.karatsuba_mul(&s, 8);
797 assert_eq!(res, res2);
798 }
799
800 #[test]
801 fn tst_poly_mul_assign() {
802 let mut s = PolynomialIn::new("x", -3, vec![1., 0., -3.]);
803 s *= s.clone();
804 let res = PolynomialIn::new("x", -6, vec![1., 0., -6., 0., 9.]);
805 assert_eq!(res, s);
806
807 let mut s = PolynomialIn::new("x", -3, vec![1., 0., -3.]);
808 let t = PolynomialIn::new("x", -1, vec![3., 4., 5., 7.]);
809 let res =
810 PolynomialIn::new("x", -4, vec![3., 4., -4., -5., -15., -21.]);
811 s *= &t;
812 assert_eq!(res, s);
813 let mut s = PolynomialIn::new("x", -3, vec![1., 0., -3.]);
814 s *= t;
815 assert_eq!(res, s);
816
817 let mut s = PolynomialIn::new("x", -3, vec![1., 7., -3.]);
818 let t = PolynomialIn::new("x", 3, vec![1., -7., 52.]);
819 let res = PolynomialIn::new("x", 0, vec![1., 0., 0., 385., -156.]);
820 s *= &t;
821 assert_eq!(res, s);
822 let mut s = PolynomialIn::new("x", -3, vec![1., 7., -3.]);
823 s *= t;
824 assert_eq!(res, s);
825 }
826
827 #[test]
828 fn tst_poly_var() {
829 let _ = PolynomialIn::new(String::from("x"), -3, vec![1., 0., -3.]);
830 let _ = PolynomialIn::new('j', -3, vec![1., 0., -3.]);
831 let _ = PolynomialIn::new(8, -3, vec![1., 0., -3.]);
832 }
833
834 #[test]
835 fn tst_poly_scalar() {
836 let s = PolynomialIn::new("x", -3, vec![1., 0., -2.]);
837 let res = PolynomialIn::new("x", -3, vec![1. / 2., 0., -1.]);
838 assert_eq!(res, std::ops::Div::div(&s, 2.));
839 assert_eq!(res, &s / 2.);
840 let mut s = s;
841 s /= 2.;
842 assert_eq!(res, s);
843
844 let s = PolynomialIn::new("x", -3, vec![1. / 2., 0., -1.]);
845 let res = PolynomialIn::new("x", -3, vec![1., 0., -2.]);
846 assert_eq!(res, &s * 2.);
847 let mut s = s;
848 s *= 2.;
849 assert_eq!(res, s);
850
851 let s = PolynomialIn::new("x", -3, vec![1. / 2., 0., -1.]);
852 assert_eq!(s, &s + 0.);
853 let res = PolynomialIn::new("x", -3, vec![1. / 2., 0., -1., 2.]);
854 assert_eq!(res, &s + 2.);
855 let s = PolynomialIn::new("x", -2, vec![1. / 2., 0., -1.]);
856 let res = PolynomialIn::new("x", -2, vec![1. / 2., 0., 1.]);
857 assert_eq!(s, &s + 0.);
858 assert_eq!(res, s + 2.);
859 let s = PolynomialIn::new("x", 2, vec![1. / 2., 0., -1.]);
860 let res = PolynomialIn::new("x", 0, vec![2., 0., 1. / 2., 0., -1.]);
861 assert_eq!(s, &s + 0.);
862 assert_eq!(res, s + 2.);
863 let s = PolynomialIn::new("x", 0, vec![-2., 0., -1.]);
864 let res = PolynomialIn::new("x", 2, vec![-1.]);
865 assert_eq!(res, s + 2.);
866
867 let s = PolynomialIn::new("x", -3, vec![1. / 2., 0., -1.]);
868 assert_eq!(s, &s - 0.);
869 let res = PolynomialIn::new("x", -3, vec![1. / 2., 0., -1., -2.]);
870 assert_eq!(res, &s - 2.);
871 let s = PolynomialIn::new("x", -2, vec![1. / 2., 0., -1.]);
872 let res = PolynomialIn::new("x", -2, vec![1. / 2., 0., -3.]);
873 assert_eq!(s, &s - 0.);
874 assert_eq!(res, s - 2.);
875 let s = PolynomialIn::new("x", 2, vec![1. / 2., 0., -1.]);
876 let res = PolynomialIn::new("x", 0, vec![-2., 0., 1. / 2., 0., -1.]);
877 assert_eq!(s, &s - 0.);
878 assert_eq!(res, s - 2.);
879 let s = PolynomialIn::new("x", 0, vec![2., 0., -1.]);
880 let res = PolynomialIn::new("x", 2, vec![-1.]);
881 assert_eq!(res, s - 2.);
882 }
883
884 #[test]
885 #[should_panic]
886 fn tst_poly_bad_add() {
887 let s = PolynomialIn::new("x", -3, vec![1., 0., -3.]);
888 let t = PolynomialIn::new("y", -3, vec![1., 0., -3.]);
889 let _ = s + t;
890 }
891
892 #[test]
893 #[should_panic]
894 fn tst_poly_bad_sub() {
895 let s = PolynomialIn::new("x", -3, vec![1., 0., -3.]);
896 let t = PolynomialIn::new("y", -3, vec![1., 0., -3.]);
897 let _ = s - t;
898 }
899
900 #[test]
901 #[should_panic]
902 fn tst_poly_bad_mul() {
903 let s = PolynomialIn::new("x", -3, vec![1., 0., -3.]);
904 let t = PolynomialIn::new("y", -3, vec![1., 0., -3.]);
905 let _ = s * t;
906 }
907}