use ark_ff::Field;
use super::{Evaluate, LinearForm};
use crate::{
algebra::{eval_eq, mixed_multilinear_extend, Embedding},
utils::zip_strict,
};
#[derive(Clone, Debug, PartialEq, Eq, Default)]
pub struct MultilinearExtension<F: Field> {
pub point: Vec<F>,
}
impl<F: Field> MultilinearExtension<F> {
pub const fn new(point: Vec<F>) -> Self {
Self { point }
}
}
impl<F: Field> LinearForm<F> for MultilinearExtension<F> {
fn size(&self) -> usize {
1 << self.point.len()
}
fn mle_evaluate(&self, point: &[F]) -> F {
zip_strict(&self.point, point).fold(F::ONE, |acc, (&l, &r)| {
acc * (l * r + (F::ONE - l) * (F::ONE - r))
})
}
fn accumulate(&self, accumulator: &mut [F], scalar: F) {
eval_eq(accumulator, &self.point, scalar);
}
}
impl<M: Embedding> Evaluate<M> for MultilinearExtension<M::Target> {
fn evaluate(&self, embedding: &M, vector: &[M::Source]) -> M::Target {
mixed_multilinear_extend(embedding, vector, &self.point)
}
}