series/
lib.rs

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
34/// Minimum requirements on series coefficients
35pub trait Coeff: Zero + One + PartialEq {}
36impl<T: Zero + One + PartialEq> Coeff for T {}
37
38/// Immutable `Series` iterator.
39///
40/// This `struct` is created by the `iter` method on `Series`
41pub type Iter<'a, C> = Zip<RangeFrom<isize>, std::slice::Iter<'a, C>>;
42/// An iterator that moves out of a series.
43///
44/// This `struct` is created by the `into_iter` method on `Series`
45pub type IntoIter<C> = Zip<RangeFrom<isize>, std::vec::IntoIter<C>>;
46
47// test code in readme
48#[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", -10, vec!());
117        // assert_eq!(format!("{}", s), "O(x^-10)");
118        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        // disabled for floating-point inaccuracy
337        // let s = SeriesIn::new("x", -3, vec!(1.,0.,-3.));
338        // let t = SeriesIn::new("x", -1, vec!(3., 4., 5., 7.));
339        // let res = SeriesIn::new("x", -2, vec!(1./3.,-4./9.,-26./27.));
340        // assert_eq!(res, &s / &t);
341        // assert_eq!(res, &t / &s);
342        // assert_eq!(res, s / t);
343
344        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        // rescale result so we can use round and still get decent precision
452        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}