Skip to main content

series/
lib.rs

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