Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions poly/src/polynomial/univariate/dense.rs
Original file line number Diff line number Diff line change
Expand Up @@ -608,9 +608,9 @@ impl<F: Field> Zero for DensePolynomial<F> {

#[cfg(test)]
mod tests {
use crate::{polynomial::univariate::*, EvaluationDomain, GeneralEvaluationDomain};
use crate::{polynomial::univariate::*, EvaluationDomain, GeneralEvaluationDomain, Polynomial};
use ark_ff::{Field, One, UniformRand, Zero};
use ark_std::{rand::Rng, test_rng};
use ark_std::{rand::Rng, test_rng, vec::Vec};
use ark_test_curves::bls12_381::Fr;

fn rand_sparse_poly<R: Rng>(degree: usize, rng: &mut R) -> SparsePolynomial<Fr> {
Expand Down Expand Up @@ -889,4 +889,24 @@ mod tests {
assert_eq!(y.degree(), n - 1);
assert!(!y.coeffs.last().unwrap().is_zero());
}

#[test]
fn evaluate_over_domain_test() {
let rng = &mut ark_std::test_rng();
let domain = crate::domain::Radix2EvaluationDomain::<Fr>::new(1 << 10).unwrap();
for _ in 0..100 {
let poly = DensePolynomial::<Fr>::rand(1 << 11, rng);
let evaluations = domain
.elements()
.map(|e| poly.evaluate(&e))
.collect::<Vec<_>>();
assert_eq!(evaluations, poly.evaluate_over_domain(domain).evals);
}
let zero = DensePolynomial::zero();
let evaluations = domain
.elements()
.map(|e| zero.evaluate(&e))
.collect::<Vec<_>>();
assert_eq!(evaluations, zero.evaluate_over_domain(domain).evals);
}
}
40 changes: 24 additions & 16 deletions poly/src/polynomial/univariate/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,27 +156,35 @@ impl<'a, F: 'a + FftField> DenseOrSparsePolynomial<'a, F> {
Evaluations::from_vec_and_domain(evals, domain)
},
DPolynomial(Cow::Borrowed(d)) => {
// Reduce the coefficients of the polynomial mod X^domain.size()
let mut chunks = d.coeffs.chunks(domain.size());
let mut reduced = chunks.next().unwrap().to_vec();
for chunk in chunks {
cfg_iter_mut!(reduced).zip(chunk).for_each(|(x, y)| {
*x += y;
});
if d.is_zero() {
Evaluations::from_vec_and_domain(vec![F::zero(); domain.size()], domain)
} else {
// Reduce the coefficients of the polynomial mod X^domain.size()
let mut chunks = d.coeffs.chunks(domain.size());
let mut reduced = chunks.next().unwrap().to_vec();
for chunk in chunks {
cfg_iter_mut!(reduced).zip(chunk).for_each(|(x, y)| {
*x += y;
});
}
Evaluations::from_vec_and_domain(domain.fft(&reduced), domain)
}
Evaluations::from_vec_and_domain(domain.fft(&reduced), domain)
},
DPolynomial(Cow::Owned(mut d)) => {
// Reduce the coefficients of the polynomial mod X^domain.size()
let mut chunks = d.coeffs.chunks_mut(domain.size());
let coeffs = chunks.next().unwrap();
for chunk in chunks {
cfg_iter_mut!(coeffs).zip(chunk).for_each(|(x, y)| {
*x += y;
});
if d.is_zero() {
Evaluations::from_vec_and_domain(vec![F::zero(); domain.size()], domain)
} else {
let mut chunks = d.coeffs.chunks_mut(domain.size());
let coeffs = chunks.next().unwrap();
for chunk in chunks {
cfg_iter_mut!(coeffs).zip(chunk).for_each(|(x, y)| {
*x += y;
});
}
domain.fft_in_place(&mut d.coeffs);
Evaluations::from_vec_and_domain(d.coeffs, domain)
}
domain.fft_in_place(&mut d.coeffs);
Evaluations::from_vec_and_domain(d.coeffs, domain)
},
}
}
Expand Down