ark_poly/evaluations/univariate/
mod.rs1use 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#[derive(Clone, PartialEq, Eq, Hash, Debug, CanonicalSerialize, CanonicalDeserialize)]
19pub struct Evaluations<F: FftField, D: EvaluationDomain<F> = GeneralEvaluationDomain<F>> {
20 pub evals: Vec<F>,
22 #[doc(hidden)]
23 domain: D,
24}
25
26impl<F: FftField, D: EvaluationDomain<F>> Evaluations<F, D> {
27 pub fn zero(domain: D) -> Self {
29 Self {
30 evals: vec![F::zero(); domain.size()],
31 domain,
32 }
33 }
34
35 pub const fn from_vec_and_domain(evals: Vec<F>, domain: D) -> Self {
37 Self { evals, domain }
38 }
39
40 pub fn interpolate_by_ref(&self) -> DensePolynomial<F> {
42 DensePolynomial::from_coefficients_vec(self.domain.ifft(&self.evals))
43 }
44
45 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 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}