Skip to main content

ark_poly/evaluations/univariate/
mod.rs

1//! A univariate polynomial represented in evaluations form.
2
3use crate::{
4    univariate::DensePolynomial, DenseUVPolynomial, EvaluationDomain, GeneralEvaluationDomain,
5};
6use ark_ff::{batch_inversion, FftField};
7use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
8use ark_std::{
9    ops::{Add, AddAssign, Div, DivAssign, Index, Mul, MulAssign, Sub, SubAssign},
10    vec,
11    vec::*,
12};
13
14#[cfg(feature = "parallel")]
15use rayon::prelude::*;
16
17/// Stores a UV polynomial in evaluation form.
18#[derive(Clone, PartialEq, Eq, Hash, Debug, CanonicalSerialize, CanonicalDeserialize)]
19pub struct Evaluations<F: FftField, D: EvaluationDomain<F> = GeneralEvaluationDomain<F>> {
20    /// The evaluations of a polynomial over the domain `D`
21    pub evals: Vec<F>,
22    #[doc(hidden)]
23    domain: D,
24}
25
26impl<F: FftField, D: EvaluationDomain<F>> Evaluations<F, D> {
27    /// Evaluations of the zero polynomial over `domain`.
28    pub fn zero(domain: D) -> Self {
29        Self {
30            evals: vec![F::zero(); domain.size()],
31            domain,
32        }
33    }
34
35    /// Construct `Self` from evaluations and a domain.
36    pub const fn from_vec_and_domain(evals: Vec<F>, domain: D) -> Self {
37        Self { evals, domain }
38    }
39
40    /// Interpolate a polynomial from a list of evaluations
41    pub fn interpolate_by_ref(&self) -> DensePolynomial<F> {
42        DensePolynomial::from_coefficients_vec(self.domain.ifft(&self.evals))
43    }
44
45    /// Interpolate a polynomial from a list of evaluations
46    pub fn interpolate(self) -> DensePolynomial<F> {
47        let Self { mut evals, domain } = self;
48        domain.ifft_in_place(&mut evals);
49        DensePolynomial::from_coefficients_vec(evals)
50    }
51
52    /// Return the domain `self` is defined over
53    pub const fn domain(&self) -> D {
54        self.domain
55    }
56}
57
58impl<F: FftField, D: EvaluationDomain<F>> Index<usize> for Evaluations<F, D> {
59    type Output = F;
60
61    fn index(&self, index: usize) -> &F {
62        &self.evals[index]
63    }
64}
65
66impl<'a, F: FftField, D: EvaluationDomain<F>> Mul<&'a Evaluations<F, D>> for &Evaluations<F, D> {
67    type Output = Evaluations<F, D>;
68
69    #[inline]
70    fn mul(self, other: &'a Evaluations<F, D>) -> Evaluations<F, D> {
71        let mut result = self.clone();
72        result *= other;
73        result
74    }
75}
76
77impl<'a, F: FftField, D: EvaluationDomain<F>> MulAssign<&'a Self> for Evaluations<F, D> {
78    #[inline]
79    fn mul_assign(&mut self, other: &'a Self) {
80        assert_eq!(self.domain, other.domain, "domains are unequal");
81        ark_std::cfg_iter_mut!(self.evals)
82            .zip(&other.evals)
83            .for_each(|(a, b)| *a *= b);
84    }
85}
86
87impl<F: FftField, D: EvaluationDomain<F>> Mul<F> for &Evaluations<F, D> {
88    type Output = Evaluations<F, D>;
89
90    #[inline]
91    fn mul(self, elem: F) -> Evaluations<F, D> {
92        let mut result = self.clone();
93        ark_std::cfg_iter_mut!(result.evals).for_each(|e| {
94            *e *= elem;
95        });
96        result
97    }
98}
99
100impl<'a, F: FftField, D: EvaluationDomain<F>> Add<&'a Evaluations<F, D>> for &Evaluations<F, D> {
101    type Output = Evaluations<F, D>;
102
103    #[inline]
104    fn add(self, other: &'a Evaluations<F, D>) -> Evaluations<F, D> {
105        let mut result = self.clone();
106        result += other;
107        result
108    }
109}
110
111impl<'a, F: FftField, D: EvaluationDomain<F>> AddAssign<&'a Self> for Evaluations<F, D> {
112    #[inline]
113    fn add_assign(&mut self, other: &'a Self) {
114        assert_eq!(self.domain, other.domain, "domains are unequal");
115        ark_std::cfg_iter_mut!(self.evals)
116            .zip(&other.evals)
117            .for_each(|(a, b)| *a += b);
118    }
119}
120
121impl<'a, F: FftField, D: EvaluationDomain<F>> Sub<&'a Evaluations<F, D>> for &Evaluations<F, D> {
122    type Output = Evaluations<F, D>;
123
124    #[inline]
125    fn sub(self, other: &'a Evaluations<F, D>) -> Evaluations<F, D> {
126        let mut result = self.clone();
127        result -= other;
128        result
129    }
130}
131
132impl<'a, F: FftField, D: EvaluationDomain<F>> SubAssign<&'a Self> for Evaluations<F, D> {
133    #[inline]
134    fn sub_assign(&mut self, other: &'a Self) {
135        assert_eq!(self.domain, other.domain, "domains are unequal");
136        ark_std::cfg_iter_mut!(self.evals)
137            .zip(&other.evals)
138            .for_each(|(a, b)| *a -= b);
139    }
140}
141
142impl<'a, F: FftField, D: EvaluationDomain<F>> Div<&'a Evaluations<F, D>> for &Evaluations<F, D> {
143    type Output = Evaluations<F, D>;
144
145    #[inline]
146    fn div(self, other: &'a Evaluations<F, D>) -> Evaluations<F, D> {
147        let mut result = self.clone();
148        result /= other;
149        result
150    }
151}
152
153impl<'a, F: FftField, D: EvaluationDomain<F>> DivAssign<&'a Self> for Evaluations<F, D> {
154    #[inline]
155    fn div_assign(&mut self, other: &'a Self) {
156        assert_eq!(self.domain, other.domain, "domains are unequal");
157        let mut other_copy = other.clone();
158        batch_inversion(other_copy.evals.as_mut_slice());
159        ark_std::cfg_iter_mut!(self.evals)
160            .zip(&other_copy.evals)
161            .for_each(|(a, b)| *a *= b);
162    }
163}