|
1 | 1 | use crate::poly::domain::vanishing_poly::VanishingPolynomial; |
2 | | -use ark_ff::{batch_inversion, PrimeField}; |
| 2 | +use ark_ff::{batch_inversion_and_mul, PrimeField}; |
3 | 3 | use ark_std::vec::Vec; |
4 | 4 | /// Struct describing Lagrange interpolation for a multiplicative coset I, |
5 | 5 | /// with |I| a power of 2. |
@@ -71,21 +71,18 @@ impl<F: PrimeField> LagrangeInterpolator<F> { |
71 | 71 | - Z_{H}(t) = \prod_{j} (t-h*g^j) = (t^m-h^m), and |
72 | 72 | - v_{i} = 1 / \prod_{j \neq i} h(g^i-g^j). |
73 | 73 | Below we use the fact that v_{0} = 1/(m * h^(m-1)) and v_{i+1} = g * v_{i}. |
74 | | - We compute the inverse of each coefficient, and then batch invert the entire result. |
| 74 | + We first compute the inverse of each coefficient, except for the Z_H(t) term. |
| 75 | + We then batch invert the entire result, and multiply by Z_H(t). |
75 | 76 | */ |
76 | | - let vp_t_inv = self |
77 | | - .domain_vp |
78 | | - .evaluate(&interpolation_point) |
79 | | - .inverse() |
80 | | - .unwrap(); |
81 | 77 | let mut inverted_lagrange_coeffs: Vec<F> = Vec::with_capacity(self.all_domain_elems.len()); |
82 | 78 | for i in 0..self.domain_order { |
83 | | - let l = vp_t_inv * self.v_inv_elems[i]; |
| 79 | + let l = self.v_inv_elems[i]; |
84 | 80 | let r = self.all_domain_elems[i]; |
85 | 81 | inverted_lagrange_coeffs.push(l * (interpolation_point - r)); |
86 | 82 | } |
| 83 | + let vp_t = self.domain_vp.evaluate(&interpolation_point); |
87 | 84 | let lagrange_coeffs = inverted_lagrange_coeffs.as_mut_slice(); |
88 | | - batch_inversion::<F>(lagrange_coeffs); |
| 85 | + batch_inversion_and_mul::<F>(lagrange_coeffs, &vp_t); |
89 | 86 | lagrange_coeffs.iter().cloned().collect() |
90 | 87 | } |
91 | 88 |
|
|
0 commit comments