Batch inversions during domain setup.

This commit is contained in:
Sean Bowe 2020-09-06 12:44:36 -06:00
parent ff8f9eb20e
commit 3157fdd7d0
No known key found for this signature in database
GPG key ID: 95684257D8F8B031

View file

@ -1,4 +1,4 @@
use crate::arithmetic::{best_fft, parallelize, Field, Group};
use crate::arithmetic::{best_fft, parallelize, BatchInvert, Field, Group};
/// Describes a relative location in the evaluation domain; applying a rotation
/// by i will rotate the vector in the evaluation domain by i.
@ -57,24 +57,20 @@ impl<G: Group> EvaluationDomain<G> {
extended_omega = extended_omega.square();
}
let extended_omega = extended_omega; // 2^{j+k}'th root of unity
let extended_omega_inv = extended_omega.invert().unwrap();
let mut extended_omega_inv = extended_omega; // Inversion computed later
let mut omega = extended_omega;
for _ in k..extended_k {
omega = omega.square();
}
let omega = omega; // 2^{k}'th root of unity
let omega_inv = omega.invert().unwrap();
let mut omega_inv = omega; // Inversion computed later
// We use zeta here because we know it generates a coset, and it's available
// already.
let g_coset = G::Scalar::ZETA;
let g_coset_inv = g_coset.square();
// TODO: merge these inversions together with t_evaluations batch inversion?
let ifft_divisor = G::Scalar::from_u64(1 << k).invert().unwrap();
let extended_ifft_divisor = G::Scalar::from_u64(1 << extended_k).invert().unwrap();
let mut t_evaluations = Vec::with_capacity(1 << (extended_k - k));
{
// Compute the evaluations of t(X) in the coset evaluation domain.
@ -97,12 +93,25 @@ impl<G: Group> EvaluationDomain<G> {
}
// Invert, because we're dividing by this polynomial.
G::Scalar::batch_invert(&mut t_evaluations);
// We invert in a batch, below.
}
let mut ifft_divisor = G::Scalar::from_u64(1 << k); // Inversion computed later
let mut extended_ifft_divisor = G::Scalar::from_u64(1 << extended_k); // Inversion computed later
// The barycentric weight of 1 over the evaluation domain
// 1 / \prod_{i != 0} (1 - omega^i)
let barycentric_weight = G::Scalar::from(n).invert().unwrap();
let mut barycentric_weight = G::Scalar::from(n); // Inversion computed later
// Compute batch inversion
t_evaluations
.iter_mut()
.chain(Some(&mut ifft_divisor))
.chain(Some(&mut extended_ifft_divisor))
.chain(Some(&mut barycentric_weight))
.chain(Some(&mut extended_omega_inv))
.chain(Some(&mut omega_inv))
.batch_invert();
EvaluationDomain {
n,