use crate::polynomial::{Error, MultilinearExtensionSpecialized, MultilinearQueryRef};
use binius_field::PackedField;
use std::{fmt::Debug, ops::Deref};
pub trait MultilinearPoly<P: PackedField>: Debug {
fn n_vars(&self) -> usize;
fn size(&self) -> usize {
1 << self.n_vars()
}
fn extension_degree(&self) -> usize;
fn evaluate_on_hypercube(&self, index: usize) -> Result<P::Scalar, Error>;
fn evaluate_on_hypercube_and_scale(
&self,
index: usize,
scalar: P::Scalar,
) -> Result<P::Scalar, Error>;
fn evaluate(&self, query: MultilinearQueryRef<P>) -> Result<P::Scalar, Error>;
fn evaluate_partial_low(
&self,
query: MultilinearQueryRef<P>,
) -> Result<MultilinearExtensionSpecialized<P, P>, Error>;
fn evaluate_partial_high(
&self,
query: MultilinearQueryRef<P>,
) -> Result<MultilinearExtensionSpecialized<P, P>, Error>;
fn subcube_inner_products(
&self,
query: MultilinearQueryRef<P>,
subcube_vars: usize,
subcube_index: usize,
inner_products: &mut [P],
) -> Result<(), Error>;
fn subcube_evals(
&self,
subcube_vars: usize,
subcube_index: usize,
evals: &mut [P],
) -> Result<(), Error>;
fn underlier_data(&self) -> Option<Vec<u8>>;
}
impl<T, P: PackedField> MultilinearPoly<P> for T
where
T: Deref + Debug,
T::Target: MultilinearPoly<P>,
{
fn n_vars(&self) -> usize {
(**self).n_vars()
}
fn size(&self) -> usize {
(**self).size()
}
fn extension_degree(&self) -> usize {
(**self).extension_degree()
}
fn evaluate_on_hypercube(&self, index: usize) -> Result<P::Scalar, Error> {
(**self).evaluate_on_hypercube(index)
}
fn evaluate_on_hypercube_and_scale(
&self,
index: usize,
scalar: P::Scalar,
) -> Result<P::Scalar, Error> {
(**self).evaluate_on_hypercube_and_scale(index, scalar)
}
fn evaluate(&self, query: MultilinearQueryRef<P>) -> Result<P::Scalar, Error> {
(**self).evaluate(query)
}
fn evaluate_partial_low(
&self,
query: MultilinearQueryRef<P>,
) -> Result<MultilinearExtensionSpecialized<P, P>, Error> {
(**self).evaluate_partial_low(query)
}
fn evaluate_partial_high(
&self,
query: MultilinearQueryRef<P>,
) -> Result<MultilinearExtensionSpecialized<P, P>, Error> {
(**self).evaluate_partial_high(query)
}
fn subcube_inner_products(
&self,
query: MultilinearQueryRef<P>,
subcube_vars: usize,
subcube_index: usize,
inner_products: &mut [P],
) -> Result<(), Error> {
(**self).subcube_inner_products(query, subcube_vars, subcube_index, inner_products)
}
fn subcube_evals(
&self,
subcube_vars: usize,
subcube_index: usize,
evals: &mut [P],
) -> Result<(), Error> {
(**self).subcube_evals(subcube_vars, subcube_index, evals)
}
fn underlier_data(&self) -> Option<Vec<u8>> {
(**self).underlier_data()
}
}