# Description
A multilinear polynomial is stored by a list of its evaluations.
__Example__ $f(x_1, x_2) = 3x_1x_2 + 2x_2$ is stored as $[0,2,0,5]$ whose evaluations are
0, 0 |-> 0
0, 1 |-> 2
1, 0 |-> 0
1, 1 |-> 5
We have a multilinear extension $eq(\vec x, \vec r)$ for $\vec x = \left<x_1,\dots,x_n\right>$ and a point $\vec r = \left<r_1,\dots,r_n\right>$.
__Task__: Evaluate
$$eq(\vec x,\vec r) = \prod_{i=1}^n (x_i \times r_i + (1-x_i)\times(1-r_i))$$
We build $eq(\vec x, \vec r)$ for $\vec x = \left<x_1,\dots,x_n\right>$ and a point $\vec r = \left<r_1,\dots,r_n\right>$ from its evaluations. To build $eq(\vec x, \vec r)$, we want to evaluate $eq(\vec x, \vec r)$ over $\vec x \in \{0, 1\}^n$.
__Example__. With n = 4, x is a binary vector of 4, then $eq(\vec x,\vec r)$ with $\vec r = [1,2,3,4]$
x1, x2, x3, x4
0, 0, 0, 0 |-> (1-r0) * (1-r1) * (1-r2) * (1-r3) = 0
1, 0, 0, 0 |-> r0 * (1-r1) * (1-r2) * (1-r3) = -6
0, 1, 0, 0 |-> (1-r0) * r1 * (1-r2) * (1-r3) = 0
1, 1, 0, 0 |-> r0 * r1 * (1-r2) * (1-r3) = 12
....
1, 1, 1, 1 |-> r0 * r1 * r2 * r3 = 24
# Code
``` rust
/// Stores a multilinear polynomial in dense evaluation form.
#[derive(Clone, PartialEq, Eq, Hash, Default, CanonicalSerialize, CanonicalDeserialize)]
pub struct DenseMultilinearExtension<F: Field> {
/// The evaluation over {0,1}^`num_vars`
pub evaluations: Vec<F>,
/// Number of variables
pub num_vars: usize,
}
```
``` rust
/// This function build the eq(x, r) polynomial for any given r.
///
/// Evaluate
/// eq(x,y) = \prod_i=1^num_var (x_i * y_i + (1-x_i)*(1-y_i))
/// over r, which is
/// eq(x,r) = \prod_i=1^num_var (x_i * r_i + (1-x_i)*(1-r_i))
pub fn build_eq_x_r<F: PrimeField>(r: &[F]) -> DenseMultilinearExtension {
// num_var = r.len()
// eq(x,r) with r = [1,2]
// 0, 0, |-> (1-r0) * (1-r1) = 0
// 1, 0, |-> r0 * (1-r1) = 1
// 0, 1, |-> (1-r0) * r1 = 0
// 1, 1, |-> r0 * r1 = 2
// your code here
let mut extensions: DenseMultilinearExtension {
evaluations: vec![],
num_vars: r.len()
}
let index = 0;
while index <= 2^(r.len()) {
let decomposition: Vec<Bool> = decompose(index);
let mut accumulator;
for (i,item) in decomposition.iter().enumerate() {
if item == false {
accumulator *= eval(r[i], 0)
} else {
accumulator *= eval(r[i], 1)
}
}
extensions.evaluations.append(accumulator)
}
}
// O(2^(r.len()) * r.len()), Super linear in terms of number of constraints
// O(N*log(N)) where N = 2^(r.len()) is # variable in CS
// O(N)
pub fn eval(r: &F, x_1: usize) -> F {
(x_1 * r) + ( 1 - x_1 ) * ( 1 - r)
}
// index loop though 0.. 2^num_vars
// decompose(0) -> (0, 0)
// decompose(1) -> (1, 0)
// decompose(2) -> (0, 1)
// decompose(3) -> (1, 1)
pub fn decompose(index: u8)-> Vec<bool>{}
// for each loop with index
// vec x = decompose(index)
// vec r = r
// compute \prod_i=1^num_var (x_i * r_i + (1-x_i)*(1-r_i))
```