kalc_lib/
complex.rs

1use crate::{
2    complex::NumStr::{
3        Comma, Division, Exponent, Func, LeftBracket, LeftCurlyBracket, Matrix, Minus,
4        Multiplication, Num, Plus, RightBracket, RightCurlyBracket, Vector,
5    },
6    math::do_math,
7    misc::{do_math_with_var, place_funcvar, place_var},
8    parse::simplify,
9    units::{Number, Options, Units},
10};
11#[cfg(feature = "rayon")]
12use rayon::iter::{IntoParallelIterator, ParallelIterator};
13use rug::{
14    Complex, Float, Integer,
15    float::{
16        Constant::Pi,
17        Special::{Infinity, Nan},
18    },
19    integer::IsPrime,
20    ops::Pow,
21};
22#[cfg(feature = "serde")]
23use serde::{Deserialize, Serialize};
24use std::cmp::Ordering;
25#[derive(Clone, PartialEq, Debug)]
26#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
27pub enum NumStr {
28    Num(Box<Number>),
29    Func(String),
30    Vector(Vec<Number>),
31    Matrix(Vec<Vec<Number>>),
32    LeftBracket,
33    RightBracket,
34    LeftCurlyBracket,
35    RightCurlyBracket,
36    Comma,
37    Plus,
38    Minus,
39    PlusMinus,
40    Multiplication,
41    Division,
42    InternalMultiplication,
43    Tetration,
44    Root,
45    Exponent,
46    Equal,
47    NotEqual,
48    Greater,
49    GreaterEqual,
50    Lesser,
51    LesserEqual,
52    Modulo,
53    Range,
54    Conversion,
55    NearEqual,
56    ShiftLeft,
57    ShiftRight,
58    And,
59    Or,
60    Not,
61    Xor,
62    Nand,
63    Implies,
64    Nor,
65    Converse,
66}
67impl NumStr {
68    pub fn new(n: Number) -> Self {
69        Num(Box::new(n))
70    }
71}
72impl Number {
73    pub fn from(number: Complex, units: Option<Units>) -> Number {
74        Self { number, units }
75    }
76    pub fn set_prec(&mut self, prec: u32) {
77        self.number.set_prec(prec)
78    }
79    pub fn from_f64(f: f64, opt: &Options) -> Number {
80        let number = Complex::with_val(opt.prec, f);
81        let units = None;
82        Self { number, units }
83    }
84    pub fn new(opt: &Options) -> Number {
85        let number = Complex::new(opt.prec);
86        let units = None;
87        Self { number, units }
88    }
89    pub fn real(&self) -> &Float {
90        self.number.real()
91    }
92    pub fn imag(&self) -> &Float {
93        self.number.imag()
94    }
95}
96pub fn add(a: &Number, b: &Number) -> Number {
97    Number::from(
98        a.number.clone() + b.number.clone(),
99        if a.units == b.units { a.units } else { None },
100    )
101}
102pub fn sub(a: &Number, b: &Number) -> Number {
103    Number::from(
104        a.number.clone() - b.number.clone(),
105        if a.units == b.units { a.units } else { None },
106    )
107}
108pub fn set_prec(function: &mut [NumStr], func_vars: &mut [(String, Vec<NumStr>)], prec: u32) {
109    function.iter_mut().for_each(|n| n.set_prec(prec));
110    func_vars
111        .iter_mut()
112        .for_each(|(_, f)| f.iter_mut().for_each(|n| n.set_prec(prec)));
113}
114impl NumStr {
115    pub fn set_prec(&mut self, prec: u32) {
116        match self {
117            Num(n) => n.set_prec(prec),
118            Vector(v) => v.iter_mut().for_each(|n| n.set_prec(prec)),
119            Matrix(m) => m
120                .iter_mut()
121                .for_each(|v| v.iter_mut().for_each(|n| n.set_prec(prec))),
122            _ => {}
123        }
124    }
125    pub fn mul(&self, b: &Self) -> Result<Self, &'static str> {
126        fn m(a: &Number, b: &Number) -> Number {
127            Number::from(
128                {
129                    let a = a.number.clone();
130                    let b = b.number.clone();
131                    if a.real().is_infinite() || b.real().is_infinite() {
132                        if (a.real().is_infinite() && b.is_zero())
133                            || (b.real().is_infinite() && a.is_zero())
134                        {
135                            Complex::with_val(a.prec(), Nan)
136                        } else {
137                            match (a.real().is_sign_positive(), b.real().is_sign_positive()) {
138                                (true, true) | (false, false) => {
139                                    Complex::with_val(a.prec(), Infinity)
140                                }
141                                (false, true) | (true, false) => {
142                                    -Complex::with_val(a.prec(), Infinity)
143                                }
144                            }
145                        }
146                    } else {
147                        a * b.clone()
148                    }
149                },
150                match (a.units, b.units) {
151                    (Some(a), Some(b)) => Some(a.mul(&b)),
152                    (Some(a), None) | (None, Some(a)) => Some(a),
153                    (None, None) => None,
154                },
155            )
156        }
157        Ok(match (self, b) {
158            (Num(a), Num(b)) => NumStr::new(m(a, b)),
159            (Num(b), Vector(a)) | (Vector(a), Num(b)) => {
160                Vector(a.iter().map(|a| m(a, b)).collect())
161            }
162            (Vector(a), Vector(b)) if a.len() == b.len() => {
163                Vector(a.iter().zip(b.iter()).map(|(a, b)| m(a, b)).collect())
164            }
165            (Num(b), Matrix(a)) | (Matrix(a), Num(b)) => Matrix(
166                a.iter()
167                    .map(|a| a.iter().map(|a| m(a, b)).collect())
168                    .collect(),
169            ),
170            (Matrix(a), Vector(b)) if a.iter().all(|a| a.len() == b.len()) => Vector(
171                a.iter()
172                    .map(|a| {
173                        let mut iter = a.iter().zip(b.iter()).map(|(a, b)| m(a, b));
174                        let mut sum = iter.next().unwrap();
175                        for val in iter {
176                            sum = add(&sum, &val)
177                        }
178                        sum
179                    })
180                    .collect::<Vec<Number>>(),
181            ),
182            (Vector(a), Matrix(b)) if a.len() == b.len() => Vector(
183                transpose(b)
184                    .iter()
185                    .map(|b| {
186                        let mut iter = b.iter().zip(a.iter()).map(|(a, b)| m(a, b));
187                        let mut sum = iter.next().unwrap();
188                        for val in iter {
189                            sum = add(&sum, &val)
190                        }
191                        sum
192                    })
193                    .collect::<Vec<Number>>(),
194            ),
195            (Matrix(a), Matrix(b)) if a.iter().all(|a| a.len() == b.len()) => Matrix(
196                a.iter()
197                    .map(|a| {
198                        transpose(b)
199                            .iter()
200                            .map(|b| {
201                                let mut iter = a.iter().zip(b.iter()).map(|(a, b)| m(a, b));
202                                let mut sum = iter.next().unwrap();
203                                for val in iter {
204                                    sum = add(&sum, &val)
205                                }
206                                sum
207                            })
208                            .collect::<Vec<Number>>()
209                    })
210                    .collect(),
211            ),
212            _ => return Err("mul err"),
213        })
214    }
215    pub fn pm(&self, b: &Self) -> Result<Self, &'static str> {
216        Ok(match (self, b) {
217            (Num(a), Num(b)) => Vector(vec![add(a, b), sub(a, b)]),
218            (Num(a), Vector(b)) => Vector(
219                b.iter()
220                    .map(|b| add(a, b))
221                    .chain(b.iter().map(|b| sub(a, b)))
222                    .collect(),
223            ),
224            (Vector(b), Num(a)) => Vector(
225                b.iter()
226                    .map(|b| add(b, a))
227                    .chain(b.iter().map(|b| sub(b, a)))
228                    .collect(),
229            ),
230            (Vector(a), Vector(b)) if a.len() == b.len() => Vector(
231                a.iter()
232                    .zip(b.iter())
233                    .map(|(a, b)| add(a, b))
234                    .chain(a.iter().zip(b.iter()).map(|(a, b)| sub(a, b)))
235                    .collect(),
236            ),
237            (Matrix(a), Num(b)) => Vector(
238                a.iter()
239                    .flat_map(|a| {
240                        a.iter()
241                            .map(|a| add(a, b))
242                            .chain(a.iter().map(|a| sub(a, b)))
243                            .collect::<Vec<Number>>()
244                    })
245                    .collect::<Vec<Number>>(),
246            ),
247            (Num(b), Matrix(a)) => Vector(
248                a.iter()
249                    .flat_map(|a| {
250                        a.iter()
251                            .map(|a| add(b, a))
252                            .chain(a.iter().map(|a| sub(b, a)))
253                            .collect::<Vec<Number>>()
254                    })
255                    .collect::<Vec<Number>>(),
256            ),
257            _ => return Err("plus-minus unsupported"),
258        })
259    }
260    pub fn pow(&self, b: &Self) -> Result<Self, &'static str> {
261        fn p(a: &Number, b: &Number) -> Number {
262            Number::from(
263                {
264                    let a = a.number.clone();
265                    let b = b.number.clone();
266                    if a.real().is_infinite() {
267                        if b.is_zero() {
268                            Complex::with_val(a.prec(), Nan)
269                        } else if b.real().is_sign_positive() {
270                            Complex::with_val(a.prec(), Infinity)
271                        } else {
272                            Complex::new(a.prec())
273                        }
274                    } else if b.real().is_infinite() {
275                        if a.clone().abs() == 1 {
276                            Complex::with_val(a.prec(), Nan)
277                        } else if b.real().is_sign_positive() == a.real().clone().trunc().is_zero()
278                        {
279                            Complex::new(a.prec())
280                        } else {
281                            Complex::with_val(a.prec(), Infinity)
282                        }
283                    } else if a.is_zero() && b.real().is_zero() {
284                        Complex::with_val(a.prec(), Nan)
285                    } else {
286                        pow_nth(a, b)
287                    }
288                },
289                match (a.units, b.units) {
290                    (Some(a), None) => Some(a.pow(b.number.real().to_f64())),
291                    _ => None,
292                },
293            )
294        }
295        Ok(match (self, b) {
296            (Num(a), Num(b)) => NumStr::new(p(a, b)),
297            (Num(a), Vector(b)) => Vector(b.iter().map(|b| p(a, b)).collect()),
298            (Vector(a), Num(b)) => Vector(a.iter().map(|a| p(a, b)).collect()),
299            (Vector(a), Vector(b)) if a.len() == b.len() => {
300                Vector(a.iter().zip(b.iter()).map(|(a, b)| p(a, b)).collect())
301            }
302            (Num(a), Matrix(b)) => Matrix(
303                b.iter()
304                    .map(|b| b.iter().map(|b| p(a, b)).collect())
305                    .collect(),
306            ),
307            (Matrix(a), Num(b)) if a.iter().all(|c| a.len() == c.len()) => {
308                let b = b.number.clone();
309                if b.imag().is_zero() && b.real().clone().fract().is_zero() {
310                    if b.real().is_zero() {
311                        let mut mat = Vec::with_capacity(a.len().max(1));
312                        for i in 0..a.len() {
313                            let mut vec = Vec::with_capacity(a.len().max(1));
314                            for j in 0..a.len() {
315                                vec.push(if i == j {
316                                    Number::from(Complex::with_val(a[0][0].number.prec(), 1), None)
317                                } else {
318                                    Number::from(Complex::new(a[0][0].number.prec()), None)
319                                })
320                            }
321                            mat.push(vec);
322                        }
323                        Matrix(mat)
324                    } else {
325                        let mut mat = Matrix(a.clone());
326                        let c = b
327                            .real()
328                            .clone()
329                            .abs()
330                            .to_integer()
331                            .unwrap_or_default()
332                            .to_usize()
333                            .unwrap_or_default();
334                        for _ in 1..c {
335                            mat = mat.mul(&Matrix(a.clone()))?;
336                        }
337                        if b.real().is_sign_positive() {
338                            mat
339                        } else {
340                            Matrix(inverse(&mat.mat()?)?)
341                        }
342                    }
343                } else {
344                    return Err("no imag/fractional support for matrix powers");
345                }
346            }
347            (Vector(b), Matrix(a)) if b.len() == a.len() => Matrix(
348                a.iter()
349                    .zip(b.iter())
350                    .map(|(a, b)| a.iter().map(|a| p(b, a)).collect())
351                    .collect(),
352            ),
353            (Matrix(a), Vector(b)) if a.len() == b.len() => Matrix(
354                a.iter()
355                    .zip(b.iter())
356                    .map(|(a, b)| a.iter().map(|a| p(a, b)).collect())
357                    .collect(),
358            ),
359            (Matrix(a), Vector(b)) if a.iter().all(|a| a.len() == b.len()) => Matrix(
360                a.iter()
361                    .map(|a| a.iter().zip(b.iter()).map(|(a, b)| p(a, b)).collect())
362                    .collect(),
363            ),
364            (Matrix(a), Matrix(b)) if a[0].len() == b[0].len() && a.len() == b.len() => Matrix(
365                a.iter()
366                    .zip(b.iter())
367                    .map(|(a, b)| {
368                        a.iter()
369                            .zip(b.iter())
370                            .map(|(a, b)| p(a, b))
371                            .collect::<Vec<Number>>()
372                    })
373                    .collect(),
374            ),
375            _ => return Err("pow err"),
376        })
377    }
378    pub fn func<F>(&self, b: &Self, func: F) -> Result<Self, &'static str>
379    where
380        F: Fn(&Number, &Number) -> Number,
381    {
382        Ok(match (self, b) {
383            (Num(a), Num(b)) => NumStr::new(func(a, b)),
384            (Num(a), Vector(b)) => Vector(b.iter().map(|b| func(a, b)).collect()),
385            (Vector(a), Num(b)) => Vector(a.iter().map(|a| func(a, b)).collect()),
386            (Num(a), Matrix(b)) => Matrix(
387                b.iter()
388                    .map(|b| b.iter().map(|b| func(a, b)).collect())
389                    .collect(),
390            ),
391            (Matrix(a), Num(b)) => Matrix(
392                a.iter()
393                    .map(|a| a.iter().map(|a| func(a, b)).collect())
394                    .collect(),
395            ),
396            (Vector(a), Vector(b)) if a.len() == b.len() => {
397                Vector(a.iter().zip(b.iter()).map(|(a, b)| func(a, b)).collect())
398            }
399            (Vector(b), Matrix(a)) if b.len() == a.len() => Matrix(
400                a.iter()
401                    .zip(b.iter())
402                    .map(|(a, b)| a.iter().map(|a| func(b, a)).collect())
403                    .collect(),
404            ),
405            (Matrix(a), Vector(b)) if a.len() == b.len() => Matrix(
406                a.iter()
407                    .zip(b.iter())
408                    .map(|(a, b)| a.iter().map(|a| func(a, b)).collect())
409                    .collect(),
410            ),
411            (Matrix(a), Vector(b)) if a.iter().all(|a| a.len() == b.len()) => Matrix(
412                a.iter()
413                    .map(|a| a.iter().zip(b.iter()).map(|(a, b)| func(a, b)).collect())
414                    .collect(),
415            ),
416            (Matrix(a), Matrix(b)) if a[0].len() == b[0].len() && a.len() == b.len() => Matrix(
417                a.iter()
418                    .zip(b.iter())
419                    .map(|(a, b)| {
420                        a.iter()
421                            .zip(b.iter())
422                            .map(|(a, b)| func(a, b))
423                            .collect::<Vec<Number>>()
424                    })
425                    .collect(),
426            ),
427            _ => return Err("operation err"),
428        })
429    }
430    pub fn str_is(&self, s: &str) -> bool {
431        match self {
432            Func(s2) => s == s2,
433            _ => false,
434        }
435    }
436    pub fn num(&self) -> Result<Number, &'static str> {
437        match self {
438            Num(n) => Ok(*n.clone()),
439            _ => Err("failed to get number"),
440        }
441    }
442    pub fn vec(&self) -> Result<Vec<Number>, &'static str> {
443        match self {
444            Vector(v) => Ok(v.clone()),
445            _ => Err("failed to get vector"),
446        }
447    }
448    pub fn mat(&self) -> Result<Vec<Vec<Number>>, &'static str> {
449        match self {
450            Matrix(m) => Ok(m.clone()),
451            _ => Err("failed to get matrix"),
452        }
453    }
454}
455pub fn and(a: &Number, b: &Number) -> Number {
456    let a = &a.number;
457    let b = &b.number;
458    Number::from(
459        Complex::with_val(
460            a.prec(),
461            (a.imag().is_zero() && b.imag().is_zero() && a.real() == &1 && b.real() == &1) as u8,
462        ),
463        None,
464    )
465}
466pub fn or(a: &Number, b: &Number) -> Number {
467    let a = &a.number;
468    let b = &b.number;
469    Number::from(
470        Complex::with_val(
471            a.prec(),
472            (a.imag().is_zero() && b.imag().is_zero() && (a.real() == &1 || b.real() == &1)) as u8,
473        ),
474        None,
475    )
476}
477pub fn xor(a: &Number, b: &Number) -> Number {
478    let a = &a.number;
479    let b = &b.number;
480    Number::from(
481        Complex::with_val(
482            a.prec(),
483            (a.imag().is_zero() && b.imag().is_zero() && ((a.real() == &1) ^ (b.real() == &1)))
484                as u8,
485        ),
486        None,
487    )
488}
489pub fn nand(a: &Number, b: &Number) -> Number {
490    let a = &a.number;
491    let b = &b.number;
492    Number::from(
493        Complex::with_val(
494            a.prec(),
495            (a.imag().is_zero() && b.imag().is_zero() && (a.real() != &1 || b.real() != &1)) as u8,
496        ),
497        None,
498    )
499}
500pub fn nor(a: &Number, b: &Number) -> Number {
501    let a = &a.number;
502    let b = &b.number;
503    Number::from(
504        Complex::with_val(
505            a.prec(),
506            (a.imag().is_zero() && b.imag().is_zero() && (a.real() != &1 && b.real() != &1)) as u8,
507        ),
508        None,
509    )
510}
511pub fn implies(a: &Number, b: &Number) -> Number {
512    let a = &a.number;
513    let b = &b.number;
514    Number::from(
515        Complex::with_val(
516            a.prec(),
517            (a.imag().is_zero() && b.imag().is_zero() && (a.real() != &1 || b.real() == &1)) as u8,
518        ),
519        None,
520    )
521}
522pub fn not(a: &NumStr) -> Result<NumStr, &'static str> {
523    match a {
524        Num(a) => {
525            let a = &a.number;
526            Ok(NumStr::new(Number::from(
527                Complex::with_val(a.prec(), (a.imag().is_zero() && a.real() != &1) as u8),
528                None,
529            )))
530        }
531        Vector(v) => {
532            let mut o = Vec::with_capacity(v.len().max(1));
533            for a in v {
534                o.push(Number::from(
535                    Complex::with_val(a.number.prec(), a.number.is_zero() && a.number.real() != &1),
536                    None,
537                ));
538            }
539            Ok(Vector(o))
540        }
541        Matrix(m) => {
542            let mut k = Vec::with_capacity(m.len().max(1));
543            for v in m {
544                let mut o = Vec::with_capacity(v.len().max(1));
545                for a in v {
546                    o.push(Number::from(
547                        Complex::with_val(
548                            a.number.prec(),
549                            a.number.is_zero() && a.number.real() != &1,
550                        ),
551                        None,
552                    ));
553                }
554                k.push(o)
555            }
556            Ok(Matrix(k))
557        }
558        _ => Err("bad not input"),
559    }
560}
561pub fn div(a: &Number, b: &Number) -> Number {
562    Number::from(
563        {
564            let a = a.number.clone();
565            let b = b.number.clone();
566            if b.is_zero() || a.real().is_infinite() {
567                if a.is_zero() || b.real().is_infinite() {
568                    Complex::with_val(a.prec(), Nan)
569                } else if a.real().is_sign_positive() == b.real().is_sign_positive() {
570                    Complex::with_val(a.prec(), Infinity)
571                } else {
572                    -Complex::with_val(a.prec(), Infinity)
573                }
574            } else {
575                a / b.clone()
576            }
577        },
578        match (a.units, b.units) {
579            (Some(a), Some(b)) => Some(a.div(&b)),
580            (Some(a), None) => Some(a),
581            (None, Some(b)) => Some(Units::default().div(&b)),
582            (None, None) => None,
583        },
584    )
585}
586pub fn root(a: &Number, b: &Number) -> Number {
587    Number::from(
588        {
589            let a = a.number.clone();
590            let b = b.number.clone();
591            if b == 2 {
592                a.sqrt()
593            } else if b.imag().is_zero()
594                && b.real().clone() % 2 == 0
595                && b.real().clone().fract().is_zero()
596                && a.imag().is_zero()
597                && a.real().is_sign_negative()
598            {
599                -pow_nth(-a, b.recip())
600            } else {
601                pow_nth(a, b.recip())
602            }
603        },
604        match (a.units, b.units) {
605            (Some(a), None) => Some(a.root(b.number.real().to_f64())),
606            _ => None,
607        },
608    )
609}
610pub fn unity(y: Complex, x: Complex) -> Vec<Number> {
611    if y.is_zero() {
612        let n = x
613            .into_real_imag()
614            .0
615            .trunc()
616            .to_integer()
617            .unwrap_or_default()
618            .to_i128()
619            .unwrap_or_default() as usize;
620        return vec![Number::from(Complex::new(y.prec()), None); n];
621    }
622    let y = y.ln();
623    let mut vec: Vec<Number> = Vec::new();
624    let taui: Complex = 2 * Complex::with_val(x.prec(), (0, Pi));
625    let r: Float = x.imag().clone().pow(2) / 2;
626    let r: Float = x.real().clone() / 2 + r / x.real().clone();
627    let n = (x.imag().clone() * y.real() / x.real() - y.imag()) / taui.imag().clone();
628    let left: Float = n.clone() - r.clone();
629    let right: Float = r + n;
630    for k in if left < right {
631        left.clone()
632            .trunc()
633            .to_integer()
634            .unwrap_or_default()
635            .to_i128()
636            .unwrap_or_default()
637            ..=if left.clone().fract().is_zero() && right.clone().fract().is_zero() {
638                right
639                    .clone()
640                    .trunc()
641                    .to_integer()
642                    .unwrap_or_default()
643                    .to_i128()
644                    .unwrap_or_default()
645                    - 1
646            } else {
647                right
648                    .clone()
649                    .trunc()
650                    .to_integer()
651                    .unwrap_or_default()
652                    .to_i128()
653                    .unwrap_or_default()
654            }
655    } else {
656        right
657            .clone()
658            .trunc()
659            .to_integer()
660            .unwrap_or_default()
661            .to_i128()
662            .unwrap_or_default()
663            ..=if left.clone().fract().is_zero() && right.clone().fract().is_zero() {
664                left.clone()
665                    .trunc()
666                    .to_integer()
667                    .unwrap_or_default()
668                    .to_i128()
669                    .unwrap_or_default()
670                    - 1
671            } else {
672                left.clone()
673                    .trunc()
674                    .to_integer()
675                    .unwrap_or_default()
676                    .to_i128()
677                    .unwrap_or_default()
678            }
679    } {
680        let r: Complex = (y.clone() + k * taui.clone()) / x.clone();
681        let r: Complex = r.exp();
682        vec.push(Number::from(r, None))
683    }
684    vec
685}
686pub fn shl(a: &Number, b: &Number) -> Number {
687    Number::from(
688        a.number.clone() * pow_nth(Complex::with_val(a.number.prec(), 2), b.number.clone()),
689        None,
690    )
691}
692pub fn shr(a: &Number, b: &Number) -> Number {
693    Number::from(
694        a.number.clone() * pow_nth(Complex::with_val(a.number.prec(), 2), -b.number.clone()),
695        None,
696    )
697}
698pub fn ne(a: &Number, b: &Number) -> Number {
699    let ua = a.units;
700    let ub = b.units;
701    let a = a.number.clone();
702    let b = b.number.clone();
703    let c: Complex = a.clone() - b.clone();
704    let int = Integer::from(10).pow(a.prec().0 / 4);
705    let re: Float = c.real().clone() * int.clone();
706    let re: Float = re.round() / int.clone();
707    let im: Float = c.imag().clone() * int.clone();
708    let im: Float = im.round() / int;
709    Number::from(
710        Complex::with_val(
711            a.prec(),
712            ((!(re.is_zero()
713                || (a.real().is_infinite()
714                    && b.real().is_infinite()
715                    && a.real().is_sign_positive() == b.real().is_sign_positive()))
716                || !(im.is_zero()
717                    || (a.imag().is_infinite()
718                        && b.imag().is_infinite()
719                        && a.imag().is_sign_positive() == b.imag().is_sign_positive())))
720                || match (ua, ub) {
721                    (Some(a), Some(b)) => a != b,
722                    (Some(a), None) | (None, Some(a)) => !a.is_none(),
723                    (None, None) => false,
724                }) as u8,
725        ),
726        None,
727    )
728}
729pub fn eq(a: &Number, b: &Number) -> Number {
730    let ua = a.units;
731    let ub = b.units;
732    let a = a.number.clone();
733    let b = b.number.clone();
734    let c: Complex = a.clone() - b.clone();
735    let int = Integer::from(10).pow(a.prec().0 / 4);
736    let re: Float = c.real().clone() * int.clone();
737    let re: Float = re.round() / int.clone();
738    let im: Float = c.imag().clone() * int.clone();
739    let im: Float = im.round() / int;
740    Number::from(
741        Complex::with_val(
742            a.prec(),
743            ((re.is_zero()
744                || (a.real().is_infinite()
745                    && b.real().is_infinite()
746                    && a.real().is_sign_positive() == b.real().is_sign_positive())
747                    && im.is_zero()
748                || (a.imag().is_infinite()
749                    && b.imag().is_infinite()
750                    && a.imag().is_sign_positive() == b.imag().is_sign_positive()))
751                && match (ua, ub) {
752                    (Some(a), Some(b)) => a == b,
753                    (Some(a), None) | (None, Some(a)) => a.is_none(),
754                    (None, None) => true,
755                }) as u8,
756        ),
757        None,
758    )
759}
760pub fn about_eq(a: &Number, b: &Number) -> Number {
761    let ua = a.units;
762    let ub = b.units;
763    let a = a.number.clone();
764    let b = b.number.clone();
765    Number::from(
766        Complex::with_val(
767            a.prec(),
768            ((a.real().is_sign_positive() == b.real().is_sign_positive()
769                && a.imag().is_sign_positive() == b.imag().is_sign_positive()
770                && a.real().clone().abs().log10().floor()
771                    == b.real().clone().abs().log10().floor()
772                && a.imag().clone().abs().log10().floor()
773                    == b.imag().clone().abs().log10().floor())
774                && match (ua, ub) {
775                    (Some(a), Some(b)) => a == b,
776                    (Some(a), None) | (None, Some(a)) => a.is_none(),
777                    (None, None) => true,
778                }) as u8,
779        ),
780        None,
781    )
782}
783pub fn ge(a: &Number, b: &Number) -> Number {
784    Number::from(
785        Complex::with_val(a.number.prec(), (a.number.real() >= b.number.real()) as u8),
786        None,
787    )
788}
789pub fn gt(a: &Number, b: &Number) -> Number {
790    Number::from(
791        Complex::with_val(a.number.prec(), (a.number.real() > b.number.real()) as u8),
792        None,
793    )
794}
795pub fn rem(a: &Number, b: &Number) -> Number {
796    let a = &a.number;
797    let b = &b.number;
798    let c = a.clone() / b.clone();
799    let c = Complex::with_val(
800        a.prec(),
801        (c.real().clone().floor(), c.imag().clone().floor()),
802    );
803    Number::from(a - b * c, None)
804}
805pub fn digamma(mut z: Complex, mut n: u32) -> Complex {
806    n += 1;
807    let oop = z.prec();
808    let op = oop.0 / 2;
809    let prec = n * op;
810    z.set_prec(prec);
811    let h: Float = Float::with_val(prec, 0.5).pow(op / 2);
812    let num = Integer::from(n);
813    let mut sum = Complex::new(prec);
814    for k in 0..=n {
815        if k % 2 == 0 {
816            sum += num.clone().binomial(k) * gamma(z.clone() + h.clone() * (n - k)).ln()
817        } else {
818            sum -= num.clone().binomial(k) * gamma(z.clone() + h.clone() * (n - k)).ln()
819        }
820    }
821    let mut n = sum * Float::with_val(prec, 2).pow(op / 2 * n);
822    n.set_prec(oop);
823    n
824}
825pub fn gamma(a: Complex) -> Complex {
826    if !a.imag().is_zero() {
827        gamma0(a)
828    } else if a.real().is_sign_negative() && a.real().clone().fract().is_zero() {
829        Complex::with_val(a.prec(), Infinity)
830    } else {
831        a.real().clone().gamma().into()
832    }
833}
834pub fn tetration(a: &Number, b: &Number) -> Number {
835    let a = a.number.clone();
836    let b = b.number.clone();
837    Number::from(
838        if b.real().clone().fract().is_zero() {
839            if b == 0 {
840                Complex::with_val(a.prec(), 1)
841            } else if b.real().is_sign_positive() {
842                (1..b
843                    .real()
844                    .to_integer()
845                    .unwrap_or_default()
846                    .to_usize()
847                    .unwrap_or_default())
848                    .fold(a.clone(), |tetration, _| pow_nth(a.clone(), tetration))
849            } else if b == -1 {
850                Complex::new(a.prec())
851            } else {
852                Complex::with_val(a.prec(), (Infinity, Nan))
853            }
854        } else {
855            tetration_recursion(a.clone(), b.clone())
856        },
857        None,
858    )
859}
860fn tetration_recursion(a: Complex, b: Complex) -> Complex {
861    if b.real().is_sign_positive() {
862        pow_nth(a.clone(), tetration_recursion(a, b - 1))
863    } else if b.real() <= &-1 {
864        tetration_recursion(a.clone(), b + 1).ln() / a.ln()
865    } else {
866        let aln = a.abs().clone().ln();
867        1 + b.clone() * (aln.clone() * (2 + b.clone()) - b) / (1 + aln)
868    }
869}
870pub fn slog(a: &Complex, b: &Complex) -> Complex {
871    if b.real() <= &0 {
872        let z = &pow_nth(a.clone(), b.clone());
873        if z.real() <= b.real() {
874            Complex::with_val(a.prec(), Nan)
875        } else {
876            slog(a, z) - 1
877        }
878    } else if b.real() > &1 {
879        let z = &(b.clone().ln() / a.clone().ln());
880        if z.real() >= b.real() {
881            Complex::with_val(a.prec(), Nan)
882        } else {
883            slog(a, z) + 1
884        }
885    } else {
886        let a = a.clone().ln();
887        b.clone() * (2 * a.clone() + b * (1 - a.clone())) / (1 + a) - 1
888    }
889}
890pub fn atan(a: Complex, b: Complex) -> Complex {
891    if a.imag().is_zero() && b.imag().is_zero() {
892        Complex::with_val(a.prec(), (a.real(), b.real())).arg()
893    } else {
894        let i = Complex::with_val(a.prec(), (0, 1));
895        let abs: Complex = sqr(a.clone()) + sqr(b.clone());
896        -i.clone() * ((a + b * i) / abs.sqrt()).ln()
897    }
898}
899pub fn to_polar(mut a: Vec<Number>, to_deg: Complex) -> Vec<Number> {
900    if a.len() == 1 {
901        a.push(Number::from(Complex::new(a[0].number.prec()), None));
902    }
903    if a.len() != 2 && a.len() != 3 {
904        a
905    } else if a.len() == 2 {
906        if a[1].number.is_zero() {
907            if a[0].number.is_zero() {
908                vec![
909                    Number::from(Complex::new(a[0].number.prec()), None),
910                    Number::from(
911                        Complex::new(a[0].number.prec()),
912                        Some(Units {
913                            angle: 1.0,
914                            ..Units::default()
915                        }),
916                    ),
917                ]
918            } else {
919                vec![
920                    Number::from(a[0].number.clone().abs(), a[0].units),
921                    Number::from(
922                        if a[0].number.real().is_sign_positive() {
923                            Complex::new(a[0].number.prec())
924                        } else {
925                            to_deg * Float::with_val(a[0].number.prec().0, Pi)
926                        },
927                        Some(Units {
928                            angle: 1.0,
929                            ..Units::default()
930                        }),
931                    ),
932                ]
933            }
934        } else {
935            let mut n: Complex = sqr(a[0].number.clone()) + sqr(a[1].number.clone());
936            n = n.sqrt();
937            vec![
938                Number::from(n.clone(), a[0].units),
939                Number::from(
940                    atan(a[0].number.clone(), a[1].number.clone()) * to_deg,
941                    Some(Units {
942                        angle: 1.0,
943                        ..Units::default()
944                    }),
945                ),
946            ]
947        }
948    } else if a[1].number.is_zero() {
949        if a[0].number.is_zero() {
950            if a[2].number.is_zero() {
951                vec![
952                    Number::from(Complex::new(a[0].number.prec()), None),
953                    Number::from(
954                        Complex::new(a[0].number.prec()),
955                        Some(Units {
956                            angle: 1.0,
957                            ..Units::default()
958                        }),
959                    ),
960                    Number::from(
961                        Complex::new(a[0].number.prec()),
962                        Some(Units {
963                            angle: 1.0,
964                            ..Units::default()
965                        }),
966                    ),
967                ]
968            } else {
969                vec![
970                    Number::from(a[2].number.clone().abs(), a[2].units),
971                    Number::from(
972                        Complex::new(a[0].number.prec()),
973                        Some(Units {
974                            angle: 1.0,
975                            ..Units::default()
976                        }),
977                    ),
978                    Number::from(
979                        Complex::new(a[0].number.prec()),
980                        Some(Units {
981                            angle: 1.0,
982                            ..Units::default()
983                        }),
984                    ),
985                ]
986            }
987        } else {
988            let nxy: Complex = sqr(a[0].number.clone()) + sqr(a[1].number.clone());
989            let mut n: Complex = nxy.clone() + sqr(a[2].number.clone());
990            n = n.sqrt();
991            vec![
992                Number::from(n.clone(), a[0].units),
993                Number::from(
994                    atan(a[2].number.clone(), nxy.sqrt()) * to_deg.clone(),
995                    Some(Units {
996                        angle: 1.0,
997                        ..Units::default()
998                    }),
999                ),
1000                Number::from(
1001                    Complex::new(a[0].number.prec()),
1002                    Some(Units {
1003                        angle: 1.0,
1004                        ..Units::default()
1005                    }),
1006                ),
1007            ]
1008        }
1009    } else {
1010        let nxy: Complex = sqr(a[0].number.clone()) + sqr(a[1].number.clone());
1011        let mut n: Complex = nxy.clone() + sqr(a[2].number.clone());
1012        n = n.sqrt();
1013        vec![
1014            Number::from(n.clone(), a[0].units),
1015            Number::from(
1016                atan(a[2].number.clone(), nxy.sqrt()) * to_deg.clone(),
1017                Some(Units {
1018                    angle: 1.0,
1019                    ..Units::default()
1020                }),
1021            ),
1022            Number::from(
1023                atan(a[0].number.clone(), a[1].number.clone()) * to_deg.clone(),
1024                Some(Units {
1025                    angle: 1.0,
1026                    ..Units::default()
1027                }),
1028            ),
1029        ]
1030    }
1031}
1032pub fn to_cyl(mut a: Vec<Number>, to_deg: Complex) -> Vec<Number> {
1033    if a.len() == 1 {
1034        a.push(Number::from(Complex::new(a[0].number.prec()), None));
1035    }
1036    if a.len() != 2 && a.len() != 3 {
1037        a
1038    } else if a.len() == 2 {
1039        if a[1].number.is_zero() {
1040            if a[0].number.is_zero() {
1041                vec![
1042                    Number::from(Complex::new(a[0].number.prec()), None),
1043                    Number::from(
1044                        Complex::new(a[0].number.prec()),
1045                        Some(Units {
1046                            angle: 1.0,
1047                            ..Units::default()
1048                        }),
1049                    ),
1050                ]
1051            } else {
1052                vec![
1053                    Number::from(a[0].number.clone().abs(), a[0].units),
1054                    Number::from(
1055                        if a[0].number.real().is_sign_positive() {
1056                            Complex::new(a[0].number.prec())
1057                        } else {
1058                            to_deg * Float::with_val(a[0].number.prec().0, Pi)
1059                        },
1060                        Some(Units {
1061                            angle: 1.0,
1062                            ..Units::default()
1063                        }),
1064                    ),
1065                ]
1066            }
1067        } else {
1068            let mut n: Complex = sqr(a[0].number.clone()) + sqr(a[1].number.clone());
1069            n = n.sqrt();
1070            vec![
1071                Number::from(n.clone(), a[0].units),
1072                Number::from(
1073                    atan(a[0].number.clone(), a[1].number.clone()) * to_deg,
1074                    Some(Units {
1075                        angle: 1.0,
1076                        ..Units::default()
1077                    }),
1078                ),
1079            ]
1080        }
1081    } else if a[1].number.is_zero() {
1082        if a[0].number.is_zero() {
1083            if a[2].number.is_zero() {
1084                vec![
1085                    Number::from(Complex::new(a[0].number.prec()), None),
1086                    Number::from(
1087                        Complex::new(a[0].number.prec()),
1088                        Some(Units {
1089                            angle: 1.0,
1090                            ..Units::default()
1091                        }),
1092                    ),
1093                    Number::from(Complex::new(a[0].number.prec()), None),
1094                ]
1095            } else {
1096                vec![
1097                    Number::from(Complex::new(a[0].number.prec()), None),
1098                    Number::from(
1099                        Complex::new(a[0].number.prec()),
1100                        Some(Units {
1101                            angle: 1.0,
1102                            ..Units::default()
1103                        }),
1104                    ),
1105                    Number::from(a[2].number.clone().abs(), a[2].units),
1106                ]
1107            }
1108        } else {
1109            let nxy: Complex = sqr(a[0].number.clone()) + sqr(a[1].number.clone());
1110            vec![
1111                Number::from(nxy.sqrt(), a[0].units),
1112                Number::from(
1113                    atan(a[0].number.clone(), a[1].number.clone()) * to_deg.clone(),
1114                    Some(Units {
1115                        angle: 1.0,
1116                        ..Units::default()
1117                    }),
1118                ),
1119                a[2].clone(),
1120            ]
1121        }
1122    } else {
1123        let nxy: Complex = sqr(a[0].number.clone()) + sqr(a[1].number.clone());
1124        vec![
1125            Number::from(nxy.sqrt(), a[0].units),
1126            Number::from(
1127                atan(a[0].number.clone(), a[1].number.clone()) * to_deg.clone(),
1128                Some(Units {
1129                    angle: 1.0,
1130                    ..Units::default()
1131                }),
1132            ),
1133            a[2].clone(),
1134        ]
1135    }
1136}
1137pub fn to(a: &NumStr, b: &NumStr) -> Result<NumStr, &'static str> {
1138    Ok(match (a, b) {
1139        (Num(a), Num(b)) => {
1140            let prec = a.number.prec();
1141            let a = a
1142                .number
1143                .real()
1144                .to_integer()
1145                .unwrap_or_default()
1146                .to_isize()
1147                .unwrap_or_default();
1148            let b = b
1149                .number
1150                .real()
1151                .to_integer()
1152                .unwrap_or_default()
1153                .to_isize()
1154                .unwrap_or_default();
1155            let vec: Vec<Number> = if a < b {
1156                (a..=b)
1157                    .map(|a| Number::from(Complex::with_val(prec, a), None))
1158                    .collect()
1159            } else {
1160                (b..=a)
1161                    .rev()
1162                    .map(|a| Number::from(Complex::with_val(prec, a), None))
1163                    .collect()
1164            };
1165            if vec.is_empty() {
1166                return Err("start range greater then end range");
1167            }
1168            Vector(vec)
1169        }
1170        (Vector(a), Num(b)) => {
1171            let prec = b.number.prec();
1172            let b = b
1173                .number
1174                .real()
1175                .to_integer()
1176                .unwrap_or_default()
1177                .to_isize()
1178                .unwrap_or_default();
1179            let mat: Vec<Vec<Number>> = a
1180                .iter()
1181                .map(|a| {
1182                    let a = a
1183                        .number
1184                        .real()
1185                        .to_integer()
1186                        .unwrap_or_default()
1187                        .to_isize()
1188                        .unwrap_or_default();
1189                    if a < b {
1190                        (a..=b)
1191                            .map(|a| Number::from(Complex::with_val(prec, a), None))
1192                            .collect()
1193                    } else {
1194                        (b..=a)
1195                            .rev()
1196                            .map(|a| Number::from(Complex::with_val(prec, a), None))
1197                            .collect()
1198                    }
1199                })
1200                .collect();
1201            if mat.is_empty() || mat.iter().any(|vec| vec.is_empty()) {
1202                return Err("start range greater then end range");
1203            }
1204            Matrix(mat)
1205        }
1206        (Num(a), Vector(b)) => {
1207            let prec = a.number.prec();
1208            let a = a
1209                .number
1210                .real()
1211                .to_integer()
1212                .unwrap_or_default()
1213                .to_isize()
1214                .unwrap_or_default();
1215            let mat: Vec<Vec<Number>> = b
1216                .iter()
1217                .map(|b| {
1218                    let b = b
1219                        .number
1220                        .real()
1221                        .to_integer()
1222                        .unwrap_or_default()
1223                        .to_isize()
1224                        .unwrap_or_default();
1225                    if a < b {
1226                        (a..=b)
1227                            .map(|a| Number::from(Complex::with_val(prec, a), None))
1228                            .collect()
1229                    } else {
1230                        (b..=a)
1231                            .rev()
1232                            .map(|a| Number::from(Complex::with_val(prec, a), None))
1233                            .collect()
1234                    }
1235                })
1236                .collect();
1237            if mat.is_empty() || mat.iter().any(|vec| vec.is_empty()) {
1238                return Err("start range greater then end range");
1239            }
1240            Matrix(mat)
1241        }
1242        _ => return Err(".. err"),
1243    })
1244}
1245pub fn mvec(
1246    function: Vec<NumStr>,
1247    func_vars: Vec<(String, Vec<NumStr>)>,
1248    var: &str,
1249    start: isize,
1250    end: isize,
1251    mvec: bool,
1252    options: Options,
1253) -> Result<NumStr, &'static str> {
1254    let mut vec = Vec::new();
1255    let mut mat = Vec::new();
1256    let mut test = true;
1257    let mut body = |z: isize| -> Result<(), &'static str> {
1258        match do_math_with_var(
1259            function.clone(),
1260            options,
1261            func_vars.clone(),
1262            var,
1263            NumStr::new(Number::from(Complex::with_val(options.prec, z), None)),
1264        )? {
1265            Num(n) => {
1266                if test && vec.is_empty() {
1267                    test = false;
1268                    vec = Vec::with_capacity((end - start + 1).max(1) as usize)
1269                }
1270                vec.push(*n)
1271            }
1272            Vector(v) if mvec => {
1273                if test && vec.is_empty() {
1274                    test = false;
1275                    vec = Vec::with_capacity((end - start + 1).max(1) as usize * v.len())
1276                }
1277                vec.extend(v)
1278            }
1279            Vector(v) => {
1280                if test && mat.is_empty() {
1281                    test = false;
1282                    mat = Vec::with_capacity((end - start + 1).max(1) as usize)
1283                }
1284                mat.push(v)
1285            }
1286            Matrix(m) if !mvec => {
1287                if test && mat.is_empty() {
1288                    test = false;
1289                    mat = Vec::with_capacity((end - start + 1).max(1) as usize * m.len().max(1))
1290                }
1291                mat.extend(m)
1292            }
1293            _ => return Err("cant create 3d matrix"),
1294        }
1295        Ok(())
1296    };
1297    if start < end {
1298        for z in start..=end {
1299            body(z)?
1300        }
1301    } else {
1302        for z in (end..=start).rev() {
1303            body(z)?
1304        }
1305    }
1306    if mat.is_empty() {
1307        if vec.is_empty() {
1308            Err("start>end")
1309        } else {
1310            Ok(Vector(vec))
1311        }
1312    } else {
1313        Ok(Matrix(mat))
1314    }
1315}
1316pub fn sum(
1317    function: Vec<NumStr>,
1318    func_vars: Vec<(String, Vec<NumStr>)>,
1319    var: &str,
1320    mut start: Float,
1321    mut end: Float,
1322    product: bool,
1323    options: Options,
1324) -> Result<NumStr, &'static str> {
1325    if start > end {
1326        (start, end) = (end, start)
1327    }
1328    if end.is_infinite() {
1329        let mut j = 0;
1330        let mut n = start
1331            .to_integer()
1332            .unwrap_or_default()
1333            .to_isize()
1334            .unwrap_or_default();
1335        let k = if end.is_sign_positive() { 1 } else { -1 };
1336        let mut last = NumStr::new(Number::from(Complex::with_val(options.prec, Nan), None));
1337        let mut value = do_math_with_var(
1338            function.clone(),
1339            options,
1340            func_vars.clone(),
1341            var,
1342            NumStr::new(Number::from(Complex::with_val(options.prec, n), None)),
1343        )?;
1344        while last != value {
1345            if j > 10000 {
1346                return Ok(NumStr::new(Number::from(
1347                    Complex::with_val(options.prec, Nan),
1348                    None,
1349                )));
1350            }
1351            j += 1;
1352            n += k;
1353            last = value;
1354            let math = do_math_with_var(
1355                function.clone(),
1356                options,
1357                func_vars.clone(),
1358                var,
1359                NumStr::new(Number::from(Complex::with_val(options.prec, n), None)),
1360            )?;
1361            if product {
1362                value = last.mul(&math)?;
1363            } else {
1364                value = last.func(&math, add)?;
1365            }
1366        }
1367        Ok(value)
1368    } else if start.is_infinite() {
1369        return Err("unsupported due to lack of example for convergence");
1370    } else {
1371        let start = start
1372            .to_integer()
1373            .unwrap_or_default()
1374            .to_isize()
1375            .unwrap_or_default();
1376        let end = end
1377            .to_integer()
1378            .unwrap_or_default()
1379            .to_isize()
1380            .unwrap_or_default();
1381        let mut value = do_math_with_var(
1382            function.clone(),
1383            options,
1384            func_vars.clone(),
1385            var,
1386            NumStr::new(Number::from(Complex::with_val(options.prec, start), None)),
1387        )?;
1388        for z in start + 1..=end {
1389            let math = do_math_with_var(
1390                function.clone(),
1391                options,
1392                func_vars.clone(),
1393                var,
1394                NumStr::new(Number::from(Complex::with_val(options.prec, z), None)),
1395            )?;
1396            if product {
1397                value = value.mul(&math)?;
1398            } else {
1399                value = value.func(&math, add)?;
1400            }
1401        }
1402        Ok(value)
1403    }
1404}
1405pub fn submatrix(a: &[Vec<Number>], row: usize, col: usize) -> Vec<Vec<Number>> {
1406    a.iter()
1407        .enumerate()
1408        .filter(|&(i, _)| i != row)
1409        .map(|(_, r)| {
1410            r.iter()
1411                .enumerate()
1412                .filter(|&(j, _)| j != col)
1413                .map(|(_, value)| value.clone())
1414                .collect::<Vec<Number>>()
1415        })
1416        .collect()
1417}
1418pub fn trace(a: &[Vec<Number>]) -> Number {
1419    let mut n = Complex::new(a[0][0].number.prec());
1420    for (i, j) in a.iter().enumerate() {
1421        if j.len() == i {
1422            break;
1423        }
1424        n += j[i].number.clone();
1425    }
1426    Number::from(n, a[0][0].units)
1427}
1428pub fn identity(a: usize, prec: u32) -> Vec<Vec<Number>> {
1429    let mut mat = Vec::with_capacity(a.max(1));
1430    for i in 0..a {
1431        let mut vec = Vec::with_capacity(a.max(1));
1432        for j in 0..a {
1433            if i == j {
1434                vec.push(Number::from(Complex::with_val(prec, 1), None));
1435            } else {
1436                vec.push(Number::from(Complex::new(prec), None));
1437            }
1438        }
1439        mat.push(vec);
1440    }
1441    mat
1442}
1443pub fn determinant(a: &[Vec<Number>]) -> Result<Number, &'static str> {
1444    if !a.is_empty() && (0..a.len()).all(|j| a.len() == a[j].len()) {
1445        Ok(Number::from(
1446            match a.len() {
1447                1 => a[0][0].number.clone(),
1448                2 => {
1449                    a[0][0].number.clone() * a[1][1].number.clone()
1450                        - a[1][0].number.clone() * a[0][1].number.clone()
1451                }
1452                3 => {
1453                    a[0][0].number.clone()
1454                        * (a[1][1].number.clone() * a[2][2].number.clone()
1455                            - a[1][2].number.clone() * a[2][1].number.clone())
1456                        + a[0][1].number.clone()
1457                            * (a[1][2].number.clone() * a[2][0].number.clone()
1458                                - a[1][0].number.clone() * a[2][2].number.clone())
1459                        + a[0][2].number.clone()
1460                            * (a[1][0].number.clone() * a[2][1].number.clone()
1461                                - a[1][1].number.clone() * a[2][0].number.clone())
1462                }
1463                _ => {
1464                    let mut det = Complex::new(a[0][0].number.prec());
1465                    for (i, x) in a[0].iter().enumerate() {
1466                        let mut sub_matrix = a[1..].to_vec();
1467                        for row in &mut sub_matrix {
1468                            row.remove(i);
1469                        }
1470                        det += x.number.clone()
1471                            * determinant(&sub_matrix)?.number
1472                            * if i % 2 == 0 { 1.0 } else { -1.0 };
1473                    }
1474                    det
1475                }
1476            },
1477            a[0][0].units.map(|b| b.pow(a.len() as f64)),
1478        ))
1479    } else {
1480        Err("not square")
1481    }
1482}
1483pub fn transpose(a: &[Vec<Number>]) -> Vec<Vec<Number>> {
1484    let mut max = 0;
1485    for i in a {
1486        if i.len() > max {
1487            max = i.len()
1488        }
1489    }
1490    let mut b = vec![vec![Number::from(Complex::new(1), None); a.len()]; max];
1491    for (i, l) in a.iter().enumerate() {
1492        for (j, n) in l.iter().enumerate() {
1493            b[j][i].clone_from(n);
1494        }
1495    }
1496    b
1497}
1498pub fn minors(a: &[Vec<Number>]) -> Result<Vec<Vec<Number>>, &'static str> {
1499    if a.iter().all(|j| a.len() == j.len()) {
1500        let mut result = vec![vec![Number::from(Complex::new(1), None); a[0].len()]; a.len()];
1501        for (i, k) in result.iter_mut().enumerate() {
1502            for (j, l) in k.iter_mut().enumerate() {
1503                *l = determinant(&submatrix(a, i, j))?
1504            }
1505        }
1506        Ok(result)
1507    } else {
1508        Err("not square")
1509    }
1510}
1511pub fn cofactor(a: &[Vec<Number>]) -> Result<Vec<Vec<Number>>, &'static str> {
1512    if a.iter().all(|j| a.len() == j.len()) && !a.is_empty() {
1513        let mut result = vec![vec![Number::from(Complex::new(1), None); a[0].len()]; a.len()];
1514        for (i, k) in result.iter_mut().enumerate() {
1515            for (j, l) in k.iter_mut().enumerate() {
1516                *l = if (i + j) % 2 == 1 {
1517                    let a = determinant(&submatrix(a, i, j))?;
1518                    Number::from(-a.number, a.units)
1519                } else {
1520                    determinant(&submatrix(a, i, j))?
1521                };
1522            }
1523        }
1524        Ok(result)
1525    } else {
1526        Err("not square")
1527    }
1528}
1529pub fn inverse(a: &[Vec<Number>]) -> Result<Vec<Vec<Number>>, &'static str> {
1530    if (0..a.len()).all(|j| a.len() == a[j].len()) {
1531        Matrix(transpose(&cofactor(a)?))
1532            .func(&NumStr::new(determinant(a)?), div)?
1533            .mat()
1534    } else {
1535        Err("not square")
1536    }
1537}
1538pub fn nth_prime(n: Integer) -> Integer {
1539    let mut count = Integer::from(1);
1540    let mut num = Integer::from(3);
1541    if n == 0 {
1542        num = Integer::new()
1543    } else if n == 1 {
1544        num = Integer::from(2);
1545    }
1546    while count < n {
1547        if num.is_probably_prime(100) != IsPrime::No {
1548            count += 1;
1549        }
1550        if count < n {
1551            num += 2;
1552        }
1553    }
1554    num
1555}
1556pub fn prime_factors(mut n: Integer) -> Vec<(Integer, isize)> {
1557    if n < 2 {
1558        return Vec::new();
1559    }
1560    let mut mat = Vec::new();
1561    let mut prime = Integer::from(2);
1562    let mut k = 0;
1563    loop {
1564        let (temp, rem) = n.clone().div_rem(prime.clone());
1565        if rem == 0 {
1566            k += 1;
1567            if temp == 1 {
1568                mat.push((prime.clone(), k));
1569                break;
1570            }
1571            n = temp;
1572        } else {
1573            if k != 0 {
1574                mat.push((prime.clone(), k));
1575            }
1576            prime = prime.next_prime();
1577            k = 0;
1578        }
1579    }
1580    mat
1581}
1582pub fn sort(mut a: Vec<Number>) -> Vec<Number> {
1583    a.sort_by(|x, y| {
1584        x.number
1585            .real()
1586            .partial_cmp(y.number.real())
1587            .unwrap_or(Ordering::Equal)
1588    });
1589    a
1590}
1591pub fn sort_mat(mut a: Vec<Vec<Number>>, prec: u32) -> Vec<Vec<Number>> {
1592    a.sort_by(|x, y| {
1593        if x.is_empty() || y.is_empty() {
1594            Ordering::Equal
1595        } else {
1596            x.iter()
1597                .fold(Float::new(prec), |sum, val| sum + val.number.real())
1598                .partial_cmp(
1599                    &y.iter()
1600                        .fold(Float::new(prec), |sum, val| sum + val.number.real()),
1601                )
1602                .unwrap_or(Ordering::Equal)
1603        }
1604    });
1605    a.sort_by(|x, y| x.len().partial_cmp(&y.len()).unwrap_or(Ordering::Equal));
1606    a
1607}
1608pub fn eigenvalues(mat: &[Vec<Number>], real: bool) -> Result<NumStr, &'static str> {
1609    if !mat.is_empty() && (0..mat.len()).all(|j| mat.len() == mat[j].len()) {
1610        match mat.len() {
1611            1 => Ok(NumStr::new(mat[0][0].clone())),
1612            2 => {
1613                let pr = mat[0][0].number.prec().0;
1614                let mut mat = Matrix(mat.into());
1615                mat.set_prec(pr * 2);
1616                let mat = mat.mat()?;
1617                let mut v = Vector(quadratic(
1618                    Number::from(Complex::with_val(mat[0][0].number.prec(), 1), None),
1619                    Number::from(
1620                        -mat[0][0].number.clone() - mat[1][1].number.clone(),
1621                        mat[0][0].units,
1622                    ),
1623                    Number::from(
1624                        mat[0][0].number.clone() * mat[1][1].number.clone()
1625                            - mat[0][1].number.clone() * mat[1][0].number.clone(),
1626                        mat[0][0].units.map(|a| a.pow(2.0)),
1627                    ),
1628                    real,
1629                ));
1630                v.set_prec(pr);
1631                Ok(v)
1632            }
1633            3 => {
1634                let pr = mat[0][0].number.prec().0;
1635                let mut mat = Matrix(mat.into());
1636                mat.set_prec(pr * 2);
1637                let mat = mat.mat()?;
1638                let mut v = Vector(cubic(
1639                    Number::from(Complex::with_val(mat[0][0].number.prec(), -1), None),
1640                    Number::from(
1641                        mat[2][2].number.clone()
1642                            + mat[1][1].number.clone()
1643                            + mat[0][0].number.clone(),
1644                        mat[0][0].units,
1645                    ),
1646                    Number::from(
1647                        -mat[0][0].number.clone() * mat[1][1].number.clone()
1648                            - mat[0][0].number.clone() * mat[2][2].number.clone()
1649                            + mat[0][1].number.clone() * mat[1][0].number.clone()
1650                            + mat[0][2].number.clone() * mat[2][0].number.clone()
1651                            - mat[1][1].number.clone() * mat[2][2].number.clone()
1652                            + mat[1][2].number.clone() * mat[2][1].number.clone(),
1653                        mat[0][0].units.map(|a| a.pow(2.0)),
1654                    ),
1655                    Number::from(
1656                        mat[0][0].number.clone()
1657                            * mat[1][1].number.clone()
1658                            * mat[2][2].number.clone()
1659                            - mat[0][0].number.clone()
1660                                * mat[1][2].number.clone()
1661                                * mat[2][1].number.clone()
1662                            - mat[0][1].number.clone()
1663                                * mat[1][0].number.clone()
1664                                * mat[2][2].number.clone()
1665                            + mat[0][1].number.clone()
1666                                * mat[1][2].number.clone()
1667                                * mat[2][0].number.clone()
1668                            + mat[0][2].number.clone()
1669                                * mat[1][0].number.clone()
1670                                * mat[2][1].number.clone()
1671                            - mat[0][2].number.clone()
1672                                * mat[1][1].number.clone()
1673                                * mat[2][0].number.clone(),
1674                        mat[0][0].units.map(|a| a.pow(3.0)),
1675                    ),
1676                    real,
1677                ));
1678                v.set_prec(pr);
1679                Ok(v)
1680            }
1681            4 => {
1682                let pr = mat[0][0].number.prec().0;
1683                let mut mat = Matrix(mat.into());
1684                mat.set_prec(pr * 2);
1685                let mat = mat.mat()?;
1686                let a = mat[0][0].number.clone();
1687                let b = mat[0][1].number.clone();
1688                let c = mat[0][2].number.clone();
1689                let d = mat[0][3].number.clone();
1690                let e = mat[1][0].number.clone();
1691                let f = mat[1][1].number.clone();
1692                let g = mat[1][2].number.clone();
1693                let h = mat[1][3].number.clone();
1694                let i = mat[2][0].number.clone();
1695                let j = mat[2][1].number.clone();
1696                let k = mat[2][2].number.clone();
1697                let l = mat[2][3].number.clone();
1698                let m = mat[3][0].number.clone();
1699                let n = mat[3][1].number.clone();
1700                let p = mat[3][2].number.clone();
1701                let q = mat[3][3].number.clone();
1702                let mut v = Vector(quartic(
1703                    Number::from(Complex::with_val(a.prec(), 1), None),
1704                    Number::from(
1705                        -a.clone() - f.clone() - k.clone() - q.clone(),
1706                        mat[0][0].units,
1707                    ),
1708                    Number::from(
1709                        a.clone() * f.clone() + a.clone() * k.clone() + a.clone() * q.clone()
1710                            - b.clone() * e.clone()
1711                            - c.clone() * i.clone()
1712                            - d.clone() * m.clone()
1713                            + f.clone() * k.clone()
1714                            + f.clone() * q.clone()
1715                            - g.clone() * j.clone()
1716                            - h.clone() * n.clone()
1717                            + k.clone() * q.clone()
1718                            - l.clone() * p.clone(),
1719                        mat[0][0].units.map(|a| a.pow(2.0)),
1720                    ),
1721                    Number::from(
1722                        -a.clone() * f.clone() * k.clone() - a.clone() * f.clone() * q.clone()
1723                            + a.clone() * g.clone() * j.clone()
1724                            + a.clone() * h.clone() * n.clone()
1725                            - a.clone() * k.clone() * q.clone()
1726                            + a.clone() * l.clone() * p.clone()
1727                            + b.clone() * e.clone() * k.clone()
1728                            + b.clone() * e.clone() * q.clone()
1729                            - b.clone() * g.clone() * i.clone()
1730                            - b.clone() * h.clone() * m.clone()
1731                            - c.clone() * e.clone() * j.clone()
1732                            + c.clone() * f.clone() * i.clone()
1733                            + c.clone() * i.clone() * q.clone()
1734                            - c.clone() * l.clone() * m.clone()
1735                            - d.clone() * e.clone() * n.clone()
1736                            + d.clone() * f.clone() * m.clone()
1737                            - d.clone() * i.clone() * p.clone()
1738                            + d.clone() * k.clone() * m.clone()
1739                            - f.clone() * k.clone() * q.clone()
1740                            + f.clone() * l.clone() * p.clone()
1741                            + g.clone() * j.clone() * q.clone()
1742                            - g.clone() * l.clone() * n.clone()
1743                            - h.clone() * j.clone() * p.clone()
1744                            + h.clone() * k.clone() * n.clone(),
1745                        mat[0][0].units.map(|a| a.pow(3.0)),
1746                    ),
1747                    Number::from(
1748                        a.clone() * f.clone() * k.clone() * q.clone()
1749                            - a.clone() * f.clone() * l.clone() * p.clone()
1750                            - a.clone() * g.clone() * j.clone() * q.clone()
1751                            + a.clone() * g.clone() * l.clone() * n.clone()
1752                            + a.clone() * h.clone() * j.clone() * p.clone()
1753                            - a.clone() * h.clone() * k.clone() * n.clone()
1754                            - b.clone() * e.clone() * k.clone() * q.clone()
1755                            + b.clone() * e.clone() * l.clone() * p.clone()
1756                            + b.clone() * g.clone() * i.clone() * q.clone()
1757                            - b.clone() * g.clone() * l.clone() * m.clone()
1758                            - b.clone() * h.clone() * i.clone() * p.clone()
1759                            + b.clone() * h.clone() * k.clone() * m.clone()
1760                            + c.clone() * e.clone() * j.clone() * q.clone()
1761                            - c.clone() * e.clone() * l.clone() * n.clone()
1762                            - c.clone() * f.clone() * i.clone() * q.clone()
1763                            + c.clone() * f.clone() * l.clone() * m.clone()
1764                            + c.clone() * h.clone() * i.clone() * n.clone()
1765                            - c.clone() * h.clone() * j.clone() * m.clone()
1766                            - d.clone() * e.clone() * j.clone() * p.clone()
1767                            + d.clone() * e.clone() * k.clone() * n.clone()
1768                            + d.clone() * f.clone() * i.clone() * p.clone()
1769                            - d.clone() * f.clone() * k.clone() * m.clone()
1770                            - d.clone() * g.clone() * i.clone() * n.clone()
1771                            + d.clone() * g.clone() * j.clone() * m.clone(),
1772                        mat[0][0].units.map(|a| a.pow(4.0)),
1773                    ),
1774                    real,
1775                ));
1776                v.set_prec(pr);
1777                Ok(v)
1778            }
1779            _ => Err("unsupported"),
1780        }
1781    } else {
1782        Err("not square")
1783    }
1784}
1785pub fn eigenvectors(mat: &[Vec<Number>], real: bool) -> Result<NumStr, &'static str> {
1786    if !mat.is_empty() && (0..mat.len()).all(|j| mat.len() == mat[j].len()) {
1787        let one = Number::from(Complex::with_val(mat[0][0].number.prec(), 1), None);
1788        match mat.len() {
1789            1 => Ok(NumStr::new(one)),
1790            2..5 => {
1791                let p = mat[0][0].number.prec().0;
1792                let mut l = eigenvalues(mat, real)?.vec()?;
1793                let mut i = 0;
1794                while i + 1 < l.len() {
1795                    let mut has = false;
1796                    for v in l[i + 1..].iter().cloned() {
1797                        if (v.number - l[i].number.clone()).abs().real().clone().log2()
1798                            < -(p as i32 / 8)
1799                        {
1800                            l.remove(i);
1801                            has = true;
1802                            break;
1803                        }
1804                    }
1805                    if !has {
1806                        i += 1;
1807                    }
1808                }
1809                let v = l
1810                    .iter()
1811                    .filter_map(|l| {
1812                        Matrix(identity(mat.len(), l.number.prec().0))
1813                            .mul(&NumStr::new(l.clone()))
1814                            .map(|n| {
1815                                Matrix(mat.to_vec())
1816                                    .func(&n, sub)
1817                                    .map(|m| Some(kernel(m.mat().unwrap()).unwrap()))
1818                                    .unwrap_or(None)
1819                            })
1820                            .unwrap_or(None)
1821                    })
1822                    .flatten()
1823                    .collect::<Vec<Vec<Number>>>();
1824                Ok(Matrix(v))
1825            }
1826            _ => Err("unsupported"),
1827        }
1828    } else {
1829        Err("not square")
1830    }
1831}
1832pub fn rcf(mat: Vec<Vec<Number>>) -> Result<NumStr, &'static str> {
1833    if mat.is_empty() || (0..mat.len()).any(|j| mat.len() != mat[j].len()) {
1834        return Err("matrix not square");
1835    }
1836    let pr = mat[0][0].number.prec().0;
1837    let l = mat.len();
1838    let mut ev = gen_ev(&mat, false)?;
1839    let mut beta = Vec::new();
1840    let m = Matrix(mat.clone());
1841    while !ev.is_empty() {
1842        let v = ev
1843            .iter_mut()
1844            .filter_map(|e| e.pop().map(Vector))
1845            .collect::<Vec<NumStr>>();
1846        let l = v.len();
1847        if l == 0 {
1848            break;
1849        }
1850        let v = if l == 1 {
1851            v[0].clone()
1852        } else {
1853            v[1..].iter().fold(v[0].clone(), |sum, val| {
1854                sum.func(val, add).unwrap_or(Func(String::new()))
1855            })
1856        };
1857        let mut c = v.vec()?;
1858        beta.push(c.clone());
1859        for _ in 1..l {
1860            c = m.mul(&Vector(c))?.vec()?;
1861            beta.push(c.clone())
1862        }
1863    }
1864    change_basis(mat, &identity(l, pr), &transpose(&beta))
1865}
1866pub fn jcf(mat: Vec<Vec<Number>>) -> Result<NumStr, &'static str> {
1867    if mat.is_empty() || (0..mat.len()).any(|j| mat.len() != mat[j].len()) {
1868        return Err("matrix not square");
1869    }
1870    let pr = mat[0][0].number.prec().0;
1871    let l = mat.len();
1872    let beta = transpose(&generalized_eigenvectors(&mat, false)?.mat()?);
1873    let i = identity(l, pr);
1874    let mut o = i.clone();
1875    let mut d = change_basis(mat, &i, &beta)?.mat()?;
1876    for (i, r) in o.iter_mut().enumerate() {
1877        r[i].number = d[i..d.len() - 1]
1878            .iter()
1879            .enumerate()
1880            .map_while(|(j, r)| {
1881                if -r[i + j + 1].number.clone().abs().real().clone().ln() < pr / 16 {
1882                    Some(r[i + j + 1].number.clone())
1883                } else {
1884                    None
1885                }
1886            })
1887            .fold(Complex::with_val(pr, 1), |sum, val| sum * val.clone());
1888    }
1889    let l = o.len();
1890    for k in 1..l {
1891        d = change_basis(d, &i, &o)?.mat()?;
1892        o = i.clone();
1893        let mut sum = Complex::new(pr);
1894        for (i, r) in o[1..l - k].iter_mut().enumerate() {
1895            let i = i + 1;
1896            sum += d[i - 1][i + k].number.clone();
1897            r[i + k].number = -sum.clone();
1898        }
1899    }
1900    let d = change_basis(d, &i, &o)?;
1901    Ok(d)
1902}
1903fn gen_ev(mat: &[Vec<Number>], real: bool) -> Result<Vec<Vec<Vec<Number>>>, &'static str> {
1904    if mat.is_empty() || (0..mat.len()).any(|j| mat.len() != mat[j].len()) {
1905        return Err("matrix not square");
1906    }
1907    let p = mat[0][0].number.prec().0;
1908    let mut l = eigenvalues(mat, real)?.vec()?;
1909    let mut i = 0;
1910    while i + 1 < l.len() {
1911        let mut has = false;
1912        for v in l[i + 1..].iter().cloned() {
1913            if (v.number - l[i].number.clone()).abs().real().clone().log2() < -(p as i32 / 8) {
1914                l.remove(i);
1915                has = true;
1916                break;
1917            }
1918        }
1919        if !has {
1920            i += 1;
1921        }
1922    }
1923    Ok(l.iter()
1924        .filter_map(|l| {
1925            Matrix(identity(mat.len(), l.number.prec().0))
1926                .mul(&NumStr::new(l.clone()))
1927                .map(|n| {
1928                    Matrix(mat.to_vec())
1929                        .func(&n, sub)
1930                        .map(|m| {
1931                            m.pow(&NumStr::new(Number::from(
1932                                Complex::with_val(p, mat.len()),
1933                                None,
1934                            )))
1935                            .map(|m| {
1936                                let ker = kernel(m.mat().unwrap()).unwrap();
1937                                Some(ker)
1938                            })
1939                            .unwrap_or(None)
1940                        })
1941                        .unwrap_or(None)
1942                })
1943                .unwrap_or(None)
1944        })
1945        .collect::<Vec<Vec<Vec<Number>>>>())
1946}
1947pub fn generalized_eigenvectors(mat: &[Vec<Number>], real: bool) -> Result<NumStr, &'static str> {
1948    if !mat.is_empty() && (0..mat.len()).all(|j| mat.len() == mat[j].len()) {
1949        let one = Number::from(Complex::with_val(mat[0][0].number.prec(), 1), None);
1950        match mat.len() {
1951            1 => Ok(NumStr::new(one)),
1952            2..5 => Ok(Matrix(
1953                gen_ev(mat, real)?
1954                    .iter()
1955                    .flatten()
1956                    .cloned()
1957                    .collect::<Vec<Vec<Number>>>(),
1958            )),
1959            _ => Err("unsupported"),
1960        }
1961    } else {
1962        Err("not square")
1963    }
1964}
1965pub fn change_basis(
1966    a: Vec<Vec<Number>>,
1967    beta: &[Vec<Number>],
1968    gamma: &[Vec<Number>],
1969) -> Result<NumStr, &'static str> {
1970    let m = Matrix(a);
1971    let tn = Matrix(inverse(&transpose(gamma))?);
1972    let mut c = Vec::new();
1973    for b in beta {
1974        c.push(tn.mul(&Vector(b.to_vec()))?.vec()?)
1975    }
1976    let tn = Matrix(inverse(&transpose(beta))?);
1977    let mut d = Vec::new();
1978    for g in gamma {
1979        d.push(tn.mul(&Vector(g.to_vec()))?.vec()?)
1980    }
1981    Matrix(c).mul(&m)?.mul(&Matrix(d))
1982}
1983pub fn coordinate(v: Vec<Number>, beta: Vec<Vec<Number>>) -> Result<NumStr, &'static str> {
1984    let tn = Matrix(inverse(&transpose(&beta))?);
1985    tn.mul(&Vector(v))
1986}
1987pub fn rref(mut a: Vec<Vec<Number>>) -> Result<Vec<Vec<Number>>, &'static str> {
1988    if a.is_empty() || a[0].is_empty() || a.iter().any(|b| a[0].len() != b.len()) {
1989        return Err("invalid matrix");
1990    }
1991    let mut count = 0;
1992    for i in 0..a[0].len() {
1993        if let Some((n, v)) = a
1994            .clone()
1995            .iter()
1996            .enumerate()
1997            .find(|(j, b)| *j >= count && !b[i].number.is_zero())
1998        {
1999            for (a, r) in a.iter_mut().enumerate() {
2000                let c = r[i].number.clone() / v[i].number.clone();
2001                for (b, num) in r.iter_mut().enumerate() {
2002                    if a != n && !v[i].number.is_zero() {
2003                        num.number -= v[b].number.clone() * c.clone();
2004                    } else {
2005                        num.number /= v[i].number.clone()
2006                    }
2007                }
2008            }
2009            if n != count {
2010                a.swap(count, n);
2011            }
2012            count += 1;
2013        }
2014    }
2015    Ok(a.to_vec())
2016}
2017pub fn kernel(a: Vec<Vec<Number>>) -> Result<Vec<Vec<Number>>, &'static str> {
2018    if a.is_empty() || a[0].is_empty() || a.iter().any(|b| a[0].len() != b.len()) {
2019        return Err("invalid matrix");
2020    }
2021    let pr = a[0][0].number.prec().0;
2022    let rref = rref(a.clone())?;
2023    let mut ker = Vec::new();
2024    let mut leading_ones = Vec::new();
2025    for r in &rref {
2026        if let Some((pos, _)) = r.iter().enumerate().find(|(_, n)| !n.number.is_zero()) {
2027            leading_ones.push(pos);
2028        }
2029    }
2030    let t = transpose(&rref);
2031    let m = Matrix(a);
2032    for (i, t) in t.iter().enumerate() {
2033        if !leading_ones.contains(&i) {
2034            let mut zero = vec![Number::from(Complex::new(pr), None); rref[0].len()];
2035            for j in 0..i.min(leading_ones.len()) {
2036                if leading_ones[j] < i {
2037                    zero[leading_ones[j]] = Number::from(-1.0 * t[j].number.clone(), None)
2038                }
2039            }
2040            zero[i] = Number::from(Complex::with_val(pr, 1), None);
2041            if m.mul(&Vector(zero.clone()))?
2042                .vec()?
2043                .iter()
2044                .all(|n| -n.number.clone().abs().real().clone().log2() > pr / 16)
2045            {
2046                ker.push(zero);
2047            }
2048        }
2049    }
2050    Ok(ker)
2051}
2052pub fn range(a: Vec<Vec<Number>>) -> Result<Vec<Vec<Number>>, &'static str> {
2053    let rref = rref(a.clone())?;
2054    let mut ran = Vec::new();
2055    let mut leading_ones = Vec::new();
2056    for r in &rref {
2057        if let Some((pos, _)) = r.iter().enumerate().find(|(_, n)| !n.number.is_zero()) {
2058            leading_ones.push(pos);
2059        }
2060    }
2061    let t = transpose(&a);
2062    for i in leading_ones {
2063        ran.push(t[i].clone());
2064    }
2065    Ok(ran)
2066}
2067pub fn mul_units(a: Option<Units>, b: Option<Units>) -> Option<Units> {
2068    match (a, b) {
2069        (Some(a), None) => Some(a),
2070        (None, Some(b)) => Some(b),
2071        (Some(a), Some(b)) => Some(a.mul(&b)),
2072        _ => None,
2073    }
2074}
2075pub fn div_units(a: Option<Units>, b: Option<Units>) -> Option<Units> {
2076    match (a, b) {
2077        (Some(a), None) => Some(a),
2078        (None, Some(b)) => Some(b.pow(-1.0)),
2079        (Some(a), Some(b)) => Some(a.div(&b)),
2080        _ => None,
2081    }
2082}
2083pub fn quadratic(a: Number, b: Number, c: Number, real: bool) -> Vec<Number> {
2084    if a.number.is_zero() {
2085        return if b.number.is_zero() {
2086            vec![Number::from(Complex::new(a.number.prec()), None)]
2087        } else {
2088            let units = div_units(c.units, b.units);
2089            let b = b.number;
2090            let c = c.number;
2091            let mut r = -c / b;
2092            if -r.imag().clone().abs().log10() > a.number.prec().0 / 4 {
2093                r = r.real().clone().into();
2094            }
2095            if real && !r.imag().is_zero() {
2096                vec![Number::from(Complex::with_val(a.number.prec(), Nan), None)]
2097            } else {
2098                vec![Number::from(r, units)]
2099            }
2100        };
2101    }
2102    let units = div_units(c.units, a.units).map(|a| a.root(2.0));
2103    let a = a.number;
2104    let b = b.number;
2105    let c = c.number;
2106    let p: Complex = sqr(b.clone());
2107    let p: Complex = p - (4 * c * a.clone());
2108    let p = p.sqrt();
2109    let a: Complex = 2 * a;
2110    let mut z1 = (p.clone() - b.clone()) / a.clone();
2111    let mut z2 = (-p - b) / a.clone();
2112    if -z1.imag().clone().abs().log10() > a.prec().0 / 4 {
2113        z1 = z1.real().clone().into();
2114    }
2115    if -z2.imag().clone().abs().log10() > a.prec().0 / 4 {
2116        z2 = z2.real().clone().into();
2117    }
2118    if real {
2119        let mut vec = Vec::new();
2120        if z1.imag().is_zero() {
2121            vec.push(Number::from(z1, units))
2122        }
2123        if z2.imag().is_zero() {
2124            vec.push(Number::from(z2, units))
2125        }
2126        if vec.is_empty() {
2127            vec![Number::from(Complex::with_val(a.prec(), Nan), None)]
2128        } else {
2129            vec
2130        }
2131    } else {
2132        vec![Number::from(z1, units), Number::from(z2, units)]
2133    }
2134}
2135pub fn cubic(a: Number, b: Number, c: Number, d: Number, real: bool) -> Vec<Number> {
2136    let units = div_units(d.units, a.units).map(|a| a.root(3.0));
2137    if a.number.is_zero() {
2138        return quadratic(b, c, d, real);
2139    }
2140    let d = d.number;
2141    if d.is_zero() {
2142        let mut vec = quadratic(a, b, c, real);
2143        vec.push(Number::from(Complex::new(d.prec()), vec[0].units));
2144        return vec;
2145    }
2146    let a = a.number;
2147    let b = b.number;
2148    let c = c.number;
2149    let prec = a.prec();
2150    let threerecip = Float::with_val(prec.0, 3).recip();
2151    if b.is_zero() && c.is_zero() {
2152        let reuse = pow_nth(d / a.clone(), threerecip.clone().into());
2153        let mut z1 = -reuse.clone();
2154        let mut z2 = reuse.clone() * Complex::with_val(prec.0, -1).pow(threerecip.clone());
2155        let mut z3: Complex = -reuse * Complex::with_val(prec.0, -1).pow(2 * threerecip);
2156        if -z1.imag().clone().abs().log10() > a.prec().0 / 4 {
2157            z1 = z1.real().clone().into();
2158        }
2159        if -z2.imag().clone().abs().log10() > a.prec().0 / 4 {
2160            z2 = z2.real().clone().into();
2161        }
2162        if -z3.imag().clone().abs().log10() > a.prec().0 / 4 {
2163            z3 = z3.real().clone().into();
2164        }
2165        return if real {
2166            let mut vec = Vec::new();
2167            if z1.imag().is_zero() {
2168                vec.push(Number::from(z1, units))
2169            }
2170            if z2.imag().is_zero() {
2171                vec.push(Number::from(z2, units))
2172            }
2173            if z3.imag().is_zero() {
2174                vec.push(Number::from(z3, units))
2175            }
2176            if vec.is_empty() {
2177                vec![Number::from(Complex::with_val(prec, Nan), None)]
2178            } else {
2179                vec
2180            }
2181        } else {
2182            vec![
2183                Number::from(z1, units),
2184                Number::from(z2, units),
2185                Number::from(z3, units),
2186            ]
2187        };
2188    }
2189    let b = b / a.clone();
2190    let c = c / a.clone();
2191    let d = d / a.clone();
2192    // https://en.wikipedia.org/wiki/Cubic_equation#General_cubic_formula
2193    let d0: Complex = sqr(b.clone()) - 3 * c.clone();
2194    let d1: Complex = 2 * cube(b.clone()) - 9 * b.clone() * c.clone() + 27 * d.clone();
2195    let c: Complex = sqr(d1.clone()) - 4 * cube(d0.clone());
2196    let c: Complex = (d1 + c.sqrt()) / 2;
2197    let c = pow_nth(c, threerecip.clone().into());
2198    let omega: Complex = Complex::with_val(prec, (-0.5, Float::with_val(prec.0, 3).sqrt() / 2));
2199    let mut z1: Complex = if d0.is_zero() {
2200        -(b.clone() + c.clone()) / 3
2201    } else {
2202        -(b.clone() + c.clone() + d0.clone() / c.clone()) / 3
2203    };
2204    let c0 = c.clone() * omega.clone();
2205    let mut z2: Complex = if d0.is_zero() {
2206        -(b.clone() + c0.clone()) / 3
2207    } else {
2208        -(b.clone() + c0.clone() + d0.clone() / c0) / 3
2209    };
2210    let c1 = c * omega.conj();
2211    let mut z3: Complex = if d0.is_zero() {
2212        -(b + c1.clone()) / 3
2213    } else {
2214        -(b + c1.clone() + d0 / c1) / 3
2215    };
2216    if -z1.imag().clone().abs().log10() > a.prec().0 / 4 {
2217        z1 = z1.real().clone().into();
2218    }
2219    if -z2.imag().clone().abs().log10() > a.prec().0 / 4 {
2220        z2 = z2.real().clone().into();
2221    }
2222    if -z3.imag().clone().abs().log10() > a.prec().0 / 4 {
2223        z3 = z3.real().clone().into();
2224    }
2225    if real {
2226        let mut vec = Vec::new();
2227        if z1.imag().is_zero() {
2228            vec.push(Number::from(z1, units))
2229        }
2230        if z2.imag().is_zero() {
2231            vec.push(Number::from(z2, units))
2232        }
2233        if z3.imag().is_zero() {
2234            vec.push(Number::from(z3, units))
2235        }
2236        if vec.is_empty() {
2237            vec![Number::from(Complex::with_val(prec, Nan), None)]
2238        } else {
2239            vec
2240        }
2241    } else {
2242        vec![
2243            Number::from(z1, units),
2244            Number::from(z2, units),
2245            Number::from(z3, units),
2246        ]
2247    }
2248}
2249pub fn quartic(div: Number, b: Number, c: Number, d: Number, e: Number, real: bool) -> Vec<Number> {
2250    let units = div_units(e.units, div.units).map(|a| a.root(4.0));
2251    if e.number.is_zero() {
2252        let mut vec = cubic(div, b, c, d, real);
2253        vec.push(Number::from(Complex::new(e.number.prec()), vec[0].units));
2254        return vec;
2255    }
2256    let div = div.number;
2257    if div.is_zero() {
2258        return cubic(b, c, d, e, real);
2259    }
2260    let b = b.number;
2261    let c = c.number;
2262    let d = d.number;
2263    let e = e.number;
2264    let prec = div.prec();
2265    let threerecip = Float::with_val(prec.0, 3).recip();
2266    let a = b / div.clone();
2267    let b = c / div.clone();
2268    let c = d / div.clone();
2269    let d = e / div;
2270    if a.is_zero() && b.is_zero() && c.is_zero() {
2271        return if d.is_zero() {
2272            vec![Number::from(Complex::new(prec), None)]
2273        } else {
2274            let a = Complex::with_val(prec, 1) / 4;
2275            let mut a: Complex = (-d).pow(a);
2276            let mut v = vec![a.clone()];
2277            for _ in 0..3 {
2278                a = a.mul_i(false);
2279                v.push(a.clone());
2280            }
2281            v.into_iter().map(|a| Number::from(a, None)).collect()
2282        };
2283    }
2284    // https://upload.wikimedia.org/wikipedia/commons/9/99/Quartic_Formula.svg
2285    let alpha: Complex = sqr(b.clone()) - 3 * a.clone() * c.clone() + 12 * d.clone();
2286    let phi: Complex = 2 * cube(b.clone()) - 9 * a.clone() * b.clone() * c.clone()
2287        + 27 * sqr(c.clone())
2288        + 27 * sqr(a.clone()) * d.clone()
2289        - 72 * b.clone() * d.clone();
2290    let omega: Complex = -4 * cube(alpha.clone()) + sqr(phi.clone());
2291    let omega: Complex = phi + omega.sqrt();
2292    let alpha: Complex = if alpha.is_zero() {
2293        Complex::new(prec)
2294    } else {
2295        Float::with_val(prec.0, 2).pow(threerecip.clone()) * alpha
2296            / (3 * pow_nth(omega.clone(), threerecip.clone().into()))
2297    };
2298    let beta: Complex = omega / 54;
2299    let beta: Complex = pow_nth(beta, threerecip.clone().into());
2300    let infirst: Complex = sqr(a.clone()) / 4 - 2 * b.clone() / 3 + alpha.clone() + beta.clone();
2301    let first: Complex = infirst.clone().sqrt() / 2;
2302    let third: Complex = -1 * cube(a.clone()) + 4 * a.clone() * b.clone() - 8 * c.clone();
2303    let third: Complex = if third.is_zero() {
2304        Complex::new(prec)
2305    } else {
2306        third / (first.clone() * 8)
2307    };
2308    let a4: Complex = -a.clone() / 4;
2309    let second: Complex = sqr(a.clone()) / 2 - 4 * b.clone() / 3 - alpha.clone() - beta.clone();
2310    let secondn: Complex = second.clone() - third.clone();
2311    let secondn: Complex = secondn.sqrt() / 2;
2312    let secondp: Complex = second + third.clone();
2313    let secondp: Complex = secondp.sqrt() / 2;
2314    let mut r1 = a4.clone() - first.clone() - secondn.clone();
2315    let mut r2 = a4.clone() - first.clone() + secondn.clone();
2316    let mut r3 = a4.clone() + first.clone() - secondp.clone();
2317    let mut r4 = a4.clone() + first.clone() + secondp.clone();
2318    if -r1.imag().clone().abs().log10() > a.prec().0 / 8 {
2319        r1 = r1.real().clone().into();
2320    }
2321    if -r2.imag().clone().abs().log10() > a.prec().0 / 8 {
2322        r2 = r2.real().clone().into();
2323    }
2324    if -r3.imag().clone().abs().log10() > a.prec().0 / 8 {
2325        r3 = r3.real().clone().into();
2326    }
2327    if -r4.imag().clone().abs().log10() > a.prec().0 / 8 {
2328        r4 = r4.real().clone().into();
2329    }
2330    if real {
2331        let mut vec = Vec::new();
2332        if r1.imag().is_zero() {
2333            vec.push(Number::from(r1, units))
2334        }
2335        if r2.imag().is_zero() {
2336            vec.push(Number::from(r2, units))
2337        }
2338        if r3.imag().is_zero() {
2339            vec.push(Number::from(r3, units))
2340        }
2341        if r4.imag().is_zero() {
2342            vec.push(Number::from(r4, units))
2343        }
2344        if vec.is_empty() {
2345            vec![Number::from(Complex::with_val(prec, Nan), None)]
2346        } else {
2347            vec
2348        }
2349    } else {
2350        vec![
2351            Number::from(r1, units),
2352            Number::from(r2, units),
2353            Number::from(r3, units),
2354            Number::from(r4, units),
2355        ]
2356    }
2357}
2358pub fn variance(a: &[Number], mean: Option<Complex>, prec: u32) -> Number {
2359    let mean = if let Some(n) = mean {
2360        n
2361    } else {
2362        a.iter()
2363            .fold(Complex::new(prec), |sum, val| sum + val.number.clone())
2364            / a.len()
2365    };
2366    let mut variance = Complex::new(prec);
2367    for a in a {
2368        variance += sqr(a.number.clone() - mean.clone())
2369    }
2370    Number::from(
2371        variance / (a.len().saturating_sub(1)),
2372        a[0].units.map(|a| a.pow(2.0)),
2373    )
2374}
2375pub fn recursion(
2376    mut func_vars: Vec<(String, Vec<NumStr>)>,
2377    mut func: Vec<NumStr>,
2378    options: Options,
2379) -> Result<NumStr, &'static str> {
2380    for fv in func_vars.clone() {
2381        if fv.0.ends_with(')') {
2382            let mut cont = false;
2383            let mut bracket = 0;
2384            let mut pw = Vec::new();
2385            for f in &func {
2386                match f {
2387                    LeftBracket | LeftCurlyBracket => bracket += 1,
2388                    RightBracket | RightCurlyBracket => {
2389                        bracket -= 1;
2390                        if !pw.is_empty() && bracket == pw[0] {
2391                            pw.remove(0);
2392                        }
2393                    }
2394                    Func(s) if s == "pw" => pw.insert(0, bracket),
2395                    _ => {
2396                        if !pw.is_empty() && f.str_is(&fv.0) {
2397                            cont = true
2398                        }
2399                    }
2400                }
2401            }
2402            if cont {
2403                continue;
2404            }
2405            if fv.0.contains(',') {
2406                let mut vars = fv.0.split(',').collect::<Vec<&str>>();
2407                vars[0] = vars[0].split('(').next_back().unwrap();
2408                {
2409                    let vl = vars.len().saturating_sub(1);
2410                    vars[vl] = &vars[vl][0..vars[vl].len().saturating_sub(1)];
2411                }
2412                let mut x = func.len();
2413                while x > 0 {
2414                    x -= 1;
2415                    if func[x].str_is(&fv.0) {
2416                        let mut fv = fv.clone();
2417                        let mut bracket = 0;
2418                        let mut k = 0;
2419                        let mut processed = Vec::new();
2420                        let mut last = 0;
2421                        for (i, n) in func[x + 2..].iter().enumerate() {
2422                            match n {
2423                                LeftBracket | LeftCurlyBracket => bracket += 1,
2424                                RightBracket | RightCurlyBracket => {
2425                                    if bracket == 0 {
2426                                        if let Ok(n) = do_math(
2427                                            func[x + 2 + last..x + 2 + i].to_vec(),
2428                                            options,
2429                                            func_vars.clone(),
2430                                        ) {
2431                                            processed.push(vec![n]);
2432                                        } else {
2433                                            let iden = format!(
2434                                                "@{}{}@",
2435                                                func_vars.len(),
2436                                                vars[processed.len()]
2437                                            );
2438                                            func_vars.push((
2439                                                iden.clone(),
2440                                                func[x + 2 + last..x + 2 + i].to_vec(),
2441                                            ));
2442                                            processed.push(vec![Func(iden)]);
2443                                        }
2444                                        k = i;
2445                                        break;
2446                                    }
2447                                    bracket -= 1;
2448                                }
2449                                Comma if bracket == 0 => {
2450                                    if let Ok(n) = do_math(
2451                                        func[x + 2 + last..x + 2 + i].to_vec(),
2452                                        options,
2453                                        func_vars.clone(),
2454                                    ) {
2455                                        processed.push(vec![n]);
2456                                    } else {
2457                                        let iden = format!(
2458                                            "@{}{}@",
2459                                            func_vars.len(),
2460                                            vars[processed.len()]
2461                                        );
2462                                        func_vars.push((
2463                                            iden.clone(),
2464                                            func[x + 2 + last..x + 2 + i].to_vec(),
2465                                        ));
2466                                        processed.push(vec![Func(iden)]);
2467                                    }
2468                                    last = i + 1;
2469                                }
2470                                _ => {}
2471                            }
2472                        }
2473                        let mut i = 0;
2474                        while i < fv.1.len() {
2475                            if let Func(s) = &fv.1[i] {
2476                                for v in processed.iter().zip(vars.iter()) {
2477                                    if s == v.1 {
2478                                        fv.1.remove(i);
2479                                        fv.1.splice(i..i, v.0.clone());
2480                                        break;
2481                                    }
2482                                }
2483                            }
2484                            i += 1;
2485                        }
2486                        func.drain(x..=k + x + 2);
2487                        func.splice(x..x, fv.1.clone());
2488                    }
2489                }
2490            } else {
2491                let var = fv.0.split('(').next_back().unwrap();
2492                let var = &var[0..var.len().saturating_sub(1)];
2493                let mut x = func.len();
2494                while x > 0 {
2495                    x -= 1;
2496                    if func[x].str_is(&fv.0) {
2497                        let mut fv = fv.clone();
2498                        let mut bracket = 0;
2499                        let mut k = 0;
2500                        for (i, n) in func[x + 2..].iter().enumerate() {
2501                            match n {
2502                                LeftBracket | LeftCurlyBracket => bracket += 1,
2503                                RightBracket | RightCurlyBracket => {
2504                                    if bracket == 0 {
2505                                        k = i;
2506                                    }
2507                                    bracket -= 1;
2508                                }
2509                                _ => {}
2510                            }
2511                        }
2512                        let iden = format!("@{}{}@", func_vars.len(), var);
2513                        let mut i = 0;
2514                        while i < fv.1.len() {
2515                            if let Func(s) = &fv.1[i] {
2516                                if *s == var {
2517                                    fv.1[i] = Func(iden.clone());
2518                                }
2519                            }
2520                            i += 1;
2521                        }
2522                        func_vars.push((iden.clone(), func[x + 1..=k + x + 2].to_vec()));
2523                        func.drain(x..=k + x + 2);
2524                        func.splice(x..x, fv.1.clone());
2525                    }
2526                }
2527            }
2528        }
2529    }
2530    do_math(func, options, func_vars)
2531}
2532pub fn gcd(mut x: Integer, mut y: Integer) -> Integer {
2533    while x != y {
2534        if x > y {
2535            x -= y.clone()
2536        } else {
2537            y -= x.clone()
2538        }
2539    }
2540    x
2541}
2542pub fn incomplete_beta(x: Complex, a: Complex, b: Complex) -> Complex {
2543    if x.real() > &((a.real().clone() + 1) / (a.real() + b.real().clone() + 2)) {
2544        (gamma(a.clone()) * gamma(b.clone()) / gamma(a.clone() + b.clone()))
2545            - incomplete_beta(1 - x, b, a)
2546    } else {
2547        let f: Complex = 1 - x.clone();
2548        pow_nth(x.clone(), a.clone()) * pow_nth(f, b.clone())
2549            / (a.clone() * (1 + incomplete_beta_recursion(x, a, b, 1, 10)))
2550    }
2551}
2552fn incomplete_beta_recursion(
2553    x: Complex,
2554    a: Complex,
2555    b: Complex,
2556    iter: usize,
2557    max: usize,
2558) -> Complex {
2559    if iter == max {
2560        Complex::new(x.prec())
2561    } else if iter % 2 == 1 {
2562        let m = (iter - 1) / 2;
2563        (-x.clone() * (a.clone() + m) * (a.clone() + b.clone() + m)
2564            / ((a.clone() + (2 * m)) * (a.clone() + (2 * m) + 1)))
2565            / (1 + incomplete_beta_recursion(x, a, b, iter + 1, max))
2566    } else {
2567        let m = iter / 2;
2568        (x.clone() * m * (b.clone() - m) / ((a.clone() + (2 * m)) * (a.clone() + (2 * m) - 1)))
2569            / (1 + incomplete_beta_recursion(x, a, b, iter + 1, max))
2570    }
2571}
2572pub fn erf(z: Complex) -> Complex {
2573    1 - erfc(z)
2574}
2575pub fn erfc(z: Complex) -> Complex {
2576    let p2: Complex = sqr(z.clone());
2577    erfc_recursion(z.clone(), 0, z.prec().0 as usize / 4) / Complex::with_val(z.prec(), Pi).sqrt()
2578        * z
2579        / p2.exp()
2580}
2581fn erfc_recursion(z: Complex, iter: usize, max: usize) -> Complex {
2582    if iter == max {
2583        Complex::with_val(z.prec(), 1)
2584    } else if iter == 0 {
2585        erfc_recursion(z, 1, max).recip()
2586    } else if iter % 2 == 1 {
2587        sqr(z.clone()) + iter / (2 * erfc_recursion(z, iter + 1, max))
2588    } else {
2589        1 + iter / (2 * erfc_recursion(z, iter + 1, max))
2590    }
2591}
2592fn gamma0(z: Complex) -> Complex {
2593    let p = z.prec().0 as usize / 4;
2594    gamma0_recursion_first(z.clone(), 0, p) + gamma0_recursion_second(z, 0, p)
2595}
2596fn gamma0_recursion_first(z: Complex, iter: usize, max: usize) -> Complex {
2597    if iter == max {
2598        Complex::with_val(z.prec(), 1)
2599    } else if iter == 0 {
2600        Float::with_val(z.prec().0, -1).exp() / gamma0_recursion_first(z, 1, max)
2601    } else {
2602        2 * iter - z.clone() + iter * (z.clone() - iter) / gamma0_recursion_first(z, iter + 1, max)
2603    }
2604}
2605fn gamma0_recursion_second(z: Complex, iter: usize, max: usize) -> Complex {
2606    if iter == max {
2607        Complex::with_val(z.prec(), 1)
2608    } else if iter == 0 {
2609        Float::with_val(z.prec().0, -1).exp() / gamma0_recursion_second(z, 1, max)
2610    } else if iter % 2 == 1 {
2611        (iter - 1) + z.clone() - (z.clone() + iter / 2) / gamma0_recursion_second(z, iter + 1, max)
2612    } else {
2613        (iter - 1) + z.clone() + (iter / 2) / gamma0_recursion_second(z, iter + 1, max)
2614    }
2615}
2616pub fn incomplete_gamma(s: Complex, z: Complex) -> Complex {
2617    if z.is_zero() {
2618        gamma(s)
2619    } else if s.real().is_sign_positive()
2620        && !s.real().clone().fract().is_zero()
2621        && *z.real() <= 0.25
2622    {
2623        let p = z.prec().0 as usize / 4;
2624        gamma(s.clone()) - lower_incomplete_gamma_recursion(s, z, 0, p)
2625    } else {
2626        let p = z.prec().0 as usize / 4;
2627        incomplete_gamma_recursion(s, z, 0, p)
2628    }
2629}
2630pub fn lower_incomplete_gamma(s: Complex, z: Complex) -> Complex {
2631    if s.real().is_sign_positive() && !s.real().clone().fract().is_zero() && *z.real() <= 1 {
2632        let p = z.prec().0 as usize / 4;
2633        lower_incomplete_gamma_recursion(s, z, 0, p)
2634    } else {
2635        gamma(s.clone()) - incomplete_gamma(s, z)
2636    }
2637}
2638pub fn eta(s: Complex) -> Complex {
2639    let prec = s.prec().0;
2640    let mut sum = Complex::new(prec);
2641    let two = Float::with_val(prec, 2);
2642    for n in 0..=(prec / 16).max(16) {
2643        let mut innersum = Complex::new(prec);
2644        let nb = Integer::from(n);
2645        for k in 0..=n {
2646            let num = nb.clone().binomial(k) * pow_nth(Complex::with_val(prec, 1 + k), -s.clone());
2647            if k % 2 == 0 {
2648                innersum += num;
2649            } else {
2650                innersum -= num;
2651            }
2652        }
2653        sum += innersum / two.clone().pow(n + 1)
2654    }
2655    sum
2656}
2657pub fn zeta(s: Complex) -> Complex {
2658    eta(s.clone()) / (1 - pow_nth(Complex::with_val(s.prec(), 2), 1 - s))
2659}
2660pub fn euleriannumbers(n: Complex, k: i32) -> Complex {
2661    if k < 0 {
2662        Complex::with_val(n.prec(), Nan)
2663    } else if n.real().clone().fract() != 0 && n.imag().is_zero() && n.real().is_sign_positive() {
2664        let mut sum = Complex::new(n.prec());
2665        for i in 0..=k {
2666            let ic = Complex::with_val(n.prec(), i);
2667            let num: Complex = k - ic.clone() + 1;
2668            let num = binomial(n.clone() + 1, ic) * pow_nth(num, n.clone());
2669            if i % 2 == 0 { sum += num } else { sum -= num }
2670        }
2671        sum
2672    } else {
2673        Complex::with_val(
2674            n.prec(),
2675            euleriannumbersint(
2676                n.real()
2677                    .to_integer()
2678                    .unwrap_or_default()
2679                    .to_u32()
2680                    .unwrap_or_default(),
2681                k as u32,
2682            ),
2683        )
2684    }
2685}
2686pub fn euleriannumbersint(n: u32, k: u32) -> Integer {
2687    let mut sum = Integer::new();
2688    for i in 0..=k {
2689        let num: Integer = k - Integer::from(i) + 1;
2690        let num = Integer::from(n + 1).binomial(i) * num.pow(n);
2691        if i % 2 == 0 { sum += num } else { sum -= num }
2692    }
2693    sum
2694}
2695pub fn binomial(a: Complex, b: Complex) -> Complex {
2696    if a.imag().is_zero()
2697        && b.imag().is_zero()
2698        && a.real().clone().fract().is_zero()
2699        && b.real().clone().fract().is_zero()
2700        && a.real().is_finite()
2701        && a.real() >= &0
2702        && b.real() >= &0
2703    {
2704        Complex::with_val(
2705            a.prec(),
2706            a.real().to_integer().unwrap_or_default().binomial(
2707                b.real()
2708                    .to_integer()
2709                    .unwrap_or_default()
2710                    .to_u32()
2711                    .unwrap_or_default(),
2712            ),
2713        )
2714    } else if a.real().is_sign_negative()
2715        && a.real().clone().fract().is_zero()
2716        && a.imag().is_zero()
2717        && b.imag().is_zero()
2718    {
2719        let prec = a.prec().0;
2720        let a = a + Complex::with_val(prec, (0, 1)) * Float::with_val(prec, 0.5).pow(prec / 2);
2721        (gamma(a.clone() + 1) / (gamma(b.clone() + 1) * gamma(a.clone() - b.clone() + 1)))
2722            .real()
2723            .clone()
2724            .into()
2725    } else {
2726        gamma(a.clone() + 1) / (gamma(b.clone() + 1) * gamma(a.clone() - b.clone() + 1))
2727    }
2728}
2729fn incomplete_gamma_recursion(s: Complex, z: Complex, iter: usize, max: usize) -> Complex {
2730    if iter == max {
2731        Complex::with_val(s.prec(), 1)
2732    } else if iter == 0 {
2733        (pow_nth(z.clone(), s.clone()) / z.clone().exp()) / incomplete_gamma_recursion(s, z, 1, max)
2734    } else if iter % 2 == 1 {
2735        z.clone()
2736            + ((iter.div_ceil(2) - s.clone()) / incomplete_gamma_recursion(s, z, iter + 1, max))
2737    } else {
2738        1 + (iter.div_ceil(2) / incomplete_gamma_recursion(s, z, iter + 1, max))
2739    }
2740}
2741fn lower_incomplete_gamma_recursion(s: Complex, z: Complex, iter: usize, max: usize) -> Complex {
2742    if iter == max {
2743        Complex::with_val(s.prec(), 1)
2744    } else if iter == 0 {
2745        (pow_nth(z.clone(), s.clone()) / z.clone().exp())
2746            / lower_incomplete_gamma_recursion(s, z, 1, max)
2747    } else if iter % 2 == 1 {
2748        s.clone() + iter
2749            - 1
2750            - ((s.clone() + iter - 1) * z.clone())
2751                / lower_incomplete_gamma_recursion(s, z, iter + 1, max)
2752    } else {
2753        s.clone() + iter - 1
2754            + (iter / 2 * z.clone() / lower_incomplete_gamma_recursion(s, z, iter + 1, max))
2755    }
2756}
2757pub fn subfactorial(z: Complex) -> Complex {
2758    subfactorial_recursion(z.clone(), 0, (z.prec().0 as usize / 4).max(32))
2759        + gamma(z.clone() + 1) / Float::with_val(z.prec().0, 1).exp()
2760}
2761fn subfactorial_recursion(z: Complex, iter: usize, max: usize) -> Complex {
2762    if iter == max {
2763        Complex::with_val(z.prec(), 1)
2764    } else if iter == 0 {
2765        Complex::with_val(z.prec(), -1).pow(z.clone()) / subfactorial_recursion(z, 1, max)
2766    } else {
2767        (z.clone() + iter + 1) - iter / subfactorial_recursion(z, iter + 1, max)
2768    }
2769}
2770#[allow(clippy::too_many_arguments)]
2771pub fn surface_area(
2772    func: Vec<NumStr>,
2773    func_vars: Vec<(String, Vec<NumStr>)>,
2774    options: Options,
2775    varx: String,
2776    mut startx: Complex,
2777    endx: Number,
2778    vary: String,
2779    starty_func: Vec<NumStr>,
2780    endy_func: Vec<NumStr>,
2781) -> Result<Number, &'static str> {
2782    if starty_func.is_empty() || endy_func.is_empty() {
2783        return Err("bad start/end");
2784    }
2785    let points = options.prec as usize / 16;
2786    let unitsx = endx.units;
2787    let endx = endx.number;
2788    let deltax: Complex = (endx.clone() - startx.clone()) / (points - 1);
2789    let mut area: Complex = Complex::new(options.prec);
2790    if let (Ok(Num(start)), Ok(Num(end))) = (
2791        do_math(starty_func.clone(), options, func_vars.clone()),
2792        do_math(endy_func.clone(), options, func_vars.clone()),
2793    ) {
2794        let starty = start.number;
2795        let endy = end.number;
2796        let unitsy = end.units;
2797        let deltay: Complex = (endy.clone() - starty.clone()) / (points - 1);
2798        let res = {
2799            let n = NumStr::new(Number::from(startx.clone(), unitsx));
2800            let func = place_var(func.clone(), &varx, n.clone());
2801            let func_vars = place_funcvar(func_vars.clone(), &varx, n);
2802            do_math_with_var(
2803                func.clone(),
2804                options,
2805                func_vars.clone(),
2806                &vary,
2807                NumStr::new(Number::from(starty.clone(), unitsy)),
2808            )?
2809        };
2810        match res {
2811            Num(n) => {
2812                let mut data: Vec<Vec<Complex>> = vec![Vec::new(); points];
2813                let units = n.units.map(|n| n.pow(2.0));
2814                data[0].push(n.number);
2815                for (nx, row) in data.iter_mut().enumerate() {
2816                    if nx + 1 == points {
2817                        startx.clone_from(&endx)
2818                    } else if nx != 0 {
2819                        startx += deltax.clone();
2820                    }
2821                    let n = NumStr::new(Number::from(startx.clone(), unitsx));
2822                    let mut func = place_var(func.clone(), &varx, n.clone());
2823                    let mut func_vars = place_funcvar(func_vars.clone(), &varx, n);
2824                    simplify(&mut func, &mut func_vars, options);
2825                    let mut starty = starty.clone();
2826                    for ny in 0..points {
2827                        if nx == 0 && ny == 0 {
2828                            continue;
2829                        }
2830                        if ny + 1 == points {
2831                            starty.clone_from(&endy)
2832                        } else if ny != 0 {
2833                            starty += deltay.clone();
2834                        }
2835                        row.push(
2836                            do_math_with_var(
2837                                func.clone(),
2838                                options,
2839                                func_vars.clone(),
2840                                &vary,
2841                                NumStr::new(Number::from(starty.clone(), unitsy)),
2842                            )?
2843                            .num()?
2844                            .number,
2845                        )
2846                    }
2847                }
2848                let k: Complex = sqr(deltax.clone()) * sqr(deltay.clone());
2849                for (nx, row) in data[..data.len() - 1].iter().enumerate() {
2850                    for (ny, z) in row[..row.len() - 1].iter().enumerate() {
2851                        let a = row[ny + 1].clone();
2852                        let b = data[nx + 1][ny].clone();
2853                        {
2854                            let a = a.clone() - z;
2855                            let b = b.clone() - z;
2856                            let i = deltay.clone() * b;
2857                            let j = deltax.clone() * a;
2858                            let i: Complex = sqr(i);
2859                            let j: Complex = sqr(j);
2860                            area += (i + j + k.clone()).sqrt() / 2;
2861                        }
2862                        {
2863                            let z = &data[nx + 1][ny + 1];
2864                            let a = a - z;
2865                            let b = b - z;
2866                            let i = deltax.clone() * b;
2867                            let j = deltay.clone() * a;
2868                            let i: Complex = sqr(i);
2869                            let j: Complex = sqr(j);
2870                            area += (i + j + k.clone()).sqrt() / 2
2871                        }
2872                    }
2873                }
2874                Ok(Number::from(area, units))
2875            }
2876            Vector(v) if v.len() == 3 => {
2877                let mut data: Vec<Vec<Vec<Complex>>> = vec![Vec::new(); points];
2878                let units = v[2].units.map(|n| n.pow(2.0));
2879                data[0].push(v.iter().map(|a| a.number.clone()).collect());
2880                for (nx, row) in data.iter_mut().enumerate() {
2881                    if nx + 1 == points {
2882                        startx.clone_from(&endx)
2883                    } else if nx != 0 {
2884                        startx += deltax.clone();
2885                    }
2886                    let n = NumStr::new(Number::from(startx.clone(), unitsx));
2887                    let mut func = place_var(func.clone(), &varx, n.clone());
2888                    let mut func_vars = place_funcvar(func_vars.clone(), &varx, n);
2889                    simplify(&mut func, &mut func_vars, options);
2890                    let mut starty = starty.clone();
2891                    for ny in 0..points {
2892                        if nx == 0 && ny == 0 {
2893                            continue;
2894                        }
2895                        if ny + 1 == points {
2896                            starty.clone_from(&endy)
2897                        } else if ny != 0 {
2898                            starty += deltay.clone();
2899                        }
2900                        let v = do_math_with_var(
2901                            func.clone(),
2902                            options,
2903                            func_vars.clone(),
2904                            &vary,
2905                            NumStr::new(Number::from(starty.clone(), unitsy)),
2906                        )?
2907                        .vec()?;
2908                        row.push(v.iter().map(|a| a.number.clone()).collect());
2909                    }
2910                }
2911                for (nx, row) in data[..data.len() - 1].iter().enumerate() {
2912                    for (ny, z) in row[..row.len() - 1].iter().enumerate() {
2913                        let a = row[ny + 1].clone();
2914                        let b = data[nx + 1][ny].clone();
2915                        {
2916                            let a0 = a[0].clone() - z[0].clone();
2917                            let a1 = a[1].clone() - z[1].clone();
2918                            let a2 = a[2].clone() - z[2].clone();
2919                            let b0 = b[0].clone() - z[0].clone();
2920                            let b1 = b[1].clone() - z[1].clone();
2921                            let b2 = b[2].clone() - z[2].clone();
2922                            let i = a1.clone() * b2.clone() - a2.clone() * b1.clone();
2923                            let j = a2 * b0.clone() - a0.clone() * b2;
2924                            let k = a0 * b1 - a1 * b0;
2925                            let i: Complex = sqr(i);
2926                            let j: Complex = sqr(j);
2927                            let k: Complex = sqr(k);
2928                            area += (i + j + k).sqrt() / 2;
2929                        }
2930                        {
2931                            let z = &data[nx + 1][ny + 1];
2932                            let a0 = a[0].clone() - z[0].clone();
2933                            let a1 = a[1].clone() - z[1].clone();
2934                            let a2 = a[2].clone() - z[2].clone();
2935                            let b0 = b[0].clone() - z[0].clone();
2936                            let b1 = b[1].clone() - z[1].clone();
2937                            let b2 = b[2].clone() - z[2].clone();
2938                            let i = a1.clone() * b2.clone() - a2.clone() * b1.clone();
2939                            let j = a2 * b0.clone() - a0.clone() * b2;
2940                            let k = a0 * b1 - a1 * b0;
2941                            let i: Complex = sqr(i);
2942                            let j: Complex = sqr(j);
2943                            let k: Complex = sqr(k);
2944                            area += (i + j + k).sqrt() / 2;
2945                        }
2946                    }
2947                }
2948                Ok(Number::from(area, units))
2949            }
2950            _ => Err("bad input"),
2951        }
2952    } else {
2953        let n = NumStr::new(Number::from(startx.clone(), unitsx));
2954        let temp_func = place_var(func.clone(), &varx, n.clone());
2955        let temp_func_vars = place_funcvar(func_vars.clone(), &varx, n.clone());
2956        let starty = do_math_with_var(
2957            starty_func.clone(),
2958            options,
2959            temp_func_vars.clone(),
2960            &varx,
2961            n.clone(),
2962        )?
2963        .num()?
2964        .number;
2965        let end = do_math_with_var(
2966            endy_func.clone(),
2967            options,
2968            temp_func_vars.clone(),
2969            &varx,
2970            n.clone(),
2971        )?
2972        .num()?;
2973        let mut endy = end.number;
2974        let unitsy = end.units;
2975        let mut deltay: Complex = (endy.clone() - starty.clone()) / (points - 1);
2976        match do_math_with_var(
2977            temp_func.clone(),
2978            options,
2979            temp_func_vars.clone(),
2980            &vary,
2981            NumStr::new(Number::from(starty.clone(), unitsy)),
2982        )? {
2983            Num(n) => {
2984                let mut data: Vec<Vec<[Complex; 2]>> = vec![Vec::new(); points];
2985                let units = n.units.map(|n| n.pow(2.0));
2986                data[0].push([starty.clone(), n.number]);
2987                for (nx, row) in data.iter_mut().enumerate() {
2988                    if nx + 1 == points {
2989                        startx.clone_from(&endx)
2990                    } else if nx != 0 {
2991                        startx += deltax.clone();
2992                    }
2993                    let n = NumStr::new(Number::from(startx.clone(), unitsx));
2994                    let mut func = place_var(func.clone(), &varx, n.clone());
2995                    let mut func_vars = place_funcvar(func_vars.clone(), &varx, n.clone());
2996                    simplify(&mut func, &mut func_vars, options);
2997                    let mut starty = starty.clone();
2998                    if nx != 0 {
2999                        starty = do_math_with_var(
3000                            starty_func.clone(),
3001                            options,
3002                            func_vars.clone(),
3003                            &varx,
3004                            n.clone(),
3005                        )?
3006                        .num()?
3007                        .number;
3008                        endy = do_math_with_var(
3009                            endy_func.clone(),
3010                            options,
3011                            func_vars.clone(),
3012                            &varx,
3013                            n.clone(),
3014                        )?
3015                        .num()?
3016                        .number;
3017                        deltay = (endy.clone() - starty.clone()) / (points - 1);
3018                    }
3019                    for ny in 0..points {
3020                        if nx == 0 && ny == 0 {
3021                            continue;
3022                        }
3023                        if ny + 1 == points {
3024                            starty.clone_from(&endy)
3025                        } else if ny != 0 {
3026                            starty += deltay.clone();
3027                        }
3028                        row.push([
3029                            starty.clone(),
3030                            do_math_with_var(
3031                                func.clone(),
3032                                options,
3033                                func_vars.clone(),
3034                                &vary,
3035                                NumStr::new(Number::from(starty.clone(), unitsy)),
3036                            )?
3037                            .num()?
3038                            .number,
3039                        ])
3040                    }
3041                }
3042                for (nx, row) in data[..data.len() - 1].iter().enumerate() {
3043                    for (ny, z) in row[..row.len() - 1].iter().enumerate() {
3044                        let a = row[ny + 1].clone();
3045                        let b = data[nx + 1][ny].clone();
3046                        {
3047                            let a1 = a[0].clone() - z[0].clone();
3048                            let a2 = a[1].clone() - z[1].clone();
3049                            let b0 = deltax.clone();
3050                            let b1 = b[0].clone() - z[0].clone();
3051                            let b2 = b[1].clone() - z[1].clone();
3052                            let i = a1.clone() * b2.clone() - a2.clone() * b1.clone();
3053                            let j = a2 * b0.clone();
3054                            let k = a1 * b0;
3055                            let i: Complex = sqr(i);
3056                            let j: Complex = sqr(j);
3057                            let k: Complex = sqr(k);
3058                            area += (i + j + k).sqrt() / 2;
3059                        }
3060                        {
3061                            let z = &data[nx + 1][ny + 1];
3062                            let a0 = deltax.clone();
3063                            let a1 = a[0].clone() - z[0].clone();
3064                            let a2 = a[1].clone() - z[1].clone();
3065                            let b1 = b[0].clone() - z[0].clone();
3066                            let b2 = b[1].clone() - z[1].clone();
3067                            let i = a1.clone() * b2.clone() - a2.clone() * b1.clone();
3068                            let j = a0.clone() * b2;
3069                            let k = a0 * b1;
3070                            let i: Complex = sqr(i);
3071                            let j: Complex = sqr(j);
3072                            let k: Complex = sqr(k);
3073                            area += (i + j + k).sqrt() / 2;
3074                        }
3075                    }
3076                }
3077                Ok(Number::from(area, units))
3078            }
3079            Vector(v) if v.len() == 3 => {
3080                let mut data: Vec<Vec<Vec<Complex>>> = vec![Vec::new(); points];
3081                let units = v[2].units.map(|n| n.pow(2.0));
3082                data[0].push(v.iter().map(|a| a.number.clone()).collect());
3083                for (nx, row) in data.iter_mut().enumerate() {
3084                    if nx + 1 == points {
3085                        startx.clone_from(&endx)
3086                    } else if nx != 0 {
3087                        startx += deltax.clone();
3088                    }
3089                    let n = NumStr::new(Number::from(startx.clone(), unitsx));
3090                    let mut func = place_var(func.clone(), &varx, n.clone());
3091                    let mut func_vars = place_funcvar(func_vars.clone(), &varx, n.clone());
3092                    simplify(&mut func, &mut func_vars, options);
3093                    let mut starty = starty.clone();
3094                    if nx != 0 {
3095                        starty = do_math_with_var(
3096                            starty_func.clone(),
3097                            options,
3098                            func_vars.clone(),
3099                            &varx,
3100                            n.clone(),
3101                        )?
3102                        .num()?
3103                        .number;
3104                        endy = do_math_with_var(
3105                            endy_func.clone(),
3106                            options,
3107                            func_vars.clone(),
3108                            &varx,
3109                            n.clone(),
3110                        )?
3111                        .num()?
3112                        .number;
3113                        deltay = (endy.clone() - starty.clone()) / (points - 1);
3114                    }
3115                    for ny in 0..points {
3116                        if nx == 0 && ny == 0 {
3117                            continue;
3118                        }
3119                        if ny + 1 == points {
3120                            starty.clone_from(&endy)
3121                        } else if ny != 0 {
3122                            starty += deltay.clone();
3123                        }
3124                        let v = do_math_with_var(
3125                            func.clone(),
3126                            options,
3127                            func_vars.clone(),
3128                            &vary,
3129                            NumStr::new(Number::from(starty.clone(), unitsy)),
3130                        )?
3131                        .vec()?;
3132                        row.push(v.iter().map(|a| a.number.clone()).collect());
3133                    }
3134                }
3135                for (nx, row) in data[..data.len() - 1].iter().enumerate() {
3136                    for (ny, z) in row[..row.len() - 1].iter().enumerate() {
3137                        let a = row[ny + 1].clone();
3138                        let b = data[nx + 1][ny].clone();
3139                        {
3140                            let a0 = a[0].clone() - z[0].clone();
3141                            let a1 = a[1].clone() - z[1].clone();
3142                            let a2 = a[2].clone() - z[2].clone();
3143                            let b0 = b[0].clone() - z[0].clone();
3144                            let b1 = b[1].clone() - z[1].clone();
3145                            let b2 = b[2].clone() - z[2].clone();
3146                            let i = a1.clone() * b2.clone() - a2.clone() * b1.clone();
3147                            let j = a2 * b0.clone() - a0.clone() * b2;
3148                            let k = a0 * b1 - a1 * b0;
3149                            let i: Complex = sqr(i);
3150                            let j: Complex = sqr(j);
3151                            let k: Complex = sqr(k);
3152                            area += (i + j + k).sqrt() / 2;
3153                        }
3154                        {
3155                            let z = &data[nx + 1][ny + 1];
3156                            let a0 = a[0].clone() - z[0].clone();
3157                            let a1 = a[1].clone() - z[1].clone();
3158                            let a2 = a[2].clone() - z[2].clone();
3159                            let b0 = b[0].clone() - z[0].clone();
3160                            let b1 = b[1].clone() - z[1].clone();
3161                            let b2 = b[2].clone() - z[2].clone();
3162                            let i = a1.clone() * b2.clone() - a2.clone() * b1.clone();
3163                            let j = a2 * b0.clone() - a0.clone() * b2;
3164                            let k = a0 * b1 - a1 * b0;
3165                            let i: Complex = sqr(i);
3166                            let j: Complex = sqr(j);
3167                            let k: Complex = sqr(k);
3168                            area += (i + j + k).sqrt() / 2;
3169                        }
3170                    }
3171                }
3172                Ok(Number::from(area, units))
3173            }
3174            _ => Err("bad input"),
3175        }
3176    }
3177}
3178pub fn length(
3179    func: Vec<NumStr>,
3180    func_vars: Vec<(String, Vec<NumStr>)>,
3181    options: Options,
3182    var: String,
3183    mut start: Complex,
3184    end: Number,
3185) -> Result<Number, &'static str> {
3186    let points = options.prec as usize / 4;
3187    let units = end.units;
3188    let end = end.number;
3189    let delta: Complex = (end.clone() - start.clone()) / points;
3190    let delta2: Complex = sqr(delta.clone());
3191    let mut x0: NumStr = do_math_with_var(
3192        func.clone(),
3193        options,
3194        func_vars.clone(),
3195        &var.clone(),
3196        NumStr::new(Number::from(start.clone(), units)),
3197    )?;
3198    let length_units = match x0.clone() {
3199        Num(a) => a.units,
3200        Vector(a) => {
3201            if a.iter().all(|b| b.units == a[0].units) {
3202                a[0].units
3203            } else {
3204                None
3205            }
3206        }
3207        _ => return Err("not supported arc length data"),
3208    };
3209    let mut length = Complex::new(options.prec);
3210    for i in 0..points {
3211        if i + 1 == points {
3212            start.clone_from(&end)
3213        } else {
3214            start += delta.clone();
3215        }
3216        let x1 = do_math_with_var(
3217            func.clone(),
3218            options,
3219            func_vars.clone(),
3220            &var.clone(),
3221            NumStr::new(Number::from(start.clone(), units)),
3222        )?;
3223        match (x0, x1) {
3224            (Num(xi), Num(xf)) => {
3225                let nl: Complex = sqr(xf.number.clone() - xi.number) + delta2.clone();
3226                length += nl.sqrt();
3227                x0 = Num(xf);
3228            }
3229            (Vector(xi), Vector(xf)) if xf.len() == 1 => {
3230                let nl: Complex = sqr(xf[0].number.clone() - xi[0].number.clone()) + delta2.clone();
3231                length += nl.sqrt();
3232                x0 = Vector(xf);
3233            }
3234            (Vector(xi), Vector(xf)) => {
3235                let nl: Complex = xi
3236                    .iter()
3237                    .zip(xf.clone())
3238                    .fold(Complex::new(options.prec), |sum, x| {
3239                        sum + sqr(x.1.number - x.0.number.clone())
3240                    });
3241                length += nl.sqrt();
3242                x0 = Vector(xf);
3243            }
3244            (_, _) => return Err("not supported arc length data"),
3245        };
3246    }
3247    Ok(Number::from(length, length_units))
3248}
3249#[allow(clippy::too_many_arguments)]
3250pub fn area(
3251    mut func: Vec<NumStr>,
3252    mut func_vars: Vec<(String, Vec<NumStr>)>,
3253    options: Options,
3254    var: String,
3255    mut start: Complex,
3256    mut end: Number,
3257    nth: Complex,
3258    combine: bool,
3259) -> Result<NumStr, &'static str> {
3260    let mut negate = false;
3261    if start.real() > end.number.real() && nth == 1 {
3262        negate = true;
3263        (end.number, start) = (start, end.number)
3264    }
3265    if start.real().is_infinite() {
3266        let neg = start.real().is_sign_negative();
3267        start = Complex::with_val(options.prec, 1) << (options.prec / 16);
3268        if neg {
3269            start *= -1
3270        }
3271    }
3272    if end.number.real().is_infinite() {
3273        let neg = end.number.real().is_sign_negative();
3274        end.number = Complex::with_val(options.prec, 1) << (options.prec / 16);
3275        if neg {
3276            end.number *= -1
3277        }
3278    }
3279    let points = options.prec as usize / 4;
3280    let units = end.units;
3281    let mut end = end.number;
3282    let mut funcs = Vec::new();
3283    if combine
3284        && !func.is_empty()
3285        && func[0] == LeftCurlyBracket
3286        && func[func.len() - 1] == RightCurlyBracket
3287    {
3288        let mut brackets = 0;
3289        let mut last = 1;
3290        for (i, f) in func.iter().enumerate() {
3291            match f {
3292                LeftBracket | LeftCurlyBracket => brackets += 1,
3293                RightBracket | RightCurlyBracket => brackets -= 1,
3294                Comma if brackets == 1 => {
3295                    funcs.push(func[last..i].to_vec());
3296                    last = i + 1;
3297                }
3298                _ => {}
3299            }
3300        }
3301        if last != 1 {
3302            func = func[last..func.len().saturating_sub(1)].to_vec();
3303        }
3304    }
3305    let mut areavec: Vec<Number> = Vec::new();
3306    let div = Float::with_val(options.prec, 0.5).pow(options.prec / 2);
3307    let mut delta: Complex = (end.clone() - start.clone()) / points;
3308    let mut area: Complex = Complex::new(options.prec);
3309    let mut x0 = do_math_with_var(
3310        func.clone(),
3311        options,
3312        func_vars.clone(),
3313        &var,
3314        NumStr::new(Number::from(start.clone(), units)),
3315    )?;
3316    if start == end {
3317        return match x0 {
3318            Num(_) => Ok(NumStr::new(Number::from(Complex::new(options.prec), None))),
3319            Vector(_) => Ok(Vector(Vec::new())),
3320            _ => Err(
3321                "not supported area data, if parametric have the 2nd arg start and end with the { } brackets",
3322            ),
3323        };
3324    }
3325    {
3326        fn check_bounds(
3327            func: Vec<NumStr>,
3328            func_vars: Vec<(String, Vec<NumStr>)>,
3329            options: Options,
3330            var: String,
3331            delta: &mut Complex,
3332            units: Option<Units>,
3333            x0: &mut NumStr,
3334            start: &mut Complex,
3335            right: bool,
3336            compute: bool,
3337        ) -> Result<(), &'static str> {
3338            let mut has = false;
3339            if let Ok(a) = x0.num() {
3340                if !a.number.real().is_finite() {
3341                    let points = options.prec as usize / 4;
3342                    let end = if right {
3343                        points * delta.clone() + start.clone()
3344                    } else {
3345                        start.clone() - points * delta.clone()
3346                    };
3347                    if right {
3348                        *start += delta.clone() >> 4;
3349                    } else {
3350                        *start -= delta.clone() >> 4;
3351                    }
3352                    *delta = if right {
3353                        (end.clone() - start.clone()) / points
3354                    } else {
3355                        (start.clone() - end.clone()) / points
3356                    };
3357                    *x0 = do_math_with_var(
3358                        func.clone(),
3359                        options,
3360                        func_vars.clone(),
3361                        &var,
3362                        NumStr::new(Number::from(start.clone(), units)),
3363                    )?;
3364                    has = true
3365                }
3366            }
3367            if !has && compute {
3368                *x0 = do_math_with_var(
3369                    func.clone(),
3370                    options,
3371                    func_vars.clone(),
3372                    &var,
3373                    NumStr::new(Number::from(start.clone(), units)),
3374                )?;
3375                check_bounds(
3376                    func, func_vars, options, var, delta, units, x0, start, right, false,
3377                )?
3378            }
3379            Ok(())
3380        }
3381        check_bounds(
3382            func.clone(),
3383            func_vars.clone(),
3384            options,
3385            var.clone(),
3386            &mut delta,
3387            units,
3388            &mut x0,
3389            &mut start,
3390            true,
3391            false,
3392        )?;
3393        let mut endv = do_math_with_var(
3394            func.clone(),
3395            options,
3396            func_vars.clone(),
3397            &var,
3398            NumStr::new(Number::from(end.clone(), units)),
3399        )?;
3400        check_bounds(
3401            func.clone(),
3402            func_vars.clone(),
3403            options,
3404            var.clone(),
3405            &mut delta,
3406            units,
3407            &mut endv,
3408            &mut end,
3409            false,
3410            false,
3411        )?;
3412        if nth == 1 && end.real().clone() - start.real().clone() > 2.0 {
3413            let mut small_start = false;
3414            if start.real().is_sign_negative() {
3415                if let Ok(a) = x0.num() {
3416                    if a.number.real().clone().abs() < Float::with_val(options.prec, 1) >> 16 {
3417                        let a = do_math_with_var(
3418                            func.clone(),
3419                            options,
3420                            func_vars.clone(),
3421                            &var,
3422                            NumStr::new(Number::from(start.clone() * 2 - 1.141, units)),
3423                        )?
3424                        .num()?;
3425                        if a.number.real().clone().abs() < Float::with_val(options.prec, 1) >> 17 {
3426                            let a = do_math_with_var(
3427                                func.clone(),
3428                                options,
3429                                func_vars.clone(),
3430                                &var,
3431                                NumStr::new(Number::from(
3432                                    -(Complex::with_val(options.prec, 4) << (options.prec / 16)),
3433                                    units,
3434                                )),
3435                            )?
3436                            .num()?;
3437                            if a.number.real().clone().abs()
3438                                < Float::with_val(options.prec, 1) >> 18
3439                            {
3440                                small_start = true;
3441                            }
3442                        }
3443                    }
3444                }
3445            }
3446            let mut small_end = false;
3447            if end.real().is_sign_positive() {
3448                if let Ok(a) = endv.num() {
3449                    if a.number.real().clone().abs() < Float::with_val(options.prec, 1) >> 16 {
3450                        let a = do_math_with_var(
3451                            func.clone(),
3452                            options,
3453                            func_vars.clone(),
3454                            &var,
3455                            NumStr::new(Number::from(end.clone() * 2 + 1.141, units)),
3456                        )?
3457                        .num()?;
3458                        if a.number.real().clone().abs() < Float::with_val(options.prec, 1) >> 17 {
3459                            let a = do_math_with_var(
3460                                func.clone(),
3461                                options,
3462                                func_vars.clone(),
3463                                &var,
3464                                NumStr::new(Number::from(
3465                                    Complex::with_val(options.prec, 4) << (options.prec / 16),
3466                                    units,
3467                                )),
3468                            )?
3469                            .num()?;
3470                            if a.number.real().clone().abs()
3471                                < Float::with_val(options.prec, 1) >> 18
3472                            {
3473                                small_end = true
3474                            }
3475                        }
3476                    }
3477                }
3478            }
3479            let two = NumStr::new(Number::from(Complex::with_val(options.prec, 2), None));
3480            let one = NumStr::new(Number::from(Complex::with_val(options.prec, 1), None));
3481            fn change_var(
3482                func: &mut [NumStr],
3483                func_vars: &mut Vec<(String, Vec<NumStr>)>,
3484                from: String,
3485                fto: Vec<NumStr>,
3486            ) {
3487                let to = format!("@!@{from}@");
3488                for v in func.iter_mut() {
3489                    if *v == Func(from.clone()) {
3490                        *v = Func(to.clone())
3491                    }
3492                }
3493                for func in func_vars.iter_mut() {
3494                    for v in func.1.iter_mut() {
3495                        if *v == Func(from.clone()) {
3496                            *v = Func(to.clone())
3497                        }
3498                    }
3499                }
3500                func_vars.push((to, fto));
3501            }
3502            match (small_start, small_end) {
3503                (true, true) => {
3504                    change_var(
3505                        &mut func,
3506                        &mut func_vars,
3507                        var.clone(),
3508                        vec![
3509                            Func(var.clone()),
3510                            Division,
3511                            LeftBracket,
3512                            one.clone(),
3513                            Minus,
3514                            Func(var.clone()),
3515                            Exponent,
3516                            two.clone(),
3517                            RightBracket,
3518                        ],
3519                    );
3520                    func.insert(0, LeftBracket);
3521                    func.extend(vec![
3522                        RightBracket,
3523                        Multiplication,
3524                        LeftBracket,
3525                        one.clone(),
3526                        Plus,
3527                        Func(var.clone()),
3528                        Exponent,
3529                        two.clone(),
3530                        RightBracket,
3531                        Division,
3532                        LeftBracket,
3533                        one,
3534                        Minus,
3535                        Func(var.clone()),
3536                        Exponent,
3537                        two.clone(),
3538                        RightBracket,
3539                        Exponent,
3540                        two,
3541                    ]);
3542                    start = Complex::with_val(options.prec, -1);
3543                    end = Complex::with_val(options.prec, 1);
3544                    delta = 2 * end.clone() / points;
3545                    check_bounds(
3546                        func.clone(),
3547                        func_vars.clone(),
3548                        options,
3549                        var.clone(),
3550                        &mut delta,
3551                        units,
3552                        &mut x0,
3553                        &mut start,
3554                        true,
3555                        true,
3556                    )?;
3557                    check_bounds(
3558                        func.clone(),
3559                        func_vars.clone(),
3560                        options,
3561                        var.clone(),
3562                        &mut delta,
3563                        units,
3564                        &mut endv,
3565                        &mut end,
3566                        false,
3567                        true,
3568                    )?;
3569                }
3570                (false, true) => {
3571                    change_var(
3572                        &mut func,
3573                        &mut func_vars,
3574                        var.clone(),
3575                        vec![
3576                            NumStr::new(Number::from(start, None)),
3577                            Plus,
3578                            Func(var.clone()),
3579                            Division,
3580                            LeftBracket,
3581                            one.clone(),
3582                            Minus,
3583                            Func(var.clone()),
3584                            RightBracket,
3585                        ],
3586                    );
3587                    func.insert(0, LeftBracket);
3588                    func.extend(vec![
3589                        RightBracket,
3590                        Division,
3591                        LeftBracket,
3592                        one,
3593                        Minus,
3594                        Func(var.clone()),
3595                        RightBracket,
3596                        Exponent,
3597                        two,
3598                    ]);
3599                    start = Complex::new(options.prec);
3600                    end = Complex::with_val(options.prec, 1);
3601                    delta = end.clone() / points;
3602                    check_bounds(
3603                        func.clone(),
3604                        func_vars.clone(),
3605                        options,
3606                        var.clone(),
3607                        &mut delta,
3608                        units,
3609                        &mut x0,
3610                        &mut start,
3611                        true,
3612                        true,
3613                    )?;
3614                    check_bounds(
3615                        func.clone(),
3616                        func_vars.clone(),
3617                        options,
3618                        var.clone(),
3619                        &mut delta,
3620                        units,
3621                        &mut endv,
3622                        &mut end,
3623                        false,
3624                        true,
3625                    )?;
3626                }
3627                (true, false) => {
3628                    change_var(
3629                        &mut func,
3630                        &mut func_vars,
3631                        var.clone(),
3632                        vec![
3633                            NumStr::new(Number::from(end, None)),
3634                            Minus,
3635                            LeftBracket,
3636                            one.clone(),
3637                            Minus,
3638                            Func(var.clone()),
3639                            RightBracket,
3640                            Division,
3641                            Func(var.clone()),
3642                        ],
3643                    );
3644                    func.insert(0, LeftBracket);
3645                    func.extend(vec![
3646                        RightBracket,
3647                        Division,
3648                        Func(var.clone()),
3649                        Exponent,
3650                        two,
3651                    ]);
3652                    start = Complex::new(options.prec);
3653                    end = Complex::with_val(options.prec, 1);
3654                    delta = end.clone() / points;
3655                    check_bounds(
3656                        func.clone(),
3657                        func_vars.clone(),
3658                        options,
3659                        var.clone(),
3660                        &mut delta,
3661                        units,
3662                        &mut x0,
3663                        &mut start,
3664                        true,
3665                        true,
3666                    )?;
3667                    check_bounds(
3668                        func.clone(),
3669                        func_vars.clone(),
3670                        options,
3671                        var.clone(),
3672                        &mut delta,
3673                        units,
3674                        &mut endv,
3675                        &mut end,
3676                        false,
3677                        true,
3678                    )?;
3679                }
3680                _ => {}
3681            }
3682        }
3683    }
3684    let yunits = if let Num(ref a) = x0 { a.units } else { None };
3685    if !funcs.is_empty() {
3686        let mut nx0t = Complex::new(options.prec);
3687        for i in &funcs {
3688            nx0t += sqr((do_math_with_var(
3689                i.clone(),
3690                options,
3691                func_vars.clone(),
3692                &var,
3693                NumStr::new(Number::from(start.clone() + div.clone(), units)),
3694            )?
3695            .num()?
3696            .number
3697                - do_math_with_var(
3698                    i.clone(),
3699                    options,
3700                    func_vars.clone(),
3701                    &var,
3702                    NumStr::new(Number::from(start.clone(), units)),
3703                )?
3704                .num()?
3705                .number)
3706                / div.clone())
3707        }
3708    }
3709    let h: Complex = delta.clone() / 4;
3710    let body = |i: usize| -> Result<(Option<Complex>, Option<Vec<Number>>), &str> {
3711        let point = if i + 1 == points {
3712            end.clone()
3713        } else {
3714            start.clone() + (i + 1) * delta.clone()
3715        };
3716        let x0 = do_math_with_var(
3717            func.clone(),
3718            options,
3719            func_vars.clone(),
3720            &var,
3721            NumStr::new(Number::from(point.clone() - 4 * h.clone(), units)),
3722        )?;
3723        let x1 = do_math_with_var(
3724            func.clone(),
3725            options,
3726            func_vars.clone(),
3727            &var,
3728            NumStr::new(Number::from(point.clone() - 3 * h.clone(), units)),
3729        )?;
3730        let x2 = do_math_with_var(
3731            func.clone(),
3732            options,
3733            func_vars.clone(),
3734            &var,
3735            NumStr::new(Number::from(point.clone() - 2 * h.clone(), units)),
3736        )?;
3737        let x3 = do_math_with_var(
3738            func.clone(),
3739            options,
3740            func_vars.clone(),
3741            &var,
3742            NumStr::new(Number::from(point.clone() - h.clone(), units)),
3743        )?;
3744        let x4 = do_math_with_var(
3745            func.clone(),
3746            options,
3747            func_vars.clone(),
3748            &var,
3749            NumStr::new(Number::from(point.clone(), units)),
3750        )?;
3751        match (x0, x1, x2, x3, x4) {
3752            (Num(nx0), Num(nx1), Num(nx2), Num(nx3), Num(nx4)) if funcs.is_empty() => {
3753                let n0;
3754                let n1;
3755                let n2;
3756                let n3;
3757                let n4;
3758                if nth != 1.0 {
3759                    let nt = pow_nth(end.clone() - point.clone() + delta.clone(), nth.clone() - 1);
3760                    n0 = nx0.number * nt;
3761                    let n: Complex = end.clone() - point.clone() + 3 * h.clone();
3762                    let nt = pow_nth(n, nth.clone() - 1);
3763                    n1 = nx1.number * nt;
3764                    let n: Complex = end.clone() - point.clone() + 2 * h.clone();
3765                    let nt = pow_nth(n, nth.clone() - 1);
3766                    n2 = nx2.number * nt;
3767                    let n: Complex = end.clone() - point.clone() + h.clone();
3768                    let nt = pow_nth(n, nth.clone() - 1);
3769                    n3 = nx3.number * nt;
3770                    let n: Complex = end.clone() - point.clone();
3771                    let nt = pow_nth(n, nth.clone() - 1);
3772                    n4 = nx4.number * nt;
3773                } else {
3774                    n0 = nx0.number;
3775                    n1 = nx1.number;
3776                    n2 = nx2.number;
3777                    n3 = nx3.number;
3778                    n4 = nx4.number;
3779                }
3780                Ok((
3781                    Some(2 * h.clone() * (7 * (n0 + n4) + 12 * n2 + 32 * (n1 + n3)) / 45),
3782                    None,
3783                ))
3784            }
3785            (Num(nx0), Num(nx1), Num(nx2), Num(nx3), Num(nx4)) => {
3786                let mut nx1t = Complex::new(options.prec);
3787                let mut nx2t = Complex::new(options.prec);
3788                let mut nx3t = Complex::new(options.prec);
3789                let mut nx4t = Complex::new(options.prec);
3790                for i in &funcs {
3791                    nx1t += sqr((do_math_with_var(
3792                        i.clone(),
3793                        options,
3794                        func_vars.clone(),
3795                        &var,
3796                        NumStr::new(Number::from(
3797                            point.clone() - 3 * h.clone() + div.clone(),
3798                            units,
3799                        )),
3800                    )?
3801                    .num()?
3802                    .number
3803                        - do_math_with_var(
3804                            i.clone(),
3805                            options,
3806                            func_vars.clone(),
3807                            &var,
3808                            NumStr::new(Number::from(point.clone() - 3 * h.clone(), units)),
3809                        )?
3810                        .num()?
3811                        .number)
3812                        / div.clone());
3813                    nx2t += sqr((do_math_with_var(
3814                        i.clone(),
3815                        options,
3816                        func_vars.clone(),
3817                        &var,
3818                        NumStr::new(Number::from(
3819                            point.clone() - 2 * h.clone() + div.clone(),
3820                            units,
3821                        )),
3822                    )?
3823                    .num()?
3824                    .number
3825                        - do_math_with_var(
3826                            i.clone(),
3827                            options,
3828                            func_vars.clone(),
3829                            &var,
3830                            NumStr::new(Number::from(point.clone() - 2 * h.clone(), units)),
3831                        )?
3832                        .num()?
3833                        .number)
3834                        / div.clone());
3835                    nx3t += sqr((do_math_with_var(
3836                        i.clone(),
3837                        options,
3838                        func_vars.clone(),
3839                        &var,
3840                        NumStr::new(Number::from(point.clone() - h.clone() + div.clone(), units)),
3841                    )?
3842                    .num()?
3843                    .number
3844                        - do_math_with_var(
3845                            i.clone(),
3846                            options,
3847                            func_vars.clone(),
3848                            &var,
3849                            NumStr::new(Number::from(point.clone() - h.clone(), units)),
3850                        )?
3851                        .num()?
3852                        .number)
3853                        / div.clone());
3854                    nx4t += sqr((do_math_with_var(
3855                        i.clone(),
3856                        options,
3857                        func_vars.clone(),
3858                        &var,
3859                        NumStr::new(Number::from(point.clone() + div.clone(), units)),
3860                    )?
3861                    .num()?
3862                    .number
3863                        - do_math_with_var(
3864                            i.clone(),
3865                            options,
3866                            func_vars.clone(),
3867                            &var,
3868                            NumStr::new(Number::from(point.clone(), units)),
3869                        )?
3870                        .num()?
3871                        .number)
3872                        / div.clone())
3873                }
3874                let nx1 = nx1.number * nx1t.sqrt();
3875                let nx2 = nx2.number * nx2t.sqrt();
3876                let nx3 = nx3.number * nx3t.sqrt();
3877                let nx4 = nx4.number * nx4t.sqrt();
3878                let n0;
3879                let n1;
3880                let n2;
3881                let n3;
3882                let n4;
3883                if nth != 1.0 {
3884                    if i == 0 {
3885                        let nt =
3886                            pow_nth(end.clone() - point.clone() + delta.clone(), nth.clone() - 1);
3887                        n0 = nx0.number * nt;
3888                    } else {
3889                        n0 = nx0.number;
3890                    }
3891                    let n: Complex = end.clone() - point.clone() + 3 * h.clone();
3892                    let nt: Complex = pow_nth(n, nth.clone() - 1);
3893                    n1 = nx1 * nt;
3894                    let n: Complex = end.clone() - point.clone() + 2 * h.clone();
3895                    let nt: Complex = pow_nth(n, nth.clone() - 1);
3896                    n2 = nx2 * nt;
3897                    let n: Complex = end.clone() - point.clone() + h.clone();
3898                    let nt: Complex = pow_nth(n, nth.clone() - 1);
3899                    n3 = nx3 * nt;
3900                    let n: Complex = end.clone() - point.clone();
3901                    let nt: Complex = pow_nth(n, nth.clone() - 1);
3902                    n4 = nx4 * nt;
3903                } else {
3904                    n0 = nx0.number;
3905                    n1 = nx1;
3906                    n2 = nx2;
3907                    n3 = nx3;
3908                    n4 = nx4;
3909                }
3910                Ok((
3911                    Some(2 * h.clone() * (7 * (n0 + n4.clone()) + 12 * n2 + 32 * (n1 + n3)) / 45),
3912                    None,
3913                ))
3914            }
3915            (Vector(nx0), Vector(nx1), Vector(nx2), Vector(nx3), Vector(nx4)) if !combine => {
3916                let mut areavec = Vec::new();
3917                for i in 0..nx0.len() {
3918                    let n0;
3919                    let n1;
3920                    let n2;
3921                    let n3;
3922                    let n4;
3923                    if nth != 1.0 {
3924                        let nt =
3925                            pow_nth(end.clone() - point.clone() + delta.clone(), nth.clone() - 1);
3926                        n0 = nx0[i].number.clone() * nt;
3927                        let n: Complex = end.clone() - point.clone() + 3 * h.clone();
3928                        let nt = pow_nth(n, nth.clone() - 1);
3929                        n1 = nx1[i].number.clone() * nt;
3930                        let n: Complex = end.clone() - point.clone() + 2 * h.clone();
3931                        let nt = pow_nth(n, nth.clone() - 1);
3932                        n2 = nx2[i].number.clone() * nt;
3933                        let n: Complex = end.clone() - point.clone() + h.clone();
3934                        let nt = pow_nth(n, nth.clone() - 1);
3935                        n3 = nx3[i].number.clone() * nt;
3936                        let n: Complex = end.clone() - point.clone();
3937                        let nt = pow_nth(n, nth.clone() - 1);
3938                        n4 = nx4[i].number.clone() * nt;
3939                    } else {
3940                        n0 = nx0[i].number.clone();
3941                        n1 = nx1[i].number.clone();
3942                        n2 = nx2[i].number.clone();
3943                        n3 = nx3[i].number.clone();
3944                        n4 = nx4[i].number.clone();
3945                    }
3946                    areavec.push(Number::from(
3947                        2 * h.clone() * (7 * (n0 + n4) + 12 * n2 + 32 * (n1 + n3)) / 45,
3948                        match (units, nx1[i].units) {
3949                            (Some(a), Some(b)) => Some(a.mul(&b)),
3950                            (Some(a), None) | (None, Some(a)) => Some(a),
3951                            (None, None) => None,
3952                        },
3953                    ))
3954                }
3955                Ok((None, Some(areavec)))
3956            }
3957            (_, _, _, _, _) => Err(
3958                "not supported area data, if parametric have the 2nd arg start and end with the { } brackets",
3959            ),
3960        }
3961    };
3962    #[allow(clippy::type_complexity)]
3963    let data: Vec<Result<(Option<Complex>, Option<Vec<Number>>), &str>> = if options.graphing {
3964        (0..points).map(body).collect()
3965    } else {
3966        #[cfg(feature = "rayon")]
3967        let r = (0..points).into_par_iter().map(body).collect();
3968        #[cfg(not(feature = "rayon"))]
3969        let r = (0..points).map(body).collect();
3970        r
3971    };
3972    for d in data {
3973        if let Ok(a) = d {
3974            if let Some(a) = a.0 {
3975                area += a
3976            } else if let Some(a) = a.1 {
3977                if areavec.is_empty() {
3978                    areavec = a
3979                } else {
3980                    for (a, b) in areavec.iter_mut().zip(a.iter()) {
3981                        a.number += b.number.clone()
3982                    }
3983                }
3984            }
3985        } else if let Err(s) = d {
3986            return Err(s);
3987        }
3988    }
3989    let g = gamma(nth.clone());
3990    if areavec.is_empty() {
3991        Ok(NumStr::new(Number::from(
3992            if negate { -area / g } else { area / g },
3993            match (units, yunits) {
3994                (Some(a), Some(b)) => Some(a.mul(&b)),
3995                (Some(a), None) | (None, Some(a)) => Some(a),
3996                (None, None) => None,
3997            },
3998        )))
3999    } else {
4000        Ok(Vector(
4001            areavec
4002                .iter()
4003                .map(|a| {
4004                    Number::from(
4005                        if negate {
4006                            -a.number.clone() / g.clone()
4007                        } else {
4008                            a.number.clone() / g.clone()
4009                        },
4010                        a.units,
4011                    )
4012                })
4013                .collect::<Vec<Number>>(),
4014        ))
4015    }
4016}
4017pub fn iter(
4018    func: Vec<NumStr>,
4019    func_vars: Vec<(String, Vec<NumStr>)>,
4020    options: Options,
4021    var: String,
4022    mut x: NumStr,
4023    n: Float,
4024    all: bool,
4025) -> Result<NumStr, &'static str> {
4026    if n.is_infinite() {
4027        let mut last = NumStr::new(Number::from(Complex::with_val(options.prec, Nan), None));
4028        let mut j = 0;
4029        if all {
4030            if let Num(num) = x.clone() {
4031                let mut vec = vec![*num];
4032                loop {
4033                    if j > 10000 {
4034                        return Ok(NumStr::new(Number::from(
4035                            Complex::with_val(options.prec, Nan),
4036                            None,
4037                        )));
4038                    }
4039                    j += 1;
4040                    last = x.clone();
4041                    x = do_math_with_var(func.clone(), options, func_vars.clone(), &var, x)?;
4042                    if last == x {
4043                        break;
4044                    }
4045                    vec.push(x.num()?);
4046                }
4047                Ok(Vector(vec))
4048            } else if let Vector(v) = x.clone() {
4049                let mut vec = vec![v];
4050                loop {
4051                    if j > 10000 {
4052                        return Ok(NumStr::new(Number::from(
4053                            Complex::with_val(options.prec, Nan),
4054                            None,
4055                        )));
4056                    }
4057                    j += 1;
4058                    last = x.clone();
4059                    x = do_math_with_var(func.clone(), options, func_vars.clone(), &var, x)?;
4060                    if last == x {
4061                        break;
4062                    }
4063                    vec.push(x.vec()?);
4064                }
4065                Ok(Matrix(vec))
4066            } else {
4067                return Err("unsupported iter");
4068            }
4069        } else {
4070            while last != x {
4071                if j > 10000 {
4072                    return Ok(NumStr::new(Number::from(
4073                        Complex::with_val(options.prec, Nan),
4074                        None,
4075                    )));
4076                }
4077                j += 1;
4078                last = x.clone();
4079                x = do_math_with_var(func.clone(), options, func_vars.clone(), &var, x)?
4080            }
4081            Ok(x)
4082        }
4083    } else {
4084        let n = n
4085            .to_integer()
4086            .unwrap_or_default()
4087            .to_usize()
4088            .unwrap_or_default();
4089        if all {
4090            if let Num(num) = x.clone() {
4091                let mut vec = vec![*num];
4092                for _ in 0..n {
4093                    x = do_math_with_var(func.clone(), options, func_vars.clone(), &var, x)?;
4094                    vec.push(x.num()?);
4095                }
4096                Ok(Vector(vec))
4097            } else if let Vector(v) = x.clone() {
4098                let mut vec = vec![v];
4099                for _ in 0..n {
4100                    x = do_math_with_var(func.clone(), options, func_vars.clone(), &var, x)?;
4101                    vec.push(x.vec()?);
4102                }
4103                Ok(Matrix(vec))
4104            } else {
4105                return Err("unsupported iter");
4106            }
4107        } else {
4108            for _ in 0..n {
4109                x = do_math_with_var(func.clone(), options, func_vars.clone(), &var, x)?
4110            }
4111            Ok(x)
4112        }
4113    }
4114}
4115pub fn solve(
4116    mut func: Vec<NumStr>,
4117    mut func_vars: Vec<(String, Vec<NumStr>)>,
4118    mut options: Options,
4119    var: String,
4120    x: Number,
4121) -> Result<NumStr, &'static str> {
4122    //newtons method, x-f(x)/f'(x)
4123    let units = x.units;
4124    let mut x = x.number;
4125    if x.real().is_nan() {
4126        let points = if x.imag().is_zero() {
4127            vec![
4128                Number::from(Complex::new(options.prec), None),
4129                Number::from(Complex::with_val(options.prec, -2), None),
4130                Number::from(Complex::with_val(options.prec, 2), None),
4131            ]
4132        } else {
4133            vec![
4134                Number::from(Complex::new(options.prec), None),
4135                Number::from(Complex::with_val(options.prec, -2), None),
4136                Number::from(Complex::with_val(options.prec, 2), None),
4137                Number::from(Complex::with_val(options.prec, (0, -2)), None),
4138                Number::from(Complex::with_val(options.prec, (0, 2)), None),
4139                Number::from(Complex::with_val(options.prec, (-4, 4)), None),
4140                Number::from(Complex::with_val(options.prec, (4, 4)), None),
4141                Number::from(Complex::with_val(options.prec, (-4, -4)), None),
4142                Number::from(Complex::with_val(options.prec, (4, -4)), None),
4143            ]
4144        };
4145        let mut values: Vec<Number> = Vec::new();
4146        let mut first = true;
4147        'main: for p in points {
4148            let v = solve(
4149                func.clone(),
4150                func_vars.clone(),
4151                options,
4152                var.clone(),
4153                p.clone(),
4154            )?
4155            .num()?;
4156            if !v.number.real().is_nan() {
4157                if first {
4158                    first = false;
4159                    func.insert(0, LeftBracket);
4160                    func.push(RightBracket);
4161                    func.push(Division);
4162                    func.push(LeftBracket);
4163                    func.push(LeftBracket);
4164                    func.push(Func(var.clone()));
4165                    func.push(Minus);
4166                    func.push(NumStr::new(v.clone()));
4167                    func.push(RightBracket);
4168                    func.push(RightBracket);
4169                } else {
4170                    for n1 in &values {
4171                        if -(n1.number.real() - v.number.real().clone())
4172                            .clone()
4173                            .abs()
4174                            .log2()
4175                            > options.prec / 16
4176                            && -(n1.number.imag() - v.number.imag().clone())
4177                                .clone()
4178                                .abs()
4179                                .log2()
4180                                > options.prec / 16
4181                        {
4182                            continue 'main;
4183                        }
4184                    }
4185                    func.insert(func.len() - 1, Multiplication);
4186                    func.insert(func.len() - 1, LeftBracket);
4187                    func.insert(func.len() - 1, Func(var.clone()));
4188                    func.insert(func.len() - 1, Minus);
4189                    func.insert(func.len() - 1, NumStr::new(v.clone()));
4190                    func.insert(func.len() - 1, RightBracket);
4191                }
4192                values.push(v);
4193            }
4194        }
4195        Ok(if values.is_empty() {
4196            NumStr::new(Number::from(Complex::with_val(options.prec, Nan), None))
4197        } else if values.len() == 1 {
4198            NumStr::new(values[0].clone())
4199        } else {
4200            Vector(values)
4201        })
4202    } else {
4203        let op = options.prec;
4204        let prec;
4205        (prec, options.prec) = set_slope_prec(options.prec, 1);
4206        x.set_prec(options.prec);
4207        set_prec(&mut func, &mut func_vars, options.prec);
4208        for _ in 0..(op / 4).max(64) {
4209            let n = Number::from(x.clone(), None);
4210            let y = do_math_with_var(
4211                func.clone(),
4212                options,
4213                func_vars.clone(),
4214                &var.clone(),
4215                NumStr::new(n.clone()),
4216            )?;
4217            x -= y.num()?.number
4218                / slopesided(
4219                    func.clone(),
4220                    func_vars.clone(),
4221                    options,
4222                    var.clone(),
4223                    n,
4224                    false,
4225                    1,
4226                    true,
4227                    Some(y),
4228                    None,
4229                    Some(prec),
4230                )?
4231                .num()?
4232                .number
4233        }
4234        let last = x.clone();
4235        let n = Number::from(x.clone(), None);
4236        let y = do_math_with_var(
4237            func.clone(),
4238            options,
4239            func_vars.clone(),
4240            &var.clone(),
4241            NumStr::new(n.clone()),
4242        )?;
4243        let k = slopesided(
4244            func,
4245            func_vars,
4246            options,
4247            var,
4248            n,
4249            false,
4250            1,
4251            true,
4252            Some(y.clone()),
4253            None,
4254            Some(prec),
4255        )?
4256        .num()?
4257        .number;
4258        x -= y.num()?.number / k.clone();
4259        if (last - x.clone()).abs().real().clone().log2() < op as i32 / -16 && k.real().is_finite()
4260        {
4261            x.set_prec(op);
4262            Ok(NumStr::new(Number::from(x, units)))
4263        } else {
4264            Ok(NumStr::new(Number::from(
4265                Complex::with_val(options.prec, Nan),
4266                None,
4267            )))
4268        }
4269    }
4270}
4271pub fn extrema(
4272    mut func: Vec<NumStr>,
4273    mut func_vars: Vec<(String, Vec<NumStr>)>,
4274    mut options: Options,
4275    var: String,
4276    x: Number,
4277) -> Result<NumStr, &'static str> {
4278    //newtons method, x-f'(x)/f''(x)
4279    let units = x.units;
4280    let mut x = x.number;
4281    let op = options.prec;
4282    let prec;
4283    (prec, options.prec) = set_slope_prec(options.prec, 2);
4284    x.set_prec(options.prec);
4285    set_prec(&mut func, &mut func_vars, options.prec);
4286    for _ in 0..(op / 4).max(64) {
4287        let n = Number::from(x.clone(), None);
4288        let y = do_math_with_var(
4289            func.clone(),
4290            options,
4291            func_vars.clone(),
4292            &var.clone(),
4293            NumStr::new(n.clone()),
4294        )?;
4295        let yh = do_math_with_var(
4296            func.clone(),
4297            options,
4298            func_vars.clone(),
4299            &var.clone(),
4300            NumStr::new(Number::from(
4301                x.clone() + Float::with_val(options.prec, 0.5).pow(prec),
4302                None,
4303            )),
4304        )?;
4305        x -= slopesided(
4306            func.clone(),
4307            func_vars.clone(),
4308            options,
4309            var.clone(),
4310            n.clone(),
4311            false,
4312            1,
4313            true,
4314            Some(y.clone()),
4315            Some(yh.clone()),
4316            Some(prec),
4317        )?
4318        .num()?
4319        .number
4320            / slopesided(
4321                func.clone(),
4322                func_vars.clone(),
4323                options,
4324                var.clone(),
4325                n,
4326                false,
4327                2,
4328                true,
4329                Some(y),
4330                Some(yh),
4331                Some(prec),
4332            )?
4333            .num()?
4334            .number
4335    }
4336    let last = x.clone();
4337    let n = Number::from(x.clone(), None);
4338    let y = do_math_with_var(
4339        func.clone(),
4340        options,
4341        func_vars.clone(),
4342        &var.clone(),
4343        NumStr::new(n.clone()),
4344    )?;
4345    let yh = do_math_with_var(
4346        func.clone(),
4347        options,
4348        func_vars.clone(),
4349        &var.clone(),
4350        NumStr::new(Number::from(
4351            x.clone() + Float::with_val(options.prec, 0.5).pow(prec),
4352            None,
4353        )),
4354    )?;
4355    let k = slopesided(
4356        func.clone(),
4357        func_vars.clone(),
4358        options,
4359        var.clone(),
4360        n.clone(),
4361        false,
4362        2,
4363        true,
4364        Some(y.clone()),
4365        Some(yh.clone()),
4366        Some(prec),
4367    )?
4368    .num()?
4369    .number;
4370    x -= slopesided(
4371        func.clone(),
4372        func_vars.clone(),
4373        options,
4374        var.clone(),
4375        n,
4376        false,
4377        1,
4378        true,
4379        Some(y),
4380        Some(yh),
4381        Some(prec),
4382    )?
4383    .num()?
4384    .number
4385        / k.clone();
4386    if (last - x.clone()).abs().real().clone().log2() < op as i32 / -16 && k.real().is_finite() {
4387        let n = Number::from(x, units);
4388        let mut v = Vector(vec![
4389            n.clone(),
4390            do_math_with_var(func, options, func_vars, &var, NumStr::new(n.clone()))?.num()?,
4391            Number::from(
4392                Complex::with_val(
4393                    options.prec,
4394                    if k.clone().abs().real().clone().log2() < op as i32 / -16 {
4395                        0
4396                    } else if k.real().is_sign_positive() {
4397                        1
4398                    } else {
4399                        -1
4400                    },
4401                ),
4402                None,
4403            ),
4404        ]);
4405        v.set_prec(op);
4406        Ok(v)
4407    } else {
4408        Ok(Vector(vec![Number::from(
4409            Complex::with_val(options.prec, Nan),
4410            None,
4411        )]))
4412    }
4413}
4414#[allow(clippy::too_many_arguments)]
4415pub fn taylor(
4416    mut func: Vec<NumStr>,
4417    mut func_vars: Vec<(String, Vec<NumStr>)>,
4418    mut options: Options,
4419    var: String,
4420    x: Option<Number>,
4421    a: Number,
4422    nth: usize,
4423) -> Result<NumStr, &'static str> {
4424    fn fact(n: usize) -> Integer {
4425        let mut fact = Integer::from(1);
4426        for i in 1..=n {
4427            fact *= i
4428        }
4429        fact
4430    }
4431    let op = options.prec;
4432    let mut an = a.number;
4433    let mut prec;
4434    (prec, _) = set_slope_prec(options.prec, nth.min(8) as u32);
4435    (_, options.prec) = set_slope_prec(options.prec, nth as u32);
4436    set_prec(&mut func, &mut func_vars, options.prec);
4437    an.set_prec(options.prec);
4438    let a = Number::from(an.clone(), a.units);
4439    let val = do_math_with_var(
4440        func.clone(),
4441        options,
4442        func_vars.clone(),
4443        &var,
4444        NumStr::new(a.clone()),
4445    )?;
4446    let mut val2 = do_math_with_var(
4447        func.clone(),
4448        options,
4449        func_vars.clone(),
4450        &var,
4451        NumStr::new(Number::from(
4452            an.clone() + Float::with_val(options.prec, 0.5).pow(prec),
4453            None,
4454        )),
4455    )?;
4456    if let Some(x) = x {
4457        let mut x = x.number;
4458        x.set_prec(options.prec);
4459        let mut sum = val.clone();
4460        for n in 1..=nth {
4461            if n % 8 == 0 {
4462                (prec, _) = set_slope_prec(options.prec, nth.min(8 + n) as u32);
4463                val2 = do_math_with_var(
4464                    func.clone(),
4465                    options,
4466                    func_vars.clone(),
4467                    &var,
4468                    NumStr::new(Number::from(
4469                        an.clone() + Float::with_val(options.prec, 0.5).pow(prec),
4470                        None,
4471                    )),
4472                )?;
4473            }
4474            let d = slopesided(
4475                func.clone(),
4476                func_vars.clone(),
4477                options,
4478                var.clone(),
4479                a.clone(),
4480                false,
4481                n as u32,
4482                true,
4483                Some(val.clone()),
4484                Some(val2.clone()),
4485                Some(prec),
4486            )?;
4487            let v = d.func(
4488                &NumStr::new(Number::from(
4489                    fact(n) * (x.clone() - an.clone()).pow(-(n as i32)),
4490                    None,
4491                )),
4492                div,
4493            )?;
4494            sum = sum.func(&v, add)?;
4495        }
4496        sum.set_prec(op);
4497        Ok(sum)
4498    } else {
4499        let mut poly_mat = Vec::with_capacity(nth + 1);
4500        let mut poly = Vec::with_capacity(nth + 1);
4501        let is_vector = match val.clone() {
4502            Vector(a) => {
4503                let empty = vec![Number::from(Complex::new(options.prec), None); a.len()];
4504                poly_mat.push(a);
4505                for _ in 1..=nth {
4506                    poly_mat.push(empty.clone())
4507                }
4508                true
4509            }
4510            Num(a) => {
4511                let empty = Number::from(Complex::new(options.prec), None);
4512                poly.push(*a);
4513                for _ in 1..=nth {
4514                    poly.push(empty.clone())
4515                }
4516                false
4517            }
4518            _ => return Err("unsupported type"),
4519        };
4520        for n in 1..=nth {
4521            if n % 8 == 0 {
4522                (prec, _) = set_slope_prec(options.prec, nth.min(8 + n) as u32);
4523                val2 = do_math_with_var(
4524                    func.clone(),
4525                    options,
4526                    func_vars.clone(),
4527                    &var,
4528                    NumStr::new(Number::from(
4529                        an.clone() + Float::with_val(options.prec, 0.5).pow(prec),
4530                        None,
4531                    )),
4532                )?;
4533            }
4534            let d = slopesided(
4535                func.clone(),
4536                func_vars.clone(),
4537                options,
4538                var.clone(),
4539                a.clone(),
4540                false,
4541                n as u32,
4542                true,
4543                Some(val.clone()),
4544                Some(val2.clone()),
4545                Some(prec),
4546            )?;
4547            if is_vector {
4548                let d = d.vec()?;
4549                for (i, poly) in poly_mat.iter_mut().enumerate() {
4550                    if i > n {
4551                        break;
4552                    }
4553                    for (d, poly) in d.iter().zip(poly.iter_mut()) {
4554                        *poly = add(
4555                            poly,
4556                            &Number::from(
4557                                (-a.clone().number).pow(n - i) * d.number.clone()
4558                                    / (fact(n - i) * fact(i)),
4559                                None,
4560                            ),
4561                        )
4562                    }
4563                }
4564            } else {
4565                let d = d.num()?.number;
4566                for (i, poly) in poly.iter_mut().enumerate() {
4567                    if i > n {
4568                        break;
4569                    }
4570                    *poly = add(
4571                        poly,
4572                        &Number::from(
4573                            (-a.clone().number).pow(n - i) * d.clone() / (fact(n - i) * fact(i)),
4574                            None,
4575                        ),
4576                    )
4577                }
4578            }
4579        }
4580        if is_vector {
4581            poly_mat.reverse();
4582            let mut m = Matrix(transpose(&poly_mat));
4583            m.set_prec(op);
4584            Ok(m)
4585        } else {
4586            poly.reverse();
4587            let mut v = Vector(poly);
4588            v.set_prec(op);
4589            Ok(v)
4590        }
4591    }
4592}
4593fn set_slope_prec(prec: u32, nth: u32) -> (u32, u32) {
4594    let prec = prec.clamp(256, 1024 * nth.max(1));
4595    (prec / (nth + 8), (nth / 8).max(1) * prec / 2)
4596}
4597#[allow(clippy::too_many_arguments)]
4598pub fn slope(
4599    func: Vec<NumStr>,
4600    func_vars: Vec<(String, Vec<NumStr>)>,
4601    mut options: Options,
4602    var: String,
4603    mut point: Number,
4604    combine: bool,
4605    nth: u32,
4606) -> Result<NumStr, &'static str> {
4607    let oop = options.prec;
4608    if nth == 0 {
4609        do_math_with_var(
4610            func.clone(),
4611            options,
4612            func_vars.clone(),
4613            &var,
4614            NumStr::new(point),
4615        )
4616    } else if options.prec <= 256 {
4617        options.prec = 256;
4618        point.number.set_prec(options.prec);
4619        let mut n = slopesided(
4620            func, func_vars, options, var, point, combine, nth, true, None, None, None,
4621        )?;
4622        n.set_prec(oop);
4623        Ok(n)
4624    } else {
4625        let op = options.prec.clamp(256, 1024);
4626        let prec;
4627        (prec, options.prec) = set_slope_prec(options.prec, nth);
4628        point.number.set_prec(options.prec);
4629        let val = do_math_with_var(
4630            func.clone(),
4631            options,
4632            func_vars.clone(),
4633            &var,
4634            NumStr::new(point.clone()),
4635        )?;
4636        let left = slopesided(
4637            func.clone(),
4638            func_vars.clone(),
4639            options,
4640            var.clone(),
4641            point.clone(),
4642            combine,
4643            nth,
4644            false,
4645            Some(val.clone()),
4646            None,
4647            Some(prec),
4648        )?;
4649        let right = slopesided(
4650            func,
4651            func_vars,
4652            options,
4653            var,
4654            point,
4655            combine,
4656            nth,
4657            true,
4658            Some(val),
4659            None,
4660            Some(prec),
4661        )?;
4662        match (left, right) {
4663            (Num(left), Num(right)) => {
4664                let units = left.units;
4665                let left = left.number;
4666                let right = right.number;
4667                if (((left.real().is_infinite()
4668                    && right.real().is_infinite()
4669                    && (left.imag().clone() - right.imag().clone())
4670                        .abs()
4671                        .clone()
4672                        .log2()
4673                        < op as i32 / -16)
4674                    || (left.imag().is_infinite()
4675                        && right.imag().is_infinite()
4676                        && (left.real().clone() - right.real().clone())
4677                            .abs()
4678                            .clone()
4679                            .log2()
4680                            < op as i32 / -16))
4681                    && left.real().is_sign_positive() == right.real().is_sign_positive()
4682                    && left.imag().is_sign_positive() == right.imag().is_sign_positive())
4683                    || (left.clone() - right.clone()).abs().real().clone().log2() < op as i32 / -16
4684                {
4685                    let mut n = NumStr::new(Number::from((left + right) / 2, units));
4686                    n.set_prec(oop);
4687                    Ok(n)
4688                } else {
4689                    Ok(NumStr::new(Number::from(
4690                        Complex::with_val(options.prec, Nan),
4691                        None,
4692                    )))
4693                }
4694            }
4695            (Vector(left), Vector(right)) => {
4696                let mut vec = Vec::with_capacity(left.len().max(1));
4697                for (left, right) in left.iter().zip(right) {
4698                    vec.push({
4699                        let units = left.units;
4700                        let left = left.number.clone();
4701                        let right = right.number.clone();
4702                        if (((left.real().is_infinite()
4703                            && right.real().is_infinite()
4704                            && (left.imag().clone() - right.imag().clone())
4705                                .abs()
4706                                .clone()
4707                                .log2()
4708                                < op as i32 / -16)
4709                            || (left.imag().is_infinite()
4710                                && right.imag().is_infinite()
4711                                && (left.real().clone() - right.real().clone())
4712                                    .abs()
4713                                    .clone()
4714                                    .log2()
4715                                    < op as i32 / -16))
4716                            && left.real().is_sign_positive() == right.real().is_sign_positive()
4717                            && left.imag().is_sign_positive() == right.imag().is_sign_positive())
4718                            || (left.clone() - right.clone()).abs().real().clone().log2()
4719                                < op as i32 / -16
4720                        {
4721                            Number::from((left + right) / 2, units)
4722                        } else {
4723                            Number::from(Complex::with_val(options.prec, Nan), None)
4724                        }
4725                    })
4726                }
4727                let mut v = Vector(vec);
4728                v.set_prec(oop);
4729                Ok(v)
4730            }
4731            (_, _) => Err("lim err"),
4732        }
4733    }
4734}
4735
4736#[allow(clippy::too_many_arguments)]
4737pub fn slopesided(
4738    func: Vec<NumStr>,
4739    func_vars: Vec<(String, Vec<NumStr>)>,
4740    mut options: Options,
4741    var: String,
4742    point: Number,
4743    combine: bool,
4744    nth: u32,
4745    right: bool,
4746    val: Option<NumStr>,
4747    val2: Option<NumStr>,
4748    prec: Option<u32>,
4749) -> Result<NumStr, &'static str> {
4750    if nth == 0 {
4751        return do_math_with_var(
4752            func.clone(),
4753            options,
4754            func_vars.clone(),
4755            &var,
4756            NumStr::new(point),
4757        );
4758    }
4759    let mut oop = 0;
4760    let units = point.units;
4761    let mut point = point.number;
4762    let prec = if let Some(prec) = prec {
4763        prec
4764    } else {
4765        oop = options.prec;
4766        options.prec = options.prec.clamp(256, 1024 * nth.max(1));
4767        let prec;
4768        (prec, options.prec) = set_slope_prec(options.prec, nth);
4769        point.set_prec(options.prec);
4770        prec
4771    };
4772    let h: Float = if right {
4773        Float::with_val(options.prec, 0.5).pow(prec)
4774    } else {
4775        -Float::with_val(options.prec, 0.5).pow(prec)
4776    };
4777    let num = Integer::from(nth);
4778    let n = if let Some(n) = val {
4779        n
4780    } else {
4781        do_math_with_var(
4782            func.clone(),
4783            options,
4784            func_vars.clone(),
4785            &var,
4786            NumStr::new(Number::from(point.clone(), units)),
4787        )?
4788    };
4789    match n {
4790        Num(sum) => {
4791            let yunits = sum.units;
4792            let mut sum = sum.number;
4793            if nth % 2 == 1 {
4794                sum *= -1;
4795            }
4796            let bo = val2.is_some();
4797            for k in 0..nth {
4798                if bo && nth - k == 1 {
4799                    if k % 2 == 0 {
4800                        sum += num.clone().binomial(k) * val2.clone().unwrap().num()?.number
4801                    } else {
4802                        sum -= num.clone().binomial(k) * val2.clone().unwrap().num()?.number
4803                    }
4804                } else if k % 2 == 0 {
4805                    sum += num.clone().binomial(k)
4806                        * do_math_with_var(
4807                            func.clone(),
4808                            options,
4809                            func_vars.clone(),
4810                            &var,
4811                            NumStr::new(Number::from(point.clone() + h.clone() * (nth - k), units)),
4812                        )?
4813                        .num()?
4814                        .number;
4815                } else {
4816                    sum -= num.clone().binomial(k)
4817                        * do_math_with_var(
4818                            func.clone(),
4819                            options,
4820                            func_vars.clone(),
4821                            &var,
4822                            NumStr::new(Number::from(point.clone() + h.clone() * (nth - k), units)),
4823                        )?
4824                        .num()?
4825                        .number;
4826                }
4827            }
4828            if right || nth % 2 == 0 {
4829                let mut n = NumStr::new(Number::from(
4830                    sum * Float::with_val(options.prec, 2).pow(nth * prec),
4831                    match (yunits, units) {
4832                        (Some(a), Some(b)) => Some(a.div(&b)),
4833                        (Some(a), None) => Some(a),
4834                        (None, Some(b)) => Some(Units::default().div(&b)),
4835                        (None, None) => None,
4836                    },
4837                ));
4838                if oop != 0 {
4839                    n.set_prec(oop);
4840                }
4841                Ok(n)
4842            } else {
4843                let mut n = NumStr::new(Number::from(
4844                    -sum * Float::with_val(options.prec, 2).pow(nth * prec),
4845                    match (yunits, units) {
4846                        (Some(a), Some(b)) => Some(a.div(&b)),
4847                        (Some(a), None) => Some(a),
4848                        (None, Some(b)) => Some(Units::default().div(&b)),
4849                        (None, None) => None,
4850                    },
4851                ));
4852                if oop != 0 {
4853                    n.set_prec(oop);
4854                }
4855                Ok(n)
4856            }
4857        }
4858        Vector(mut sum) if !combine => {
4859            let yunits = sum[0].units;
4860            if nth % 2 == 1 {
4861                for n in sum.iter_mut() {
4862                    n.number *= -1;
4863                }
4864            }
4865            for k in 0..nth {
4866                let b = num.clone().binomial(k);
4867                let vec = do_math_with_var(
4868                    func.clone(),
4869                    options,
4870                    func_vars.clone(),
4871                    &var,
4872                    NumStr::new(Number::from(point.clone() + h.clone() * (nth - k), units)),
4873                )?
4874                .vec()?;
4875                if k % 2 == 0 {
4876                    for (n, a) in sum.iter_mut().zip(vec) {
4877                        n.number += a.number * b.clone()
4878                    }
4879                } else {
4880                    for (n, a) in sum.iter_mut().zip(vec) {
4881                        n.number -= a.number * b.clone()
4882                    }
4883                }
4884            }
4885            let mut v = Vector(
4886                sum.iter()
4887                    .map(|n| {
4888                        Number::from(
4889                            if right || nth % 2 == 0 {
4890                                n.number.clone() * Float::with_val(options.prec, 2).pow(nth * prec)
4891                            } else {
4892                                -n.number.clone() * Float::with_val(options.prec, 2).pow(nth * prec)
4893                            },
4894                            match (yunits, units) {
4895                                (Some(a), Some(b)) => Some(a.div(&b)),
4896                                (Some(a), None) => Some(a),
4897                                (None, Some(b)) => Some(Units::default().div(&b)),
4898                                (None, None) => None,
4899                            },
4900                        )
4901                    })
4902                    .collect::<Vec<Number>>(),
4903            );
4904            if oop != 0 {
4905                v.set_prec(oop);
4906            }
4907            Ok(v)
4908        }
4909        Vector(mut sum) if sum.len() == 1 => {
4910            let yunits = sum[0].units;
4911            if nth % 2 == 1 {
4912                sum[0].number *= -1;
4913            }
4914            for k in 0..nth {
4915                if k % 2 == 0 {
4916                    sum[0].number += num.clone().binomial(k)
4917                        * do_math_with_var(
4918                            func.clone(),
4919                            options,
4920                            func_vars.clone(),
4921                            &var,
4922                            NumStr::new(Number::from(point.clone() + h.clone() * (nth - k), units)),
4923                        )?
4924                        .num()?
4925                        .number;
4926                } else {
4927                    sum[0].number -= num.clone().binomial(k)
4928                        * do_math_with_var(
4929                            func.clone(),
4930                            options,
4931                            func_vars.clone(),
4932                            &var,
4933                            NumStr::new(Number::from(point.clone() + h.clone() * (nth - k), units)),
4934                        )?
4935                        .num()?
4936                        .number;
4937                }
4938            }
4939            if right || nth % 2 == 0 {
4940                let mut n = NumStr::new(Number::from(
4941                    sum[0].number.clone() * Float::with_val(options.prec, 2).pow(nth * prec),
4942                    match (yunits, units) {
4943                        (Some(a), Some(b)) => Some(a.div(&b)),
4944                        (Some(a), None) => Some(a),
4945                        (None, Some(b)) => Some(Units::default().div(&b)),
4946                        (None, None) => None,
4947                    },
4948                ));
4949                if oop != 0 {
4950                    n.set_prec(oop)
4951                }
4952                Ok(n)
4953            } else {
4954                let mut n = NumStr::new(Number::from(
4955                    -sum[0].number.clone() * Float::with_val(options.prec, 2).pow(nth * prec),
4956                    match (yunits, units) {
4957                        (Some(a), Some(b)) => Some(a.div(&b)),
4958                        (Some(a), None) => Some(a),
4959                        (None, Some(b)) => Some(Units::default().div(&b)),
4960                        (None, None) => None,
4961                    },
4962                ));
4963                if oop != 0 {
4964                    n.set_prec(oop)
4965                }
4966                Ok(n)
4967            }
4968        }
4969        Vector(mut sum) => {
4970            let yunits = sum[0].units;
4971            if nth % 2 == 1 {
4972                for n in sum.iter_mut() {
4973                    n.number *= -1;
4974                }
4975            }
4976            for k in 0..nth {
4977                let b = num.clone().binomial(k);
4978                let vec = do_math_with_var(
4979                    func.clone(),
4980                    options,
4981                    func_vars.clone(),
4982                    &var,
4983                    NumStr::new(Number::from(point.clone() + h.clone() * (nth - k), units)),
4984                )?
4985                .vec()?;
4986                if k % 2 == 0 {
4987                    for (n, a) in sum.iter_mut().zip(vec) {
4988                        n.number += a.number * b.clone()
4989                    }
4990                } else {
4991                    for (n, a) in sum.iter_mut().zip(vec) {
4992                        n.number -= a.number * b.clone()
4993                    }
4994                }
4995            }
4996            if sum.len() == 2 {
4997                let mut n = NumStr::new(Number::from(
4998                    sum[1].number.clone() / sum[0].number.clone(),
4999                    match (yunits, units) {
5000                        (Some(a), Some(b)) => Some(a.div(&b)),
5001                        (Some(a), None) => Some(a),
5002                        (None, Some(b)) => Some(Units::default().div(&b)),
5003                        (None, None) => None,
5004                    },
5005                ));
5006                if oop != 0 {
5007                    n.set_prec(oop)
5008                }
5009                Ok(n)
5010            } else {
5011                let nf = &sum.last().unwrap().number;
5012                let mut v = Vector(
5013                    sum[0..sum.len().saturating_sub(1)]
5014                        .iter()
5015                        .map(|n| {
5016                            Number::from(
5017                                nf.clone() / n.number.clone(),
5018                                match (yunits, units) {
5019                                    (Some(a), Some(b)) => Some(a.div(&b)),
5020                                    (Some(a), None) => Some(a),
5021                                    (None, Some(b)) => Some(Units::default().div(&b)),
5022                                    (None, None) => None,
5023                                },
5024                            )
5025                        })
5026                        .collect::<Vec<Number>>(),
5027                );
5028                if oop != 0 {
5029                    v.set_prec(oop)
5030                }
5031                Ok(v)
5032            }
5033        }
5034        _ => Err("not supported slope data"),
5035    }
5036}
5037#[derive(Copy, Clone, PartialEq)]
5038pub enum LimSide {
5039    Left,
5040    Right,
5041    Both,
5042}
5043pub fn limit(
5044    mut func: Vec<NumStr>,
5045    mut func_vars: Vec<(String, Vec<NumStr>)>,
5046    mut options: Options,
5047    var: String,
5048    point: Number,
5049    side: LimSide,
5050) -> Result<NumStr, &'static str> {
5051    let xunits = point.units;
5052    let mut point = point.number;
5053    let oop = options.prec;
5054    options.prec = options.prec.clamp(256, 1024);
5055    if oop != options.prec {
5056        point.set_prec(options.prec);
5057        set_prec(&mut func, &mut func_vars, options.prec);
5058    }
5059    if point.clone().real().is_infinite() || point.clone().imag().is_infinite() {
5060        let (h1, h2);
5061        let positive = point.real().is_sign_positive();
5062        if positive {
5063            h1 = Complex::with_val(options.prec, 2).pow(options.prec / 4);
5064            h2 = Complex::with_val(options.prec, 2).pow((options.prec / 3) as f64 + 7.0 / 0.94) - 3;
5065        } else {
5066            h1 = -Complex::with_val(options.prec, 2).pow(options.prec / 4);
5067            h2 = 3 - Complex::with_val(options.prec, 2).pow((options.prec / 3) as f64 + 7.0 / 0.94);
5068        }
5069        let n1 = do_math_with_var(
5070            func.clone(),
5071            options,
5072            func_vars.clone(),
5073            &var,
5074            NumStr::new(Number::from(h1, xunits)),
5075        )?;
5076        let n2 = do_math_with_var(
5077            func.clone(),
5078            options,
5079            func_vars.clone(),
5080            &var,
5081            NumStr::new(Number::from(h2, xunits)),
5082        )?;
5083        match (n1, n2) {
5084            (Num(n1), Num(n2)) => {
5085                let units = n1.units;
5086                let n1 = n1.number;
5087                let n2 = n2.number;
5088                let mut n = if (n1.clone() - n2.clone()).abs().real().clone().log2()
5089                    < options.prec as i32 / -16
5090                {
5091                    NumStr::new(Number::from(n2, units))
5092                } else if n1.real().is_sign_positive() != n2.real().is_sign_positive()
5093                    || n1.imag().is_sign_positive() != n2.imag().is_sign_positive()
5094                {
5095                    NumStr::new(Number::from(Complex::with_val(options.prec, Nan), None))
5096                } else if n2.real().is_infinite() || n2.imag().is_infinite() {
5097                    NumStr::new(Number::from(
5098                        match (n2.real().is_infinite(), n2.imag().is_infinite()) {
5099                            (true, true) => {
5100                                match (n1.real().is_sign_positive(), n1.imag().is_sign_positive()) {
5101                                    (true, true) => {
5102                                        Complex::with_val(options.prec, (Infinity, Infinity))
5103                                    }
5104                                    (true, false) => Complex::with_val(
5105                                        options.prec,
5106                                        (Infinity, -Float::with_val(options.prec, Infinity)),
5107                                    ),
5108                                    (false, true) => Complex::with_val(
5109                                        options.prec,
5110                                        (-Float::with_val(options.prec, Infinity), Infinity),
5111                                    ),
5112                                    (false, false) => {
5113                                        -Complex::with_val(options.prec, (Infinity, Infinity))
5114                                    }
5115                                }
5116                            }
5117                            (true, false) => {
5118                                if n1.real().is_sign_positive() {
5119                                    Complex::with_val(
5120                                        options.prec,
5121                                        (
5122                                            Infinity,
5123                                            if (n1.imag() - n2.imag().clone()).abs().log2()
5124                                                < options.prec as i32 / -16
5125                                            {
5126                                                n2.imag().clone()
5127                                            } else {
5128                                                Float::new(options.prec)
5129                                            },
5130                                        ),
5131                                    )
5132                                } else {
5133                                    -Complex::with_val(
5134                                        options.prec,
5135                                        (
5136                                            Infinity,
5137                                            if (n1.imag() - n2.imag().clone()).abs().log2()
5138                                                < options.prec as i32 / -16
5139                                            {
5140                                                -n2.imag().clone()
5141                                            } else {
5142                                                Float::new(options.prec)
5143                                            },
5144                                        ),
5145                                    )
5146                                }
5147                            }
5148                            (false, true) => {
5149                                if n1.imag().is_sign_positive() {
5150                                    Complex::with_val(
5151                                        options.prec,
5152                                        (
5153                                            if (n1.real() - n2.real().clone()).abs().log2()
5154                                                < options.prec as i32 / -16
5155                                            {
5156                                                n2.real().clone()
5157                                            } else {
5158                                                Float::new(options.prec)
5159                                            },
5160                                            Infinity,
5161                                        ),
5162                                    )
5163                                } else {
5164                                    -Complex::with_val(
5165                                        options.prec,
5166                                        (
5167                                            if (n1.real() - n2.real().clone()).abs().log2()
5168                                                < options.prec as i32 / -16
5169                                            {
5170                                                -n2.real().clone()
5171                                            } else {
5172                                                Float::new(options.prec)
5173                                            },
5174                                            Infinity,
5175                                        ),
5176                                    )
5177                                }
5178                            }
5179                            (false, false) => Complex::with_val(options.prec, Nan),
5180                        },
5181                        units,
5182                    ))
5183                } else {
5184                    let n3 = do_math_with_var(
5185                        func.clone(),
5186                        options,
5187                        func_vars.clone(),
5188                        &var,
5189                        NumStr::new(Number::from(
5190                            if positive {
5191                                Complex::with_val(options.prec, 2)
5192                                    .pow((options.prec / 2) as f64 + 13.0 / 0.7)
5193                                    - 7
5194                            } else {
5195                                7 - Complex::with_val(options.prec, 2)
5196                                    .pow((options.prec / 2) as f64 + 13.0 / 0.7)
5197                            },
5198                            xunits,
5199                        )),
5200                    )?
5201                    .num()?
5202                    .number;
5203                    let sign = n2.real().is_sign_positive() == n3.real().is_sign_positive()
5204                        && n2.imag().is_sign_positive() == n3.imag().is_sign_positive();
5205                    let n1r = n1.real().clone().abs();
5206                    let n2r = n2.real().clone().abs();
5207                    let n3r = n3.real().clone().abs();
5208                    let n1i = n1.imag().clone().abs();
5209                    let n2i = n2.imag().clone().abs();
5210                    let n3i = n3.imag().clone().abs();
5211                    NumStr::new(Number::from(
5212                        if !sign {
5213                            Complex::with_val(options.prec, Nan)
5214                        } else {
5215                            match (n3r > n2r && n2r > n1r, n3i > n2i && n2i > n1i) {
5216                                (true, true) => {
5217                                    match (
5218                                        n1.real().is_sign_positive(),
5219                                        n1.imag().is_sign_positive(),
5220                                    ) {
5221                                        (true, true) => {
5222                                            Complex::with_val(options.prec, (Infinity, Infinity))
5223                                        }
5224                                        (true, false) => Complex::with_val(
5225                                            options.prec,
5226                                            (Infinity, -Float::with_val(options.prec, Infinity)),
5227                                        ),
5228                                        (false, true) => Complex::with_val(
5229                                            options.prec,
5230                                            (-Float::with_val(options.prec, Infinity), Infinity),
5231                                        ),
5232                                        (false, false) => {
5233                                            -Complex::with_val(options.prec, (Infinity, Infinity))
5234                                        }
5235                                    }
5236                                }
5237                                (true, false) => {
5238                                    if n1.real().is_sign_positive() {
5239                                        Complex::with_val(
5240                                            options.prec,
5241                                            (
5242                                                Infinity,
5243                                                if (n2i - n3i.clone()).abs().log2()
5244                                                    < options.prec as i32 / -16
5245                                                {
5246                                                    n3i
5247                                                } else {
5248                                                    Float::new(options.prec)
5249                                                },
5250                                            ),
5251                                        )
5252                                    } else {
5253                                        -Complex::with_val(
5254                                            options.prec,
5255                                            (
5256                                                Infinity,
5257                                                if (n2i - n3i.clone()).abs().log2()
5258                                                    < options.prec as i32 / -16
5259                                                {
5260                                                    -n3i
5261                                                } else {
5262                                                    Float::new(options.prec)
5263                                                },
5264                                            ),
5265                                        )
5266                                    }
5267                                }
5268                                (false, true) => {
5269                                    if n1.imag().is_sign_positive() {
5270                                        Complex::with_val(
5271                                            options.prec,
5272                                            (
5273                                                if (n2r - n3r.clone()).abs().log2()
5274                                                    < options.prec as i32 / -16
5275                                                {
5276                                                    n3r
5277                                                } else {
5278                                                    Float::new(options.prec)
5279                                                },
5280                                                Infinity,
5281                                            ),
5282                                        )
5283                                    } else {
5284                                        -Complex::with_val(
5285                                            options.prec,
5286                                            (
5287                                                if (n2r - n3r.clone()).abs().log2()
5288                                                    < options.prec as i32 / -16
5289                                                {
5290                                                    -n3r
5291                                                } else {
5292                                                    Float::new(options.prec)
5293                                                },
5294                                                Infinity,
5295                                            ),
5296                                        )
5297                                    }
5298                                }
5299                                (false, false) => Complex::with_val(options.prec, Nan),
5300                            }
5301                        },
5302                        units,
5303                    ))
5304                };
5305                n.set_prec(oop);
5306                Ok(n)
5307            }
5308            (Vector(v1), Vector(v2)) => {
5309                let mut v3: Vec<Number> = Vec::new();
5310                let mut vec = Vec::with_capacity(v1.len().max(1));
5311                for (i, (n1, n2)) in v1.iter().zip(v2).enumerate() {
5312                    let units = n1.units;
5313                    let n1 = n1.number.clone();
5314                    let n2 = n2.number.clone();
5315                    vec.push(Number::from(
5316                        if (n1.clone() - n2.clone()).abs().real().clone().log2()
5317                            < options.prec as i32 / -16
5318                        {
5319                            n2
5320                        } else if n1.real().is_sign_positive() != n2.real().is_sign_positive()
5321                            || n1.imag().is_sign_positive() != n2.imag().is_sign_positive()
5322                        {
5323                            Complex::with_val(options.prec, Nan)
5324                        } else if n2.real().is_infinite() || n2.imag().is_infinite() {
5325                            match (n2.real().is_infinite(), n2.imag().is_infinite()) {
5326                                (true, true) => {
5327                                    match (
5328                                        n1.real().is_sign_positive(),
5329                                        n1.imag().is_sign_positive(),
5330                                    ) {
5331                                        (true, true) => {
5332                                            Complex::with_val(options.prec, (Infinity, Infinity))
5333                                        }
5334                                        (true, false) => Complex::with_val(
5335                                            options.prec,
5336                                            (Infinity, -Float::with_val(options.prec, Infinity)),
5337                                        ),
5338                                        (false, true) => Complex::with_val(
5339                                            options.prec,
5340                                            (-Float::with_val(options.prec, Infinity), Infinity),
5341                                        ),
5342                                        (false, false) => {
5343                                            -Complex::with_val(options.prec, (Infinity, Infinity))
5344                                        }
5345                                    }
5346                                }
5347                                (true, false) => {
5348                                    if n1.real().is_sign_positive() {
5349                                        Complex::with_val(
5350                                            options.prec,
5351                                            (
5352                                                Infinity,
5353                                                if (n1.imag() - n2.imag().clone()).abs().log10()
5354                                                    <= -10
5355                                                {
5356                                                    n2.imag().clone()
5357                                                } else {
5358                                                    Float::new(options.prec)
5359                                                },
5360                                            ),
5361                                        )
5362                                    } else {
5363                                        -Complex::with_val(
5364                                            options.prec,
5365                                            (
5366                                                Infinity,
5367                                                if (n1.imag() - n2.imag().clone()).abs().log10()
5368                                                    <= -10
5369                                                {
5370                                                    -n2.imag().clone()
5371                                                } else {
5372                                                    Float::new(options.prec)
5373                                                },
5374                                            ),
5375                                        )
5376                                    }
5377                                }
5378                                (false, true) => {
5379                                    if n1.imag().is_sign_positive() {
5380                                        Complex::with_val(
5381                                            options.prec,
5382                                            (
5383                                                if (n1.real() - n2.real().clone()).abs().log10()
5384                                                    <= -10
5385                                                {
5386                                                    n2.real().clone()
5387                                                } else {
5388                                                    Float::new(options.prec)
5389                                                },
5390                                                Infinity,
5391                                            ),
5392                                        )
5393                                    } else {
5394                                        -Complex::with_val(
5395                                            options.prec,
5396                                            (
5397                                                if (n1.real() - n2.real().clone()).abs().log10()
5398                                                    <= -10
5399                                                {
5400                                                    -n2.real().clone()
5401                                                } else {
5402                                                    Float::new(options.prec)
5403                                                },
5404                                                Infinity,
5405                                            ),
5406                                        )
5407                                    }
5408                                }
5409                                (false, false) => Complex::with_val(options.prec, Nan),
5410                            }
5411                        } else {
5412                            if v3.is_empty() {
5413                                v3 = do_math_with_var(
5414                                    func.clone(),
5415                                    options,
5416                                    func_vars.clone(),
5417                                    &var,
5418                                    NumStr::new(Number::from(
5419                                        if positive {
5420                                            Complex::with_val(options.prec, 2)
5421                                                .pow((options.prec / 2) as f64 + 13.0 / 0.7)
5422                                                - 7
5423                                        } else {
5424                                            7 - Complex::with_val(options.prec, 2)
5425                                                .pow((options.prec / 2) as f64 + 13.0 / 0.7)
5426                                        },
5427                                        xunits,
5428                                    )),
5429                                )?
5430                                .vec()?;
5431                            }
5432                            let v3 = &v3[i].number;
5433                            let sign = n2.real().is_sign_positive() == v3.real().is_sign_positive()
5434                                && n2.imag().is_sign_positive() == v3.imag().is_sign_positive();
5435                            let n1r = n1.real().clone().abs();
5436                            let n2r = n2.real().clone().abs();
5437                            let n3r = v3.real().clone().abs();
5438                            let n1i = n1.imag().clone().abs();
5439                            let n2i = n2.imag().clone().abs();
5440                            let n3i = v3.imag().clone().abs();
5441                            if !sign {
5442                                Complex::with_val(options.prec, Nan)
5443                            } else {
5444                                match (n3r > n2r && n2r > n1r, n3i > n2i && n2i > n1i) {
5445                                    (true, true) => {
5446                                        match (
5447                                            n1.real().is_sign_positive(),
5448                                            n1.imag().is_sign_positive(),
5449                                        ) {
5450                                            (true, true) => Complex::with_val(
5451                                                options.prec,
5452                                                (Infinity, Infinity),
5453                                            ),
5454                                            (true, false) => Complex::with_val(
5455                                                options.prec,
5456                                                (
5457                                                    Infinity,
5458                                                    -Float::with_val(options.prec, Infinity),
5459                                                ),
5460                                            ),
5461                                            (false, true) => Complex::with_val(
5462                                                options.prec,
5463                                                (
5464                                                    -Float::with_val(options.prec, Infinity),
5465                                                    Infinity,
5466                                                ),
5467                                            ),
5468                                            (false, false) => -Complex::with_val(
5469                                                options.prec,
5470                                                (Infinity, Infinity),
5471                                            ),
5472                                        }
5473                                    }
5474                                    (true, false) => {
5475                                        if n1.real().is_sign_positive() {
5476                                            Complex::with_val(
5477                                                options.prec,
5478                                                (
5479                                                    Infinity,
5480                                                    if (n2i - n3i.clone()).abs().log2()
5481                                                        < options.prec as i32 / -16
5482                                                    {
5483                                                        n3i
5484                                                    } else {
5485                                                        Float::new(options.prec)
5486                                                    },
5487                                                ),
5488                                            )
5489                                        } else {
5490                                            -Complex::with_val(
5491                                                options.prec,
5492                                                (
5493                                                    Infinity,
5494                                                    if (n2i - n3i.clone()).abs().log2()
5495                                                        < options.prec as i32 / -16
5496                                                    {
5497                                                        -n3i
5498                                                    } else {
5499                                                        Float::new(options.prec)
5500                                                    },
5501                                                ),
5502                                            )
5503                                        }
5504                                    }
5505                                    (false, true) => {
5506                                        if n1.imag().is_sign_positive() {
5507                                            Complex::with_val(
5508                                                options.prec,
5509                                                (
5510                                                    if (n2r - n3r.clone()).abs().log2()
5511                                                        < options.prec as i32 / -16
5512                                                    {
5513                                                        n3r
5514                                                    } else {
5515                                                        Float::new(options.prec)
5516                                                    },
5517                                                    Infinity,
5518                                                ),
5519                                            )
5520                                        } else {
5521                                            -Complex::with_val(
5522                                                options.prec,
5523                                                (
5524                                                    if (n2r - n3r.clone()).abs().log2()
5525                                                        < options.prec as i32 / -16
5526                                                    {
5527                                                        -n3r
5528                                                    } else {
5529                                                        Float::new(options.prec)
5530                                                    },
5531                                                    Infinity,
5532                                                ),
5533                                            )
5534                                        }
5535                                    }
5536                                    (false, false) => Complex::with_val(options.prec, Nan),
5537                                }
5538                            }
5539                        },
5540                        units,
5541                    ))
5542                }
5543                let mut v = Vector(vec);
5544                v.set_prec(oop);
5545                Ok(v)
5546            }
5547            (_, _) => Err("unsupported lim data"),
5548        }
5549    } else {
5550        let point = Number::from(point, xunits);
5551        match side {
5552            LimSide::Left => limsided(func, func_vars, options, var, point, false),
5553            LimSide::Right => limsided(func, func_vars, options, var, point, true),
5554            LimSide::Both => {
5555                let left = limsided(
5556                    func.clone(),
5557                    func_vars.clone(),
5558                    options,
5559                    var.clone(),
5560                    point.clone(),
5561                    false,
5562                )?;
5563                let right = limsided(func, func_vars, options, var, point, true)?;
5564                match (left, right) {
5565                    (Num(left), Num(right)) => {
5566                        let units = left.units;
5567                        let left = left.number;
5568                        let right = right.number;
5569                        if (((left.real().is_infinite()
5570                            && right.real().is_infinite()
5571                            && (left.imag().clone() - right.imag().clone())
5572                                .abs()
5573                                .clone()
5574                                .log2()
5575                                < options.prec as i32 / -16)
5576                            || (left.imag().is_infinite()
5577                                && right.imag().is_infinite()
5578                                && (left.real().clone() - right.real().clone())
5579                                    .abs()
5580                                    .clone()
5581                                    .log2()
5582                                    < options.prec as i32 / -16))
5583                            && left.real().is_sign_positive() == right.real().is_sign_positive()
5584                            && left.imag().is_sign_positive() == right.imag().is_sign_positive())
5585                            || (left.clone() - right.clone()).abs().real().clone().log2()
5586                                < options.prec as i32 / -16
5587                        {
5588                            let mut n = NumStr::new(Number::from((left + right) / 2, units));
5589                            n.set_prec(oop);
5590                            Ok(n)
5591                        } else {
5592                            Ok(NumStr::new(Number::from(
5593                                Complex::with_val(options.prec, Nan),
5594                                None,
5595                            )))
5596                        }
5597                    }
5598                    (Vector(left), Vector(right)) => {
5599                        let mut vec = Vec::with_capacity(left.len().max(1));
5600                        for (left, right) in left.iter().zip(right) {
5601                            let units = left.units;
5602                            let left = &left.number;
5603                            let right = &right.number;
5604                            vec.push(
5605                                if (((left.real().is_infinite()
5606                                    && right.real().is_infinite()
5607                                    && (left.imag().clone() - right.imag().clone())
5608                                        .abs()
5609                                        .clone()
5610                                        .log2()
5611                                        < options.prec as i32 / -16)
5612                                    || (left.imag().is_infinite()
5613                                        && right.imag().is_infinite()
5614                                        && (left.real().clone() - right.real().clone())
5615                                            .abs()
5616                                            .clone()
5617                                            .log2()
5618                                            < options.prec as i32 / -16))
5619                                    && left.real().is_sign_positive()
5620                                        == right.real().is_sign_positive()
5621                                    && left.imag().is_sign_positive()
5622                                        == right.imag().is_sign_positive())
5623                                    || (left.clone() - right.clone()).abs().real().clone().log2()
5624                                        < options.prec as i32 / -16
5625                                {
5626                                    Number::from((left + right.clone()) / 2, units)
5627                                } else {
5628                                    Number::from(Complex::with_val(options.prec, Nan), None)
5629                                },
5630                            )
5631                        }
5632                        let mut v = Vector(vec);
5633                        v.set_prec(options.prec);
5634                        Ok(v)
5635                    }
5636                    (_, _) => Err("lim err"),
5637                }
5638            }
5639        }
5640    }
5641}
5642fn limsided(
5643    func: Vec<NumStr>,
5644    func_vars: Vec<(String, Vec<NumStr>)>,
5645    options: Options,
5646    var: String,
5647    point: Number,
5648    right: bool,
5649) -> Result<NumStr, &'static str> {
5650    let xunits = point.units;
5651    let point = point.number;
5652    let h1 = Float::with_val(options.prec, 0.5).pow(options.prec / 4);
5653    let h2 = Float::with_val(options.prec, 0.5).pow((options.prec / 3) as f64 + 7.0 / 0.94);
5654    let n1 = do_math_with_var(
5655        func.clone(),
5656        options,
5657        func_vars.clone(),
5658        &var,
5659        NumStr::new(Number::from(
5660            point.clone() + if right { h1 } else { -h1 },
5661            xunits,
5662        )),
5663    )?;
5664    let n2 = do_math_with_var(
5665        func.clone(),
5666        options,
5667        func_vars.clone(),
5668        &var,
5669        NumStr::new(Number::from(
5670            point.clone() + if right { h2 } else { -h2 },
5671            xunits,
5672        )),
5673    )?;
5674    match (n1, n2) {
5675        (Num(n1), Num(n2)) => {
5676            let units = n1.units;
5677            let n1 = n1.number;
5678            let n2 = n2.number;
5679            Ok(NumStr::new(Number::from(
5680                if (n2.clone() - n1.clone()).abs().real().clone().log2() < options.prec as i32 / -16
5681                {
5682                    n1
5683                } else {
5684                    let h3 = Complex::with_val(options.prec, 0.5)
5685                        .pow((options.prec / 2) as f64 + 13.0 / 0.7);
5686                    let n3 = do_math_with_var(
5687                        func.clone(),
5688                        options,
5689                        func_vars.clone(),
5690                        &var,
5691                        NumStr::new(Number::from(
5692                            point.clone() + if right { h3 } else { -h3 },
5693                            xunits,
5694                        )),
5695                    )?
5696                    .num()?
5697                    .number;
5698                    let sign = n1.real().is_sign_positive() == n2.real().is_sign_positive()
5699                        && n2.real().is_sign_positive() == n3.real().is_sign_positive()
5700                        && n1.imag().is_sign_positive() == n2.imag().is_sign_positive()
5701                        && n2.imag().is_sign_positive() == n3.imag().is_sign_positive();
5702                    let n1r = n1.real().clone().abs();
5703                    let n2r = n2.real().clone().abs();
5704                    let n3r = n3.real().clone().abs();
5705                    let n1i = n1.imag().clone().abs();
5706                    let n2i = n2.imag().clone().abs();
5707                    let n3i = n3.imag().clone().abs();
5708                    if !sign {
5709                        Complex::with_val(options.prec, Nan)
5710                    } else {
5711                        match (n3r > n2r && n2r > n1r, n3i > n2i && n2i > n1i) {
5712                            (true, true) => {
5713                                match (n1.real().is_sign_positive(), n1.imag().is_sign_positive()) {
5714                                    (true, true) => {
5715                                        Complex::with_val(options.prec, (Infinity, Infinity))
5716                                    }
5717                                    (true, false) => Complex::with_val(
5718                                        options.prec,
5719                                        (Infinity, -Float::with_val(options.prec, Infinity)),
5720                                    ),
5721                                    (false, true) => Complex::with_val(
5722                                        options.prec,
5723                                        (-Float::with_val(options.prec, Infinity), Infinity),
5724                                    ),
5725                                    (false, false) => {
5726                                        -Complex::with_val(options.prec, (Infinity, Infinity))
5727                                    }
5728                                }
5729                            }
5730                            (true, false) => {
5731                                if n1.real().is_sign_positive() {
5732                                    Complex::with_val(
5733                                        options.prec,
5734                                        (
5735                                            Infinity,
5736                                            if (n1.imag() - n2.imag().clone()).abs().log2()
5737                                                < options.prec as i32 / -16
5738                                            {
5739                                                n2.imag().clone()
5740                                            } else {
5741                                                Float::new(options.prec)
5742                                            },
5743                                        ),
5744                                    )
5745                                } else {
5746                                    -Complex::with_val(
5747                                        options.prec,
5748                                        (
5749                                            Infinity,
5750                                            if (n1.imag() - n2.imag().clone()).abs().log2()
5751                                                < options.prec as i32 / -16
5752                                            {
5753                                                -n2.imag().clone()
5754                                            } else {
5755                                                Float::new(options.prec)
5756                                            },
5757                                        ),
5758                                    )
5759                                }
5760                            }
5761                            (false, true) => {
5762                                if n1.imag().is_sign_positive() {
5763                                    Complex::with_val(
5764                                        options.prec,
5765                                        (
5766                                            if (n1.real() - n2.real().clone()).abs().log2()
5767                                                < options.prec as i32 / -16
5768                                            {
5769                                                n2.real().clone()
5770                                            } else {
5771                                                Float::new(options.prec)
5772                                            },
5773                                            Infinity,
5774                                        ),
5775                                    )
5776                                } else {
5777                                    -Complex::with_val(
5778                                        options.prec,
5779                                        (
5780                                            if (n1.real() - n2.real().clone()).abs().log2()
5781                                                < options.prec as i32 / -16
5782                                            {
5783                                                -n2.real().clone()
5784                                            } else {
5785                                                Float::new(options.prec)
5786                                            },
5787                                            Infinity,
5788                                        ),
5789                                    )
5790                                }
5791                            }
5792                            (false, false) => Complex::with_val(options.prec, Nan),
5793                        }
5794                    }
5795                },
5796                units,
5797            )))
5798        }
5799        (Vector(n1), Vector(n2)) => {
5800            let mut n3: Vec<Number> = Vec::new();
5801            let mut vec = Vec::with_capacity(n1.len().max(1));
5802            for (i, (n1, n2)) in n1.iter().zip(n2).enumerate() {
5803                let units = n1.units;
5804                let n1 = &n1.number;
5805                let n2 = &n2.number;
5806                vec.push(Number::from(
5807                    if (n2.clone() - n1.clone()).abs().real().clone().log2()
5808                        < options.prec as i32 / -16
5809                    {
5810                        n1.clone()
5811                    } else {
5812                        if n3.is_empty() {
5813                            let h3 = Complex::with_val(options.prec, 0.5)
5814                                .pow((options.prec / 2) as f64 + 13.0 / 0.7);
5815                            n3 = do_math_with_var(
5816                                func.clone(),
5817                                options,
5818                                func_vars.clone(),
5819                                &var,
5820                                NumStr::new(Number::from(point.clone() - h3.clone(), xunits)),
5821                            )?
5822                            .vec()?;
5823                        }
5824                        let n3 = &n3[i].number;
5825                        let sign = n1.real().is_sign_positive() == n2.real().is_sign_positive()
5826                            && n2.real().is_sign_positive() == n3.real().is_sign_positive()
5827                            && n1.imag().is_sign_positive() == n2.imag().is_sign_positive()
5828                            && n2.imag().is_sign_positive() == n3.imag().is_sign_positive();
5829                        let n1r = n1.real().clone().abs();
5830                        let n2r = n2.real().clone().abs();
5831                        let n3r = n3.real().clone().abs();
5832                        let n1i = n1.imag().clone().abs();
5833                        let n2i = n2.imag().clone().abs();
5834                        let n3i = n3.imag().clone().abs();
5835                        if !sign {
5836                            Complex::with_val(options.prec, Nan)
5837                        } else {
5838                            match (n3r > n2r && n2r > n1r, n3i > n2i && n2i > n1i) {
5839                                (true, true) => {
5840                                    match (
5841                                        n1.real().is_sign_positive(),
5842                                        n1.imag().is_sign_positive(),
5843                                    ) {
5844                                        (true, true) => {
5845                                            Complex::with_val(options.prec, (Infinity, Infinity))
5846                                        }
5847                                        (true, false) => Complex::with_val(
5848                                            options.prec,
5849                                            (Infinity, -Float::with_val(options.prec, Infinity)),
5850                                        ),
5851                                        (false, true) => Complex::with_val(
5852                                            options.prec,
5853                                            (-Float::with_val(options.prec, Infinity), Infinity),
5854                                        ),
5855                                        (false, false) => {
5856                                            -Complex::with_val(options.prec, (Infinity, Infinity))
5857                                        }
5858                                    }
5859                                }
5860                                (true, false) => {
5861                                    if n1.real().is_sign_positive() {
5862                                        Complex::with_val(
5863                                            options.prec,
5864                                            (
5865                                                Infinity,
5866                                                if (n2i - n3i.clone()).abs().log2()
5867                                                    < options.prec as i32 / -16
5868                                                {
5869                                                    n3i
5870                                                } else {
5871                                                    Float::new(options.prec)
5872                                                },
5873                                            ),
5874                                        )
5875                                    } else {
5876                                        -Complex::with_val(
5877                                            options.prec,
5878                                            (
5879                                                Infinity,
5880                                                if (n2i - n3i.clone()).abs().log2()
5881                                                    < options.prec as i32 / -16
5882                                                {
5883                                                    -n3i
5884                                                } else {
5885                                                    Float::new(options.prec)
5886                                                },
5887                                            ),
5888                                        )
5889                                    }
5890                                }
5891                                (false, true) => {
5892                                    if n1.imag().is_sign_positive() {
5893                                        Complex::with_val(
5894                                            options.prec,
5895                                            (
5896                                                if (n2r - n3r.clone()).abs().log2()
5897                                                    < options.prec as i32 / -16
5898                                                {
5899                                                    n3r
5900                                                } else {
5901                                                    Float::new(options.prec)
5902                                                },
5903                                                Infinity,
5904                                            ),
5905                                        )
5906                                    } else {
5907                                        -Complex::with_val(
5908                                            options.prec,
5909                                            (
5910                                                if (n2r - n3r.clone()).abs().log2()
5911                                                    < options.prec as i32 / -16
5912                                                {
5913                                                    -n3r
5914                                                } else {
5915                                                    Float::new(options.prec)
5916                                                },
5917                                                Infinity,
5918                                            ),
5919                                        )
5920                                    }
5921                                }
5922                                (false, false) => Complex::with_val(options.prec, Nan),
5923                            }
5924                        }
5925                    },
5926                    units,
5927                ))
5928            }
5929            Ok(Vector(vec))
5930        }
5931        (_, _) => Err("unsupported lim data"),
5932    }
5933}
5934//https://github.com/IstvanMezo/LambertW-function/blob/master/complex%20Lambert.cpp
5935pub fn lambertw(z: Complex, k: Integer) -> Complex {
5936    if z.is_zero() {
5937        return if k == 0 {
5938            Complex::new(z.prec())
5939        } else {
5940            -Complex::with_val(z.prec(), Infinity)
5941        };
5942    }
5943    if z.imag().is_zero() && (k == 0 || k == -1) {
5944        let e: Float = -Float::with_val(z.prec().0, -1).exp();
5945        if z.real() == &e {
5946            return Complex::with_val(z.prec(), -1);
5947        }
5948    }
5949    let mut w = initpoint(z.clone(), k);
5950    for _ in 0..(z.prec().0 / 64).max(8) {
5951        let zexp = w.clone().exp();
5952        let zexpz = &w * zexp.clone();
5953        let zexpz_d = &zexp + zexpz.clone();
5954        let zexpz_dd = (2 * zexp) + &zexpz;
5955        w -=
5956            2 * ((zexpz.clone() - &z) * &zexpz_d) / ((2 * sqr(zexpz_d)) - ((zexpz - &z) * zexpz_dd))
5957    }
5958    w
5959}
5960fn initpoint(z: Complex, k: Integer) -> Complex {
5961    let prec = z.prec();
5962    {
5963        let e = Float::with_val(prec.0, -1).exp();
5964        let test: Complex = z.clone() + &e;
5965        if test.abs().real() <= &1.005 {
5966            if k == 0 && z.real() > &-0.5 {
5967                let p1: Complex = 2 * z / e + 2;
5968                let p = p1.clone().sqrt();
5969                return p.clone() - (p1 / 3) + ((11 * cube(p)) / 72) - 1;
5970            } else if k == -1 && z.real().is_sign_negative() && z.imag().is_zero() {
5971                let p1: Complex = 2 * z / e + 2;
5972                let p = p1.clone().sqrt();
5973                return -p.clone() - (p1 / 3) - ((11 * cube(p)) / 72) - 1;
5974            }
5975        }
5976    }
5977    {
5978        let test: Complex = z.clone() - 0.5;
5979        if test.abs().real() <= &0.6 {
5980            if k == 0 {
5981                return (0.35173371 * (0.1237166 + 7.061302897 * z.clone()))
5982                    / (2 + 0.827184 * (1 + 2 * z));
5983            } else if k == -1 {
5984                return (Complex::with_val(prec, (-2.2591588985, -4.22096))
5985                    * (Complex::with_val(prec, (-14.073271, -33.767687754)) * &z
5986                        + Complex::with_val(prec, (-12.7127, 19.071643)) * (1 + 2 * z.clone())))
5987                    / (2 + Complex::with_val(prec, (-17.23103, 10.629721)) * (1 + 2 * z));
5988            }
5989        }
5990    }
5991    let zln = z.ln() + Complex::with_val(prec, (0, 2 * Float::with_val(prec.0, Pi) * k));
5992    zln.clone() - zln.ln()
5993}
5994#[cfg(feature = "fastrand")]
5995pub fn rand_gamma(k: Float, t: Float) -> Float {
5996    let prec = k.prec();
5997    let mut sum = Float::new(prec);
5998    for _ in 1..=k
5999        .clone()
6000        .floor()
6001        .to_integer()
6002        .unwrap_or_default()
6003        .to_usize()
6004        .unwrap_or_default()
6005    {
6006        let u: Float = Float::with_val(prec, fastrand::u128(1..)) / u128::MAX;
6007        sum += u.ln();
6008    }
6009    let s = k.clone().fract();
6010    let e = Float::with_val(prec, 1).exp();
6011    let check = e.clone() / (e + s.clone());
6012    let mut eta: Float;
6013    loop {
6014        let u: Float = Float::with_val(prec, fastrand::u128(1..)) / u128::MAX;
6015        let v: Float = Float::with_val(prec, fastrand::u128(1..)) / u128::MAX;
6016        let w: Float = Float::with_val(prec, fastrand::u128(1..)) / u128::MAX;
6017        let n;
6018        if u <= check {
6019            eta = v.pow(1 / s.clone());
6020            n = w * eta.clone().pow(s.clone() - 1);
6021        } else {
6022            eta = 1 - v.ln();
6023            n = w * (-eta.clone()).exp();
6024        };
6025        if n <= eta.clone().pow(s.clone() - 1) * (-eta.clone()).exp() {
6026            break;
6027        }
6028    }
6029    let f: Float = eta - sum;
6030    t * f
6031}
6032#[cfg(feature = "fastrand")]
6033pub fn rand_norm(m: Complex, s: Complex) -> Complex {
6034    let prec = s.prec().0;
6035    let mut u: Float = Float::with_val(prec, fastrand::i128(i128::MIN + 2..i128::MAX)) / i128::MAX;
6036    let mut v: Float = Float::with_val(prec, fastrand::i128(i128::MIN + 2..i128::MAX)) / i128::MAX;
6037    let mut g: Float = u.clone().pow(2) + v.pow(2);
6038    while g >= 1 {
6039        u = Float::with_val(prec, fastrand::i128(i128::MIN + 2..i128::MAX)) / i128::MAX;
6040        v = Float::with_val(prec, fastrand::i128(i128::MIN + 2..i128::MAX)) / i128::MAX;
6041        g = u.clone().pow(2) + v.pow(2);
6042    }
6043    let d: Float = -2 * g.clone().ln() / g;
6044    let z: Float = u * d.sqrt();
6045    m + z * s
6046}
6047pub fn regularized_incomplete_beta(x: Complex, a: Complex, b: Complex) -> Complex {
6048    (gamma(a.clone() + b.clone())) * incomplete_beta(x, a.clone(), b.clone())
6049        / (gamma(a) * gamma(b))
6050}
6051pub fn sqr(z: Complex) -> Complex {
6052    if z.imag().is_zero() {
6053        z.pow(2)
6054    } else {
6055        z.clone() * z
6056    }
6057}
6058pub fn cube(z: Complex) -> Complex {
6059    if z.imag().is_zero() {
6060        z.pow(3)
6061    } else {
6062        z.clone() * &z * z
6063    }
6064}
6065pub fn pow_nth(z: Complex, n: Complex) -> Complex {
6066    let zz = z.imag().is_zero();
6067    let nz = n.imag().is_zero();
6068    let nr = n.real();
6069    if nr.clone().fract().is_zero() && nz {
6070        if !zz && nr <= &256 {
6071            if nr.is_zero() {
6072                Complex::with_val(z.prec(), 1)
6073            } else {
6074                let mut p = z.clone();
6075                for _ in 1..n
6076                    .real()
6077                    .to_integer()
6078                    .unwrap_or_default()
6079                    .abs()
6080                    .to_usize()
6081                    .unwrap_or_default()
6082                {
6083                    p *= &z;
6084                }
6085                if nr.is_sign_positive() { p } else { 1 / p }
6086            }
6087        } else {
6088            z.pow(n)
6089        }
6090    } else if zz && nz && {
6091        let zr = z.real();
6092        zr.clone().fract().is_zero() && zr.is_sign_negative()
6093    } {
6094        z.pow(n)
6095    } else {
6096        (z.ln() * n).exp()
6097    }
6098}
6099pub fn hsv2rgb(mut hue: Float, sat: Float, val: Float) -> Vec<Number> {
6100    if sat.is_zero() {
6101        return rgb2val(val.clone(), val.clone(), val);
6102    }
6103    hue *= 6;
6104    let i = hue
6105        .clone()
6106        .floor()
6107        .to_integer()
6108        .unwrap_or_default()
6109        .to_usize()
6110        .unwrap_or_default();
6111    let f = hue - i;
6112    let p = val.clone() * (1 - sat.clone());
6113    let q = val.clone() * (1 - sat.clone() * f.clone());
6114    let t = val.clone() * (1 - sat * (1 - f));
6115    match i % 6 {
6116        0 => rgb2val(val, t, p),
6117        1 => rgb2val(q, val, p),
6118        2 => rgb2val(p, val, t),
6119        3 => rgb2val(p, q, val),
6120        4 => rgb2val(t, p, val),
6121        5 => rgb2val(val, p, q),
6122        _ => rgb2val(val, p, q),
6123    }
6124}
6125pub fn rgb2val(r: Float, g: Float, b: Float) -> Vec<Number> {
6126    let r: Float = 255 * r;
6127    let g: Float = 255 * g;
6128    let b: Float = 255 * b;
6129    vec![
6130        Number::from(r.into(), None),
6131        Number::from(g.into(), None),
6132        Number::from(b.into(), None),
6133    ]
6134}