arnaucube
arnaucube/shockwave-plusPublic Self-hosted repository
shockwave-plus/tensor_pcs/src/polynomial/sparse_ml_poly.rs
tensor_pcs/src/polynomial/sparse_ml_poly.rsRaw
 1use crate::{EqPoly, FieldExt};
 2
 3#[derive(Clone, Debug)]
 4pub struct SparseMLPoly<F> {
 5    pub evals: Vec<(usize, F)>,
 6    pub num_vars: usize,
 7}
 8
 9impl<F: FieldExt> SparseMLPoly<F> {
10    pub fn new(evals: Vec<(usize, F)>, num_vars: usize) -> Self {
11        Self { evals, num_vars }
12    }
13
14    pub fn from_dense(dense_evals: Vec<F>) -> Self {
15        let sparse_evals = dense_evals
16            .iter()
17            .filter(|eval| **eval != F::ZERO)
18            .enumerate()
19            .map(|(i, eval)| (i, *eval))
20            .collect::<Vec<(usize, F)>>();
21        let num_vars = (dense_evals.len() as f64).log2() as usize;
22
23        Self {
24            evals: sparse_evals,
25            num_vars,
26        }
27    }
28
29    pub fn eval(&self, t: &[F]) -> F {
30        // Evaluate the multilinear extension of the polynomial `a`,
31        // over the boolean hypercube
32
33        let eq_poly = EqPoly::new(t.to_vec());
34        let eq_evals = eq_poly.evals();
35
36        let mut result = F::ZERO;
37
38        for eval in &self.evals {
39            result += eq_evals[eval.0] * eval.1;
40        }
41
42        result
43    }
44}