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