1use crate::math::fps::log::*;
3use crate::math::polynomial::{Polynomial, PolynomialOperator};
4
5pub trait FpsExp {
7 type Poly;
9
10 fn fps_exp(&self, f: Self::Poly) -> Self::Poly;
12}
13
14impl<const P: u32, const PR: u32> FpsExp for PolynomialOperator<'_, P, PR> {
15 type Poly = Polynomial<P>;
16
17 fn fps_exp(&self, f: Self::Poly) -> Self::Poly {
18 let f: Vec<_> = f.into();
19 let n = f.len();
20
21 let mut t = 1;
22 let mut b = Polynomial::constant(1.into());
23
24 loop {
25 let mut temp: Vec<_> = self.fps_log(b.clone()).into();
26
27 temp.resize(2 * t, 0.into());
28 temp.iter_mut().for_each(|x| *x = -*x);
29 temp[0] += 1.into();
30
31 temp.iter_mut()
32 .zip(f.iter())
33 .for_each(|(temp, f)| *temp += *f);
34
35 b = self.mul(b, temp.into());
36 b.as_mut().resize(2 * t, 0.into());
37
38 if t >= n {
39 break;
40 }
41
42 t <<= 1;
43 }
44
45 b.as_mut().truncate(n);
46 b
47 }
48}