---
# System prepended metadata

title: 'Implement `Eq(x,r)` function'

---

# 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))
```