haar_lib/math/fps/
log_sparse.rs1use crate::math::fps::inv_sparse::*;
3use crate::math::polynomial::sparse::SparsePolynomial;
4use crate::math::polynomial::Polynomial;
5use crate::math::prime_mod::PrimeMod;
6use crate::num::const_modint::*;
7
8pub trait FpsLogSparse {
10 type Output;
12
13 fn fps_log_sparse(self, n: usize) -> Result<Self::Output, &'static str>;
15}
16
17impl<P: PrimeMod> FpsLogSparse for SparsePolynomial<P> {
18 type Output = Polynomial<P>;
19
20 fn fps_log_sparse(self, n: usize) -> Result<Self::Output, &'static str> {
22 let mut f = self.clone();
23 f.differential();
24
25 let g = self.fps_inv_sparse(n)?;
26
27 let mut h = vec![ConstModInt::new(0); n];
28 for (&i, &x) in f.iter() {
29 for (&y, h) in g.data.iter().zip(h.iter_mut().skip(i)) {
30 *h += x * y;
31 }
32 }
33
34 let mut invs = vec![ConstModInt::new(1); n + 1];
35 for i in 2..=n {
36 invs[i] = -invs[P::PRIME_NUM as usize % i] * ConstModInt::new(P::PRIME_NUM / i as u32);
37 }
38
39 for i in (0..n - 1).rev() {
40 h[i + 1] = h[i] * invs[i + 1];
41 }
42 h[0] = 0.into();
43
44 Ok(Polynomial::from(h))
45 }
46}