diff --git a/prover/src/constraints/evaluator/default.rs b/prover/src/constraints/evaluator/default.rs index d923017b1..e5652faf4 100644 --- a/prover/src/constraints/evaluator/default.rs +++ b/prover/src/constraints/evaluator/default.rs @@ -322,7 +322,7 @@ where ); } - evaluator.evaluate_lagrange_kernel_constraints_2::( + evaluator.evaluate_lagrange_kernel_constraints::( trace, lagrange_kernel_aux_column_idx, domain, diff --git a/prover/src/constraints/evaluator/lagrange.rs b/prover/src/constraints/evaluator/lagrange.rs index 622b55f4e..ca49f2f94 100644 --- a/prover/src/constraints/evaluator/lagrange.rs +++ b/prover/src/constraints/evaluator/lagrange.rs @@ -36,7 +36,13 @@ impl LagrangeKernelConstraintsBatchEvaluator { } } - pub fn evaluate_lagrange_kernel_constraints_2( + /// Evaluates the transition and boundary constraints. Specifically, the constraint evaluations + /// are divided by their corresponding divisors, and the resulting terms are linearly combined + /// using the composition coefficients. + /// + /// Returns a buffer with the same length as the CE domain, where each element contains the + /// constraint evaluations (as explained above) at the corresponding domain point. + pub fn evaluate_lagrange_kernel_constraints( &self, trace: &T, lagrange_kernel_column_idx: usize, @@ -107,146 +113,23 @@ impl LagrangeKernelConstraintsBatchEvaluator { combined_evaluations_acc } - - /// Evaluates the transition and boundary constraints. Specifically, the constraint evaluations - /// are divided by their corresponding divisors, and the resulting terms are linearly combined - /// using the composition coefficients. - /// - /// Returns a buffer with the same length as the CE domain, where each element contains the - /// constraint evaluations (as explained above) at the corresponding domain point. - pub fn evaluate_lagrange_kernel_constraints( - &self, - num_trans_constraints: usize, - lagrange_kernel_column_frames: Vec>, - domain: &StarkDomain, - ) -> Vec - where - A: Air, - E: FieldElement, - { - let transition_constraint_combined_evaluations = self - .evaluate_combined_transition_constraints::( - num_trans_constraints, - &lagrange_kernel_column_frames, - domain, - ); - - let boundary_constraint_combined_evaluations: Vec = self - .evaluate_combined_boundary_constraints::(&lagrange_kernel_column_frames, domain); - - // combine boundary and transition constraint combined evaluations - transition_constraint_combined_evaluations - .into_iter() - .zip(boundary_constraint_combined_evaluations) - .map(|(transitions_combined, boundaries_combined)| { - transitions_combined + boundaries_combined - }) - .collect() - } - - // HELPERS - // --------------------------------------------------------------------------------------------- - - /// Evaluate the transition constraints where the divisors' evaluations are batched to reduce - /// the number of divisions performed (which has a big effect on performance). - /// - /// This algorithm takes advantage of some structure in the divisors' evaluations. Recall that - /// the divisor for the i'th transition constraint is `x^(2^i) - 1`. When substituting `x` for - /// each value of the constraint evaluation domain, for constraints `i>0`, the divisor - /// evaluations "wrap-around" such that some values repeat. For example, - /// i=0: no repetitions - /// i=1: the first half of the buffer is equal to the second half - /// i=2: each 1/4th of the buffer are equal - /// i=3: each 1/8th of the buffer are equal - /// ... - /// Therefore, we only compute the non-repeating section of the buffer in each iteration, and index - /// into it accordingly. - fn evaluate_combined_transition_constraints( - &self, - num_trans_constraints: usize, - lagrange_kernel_column_frames: &[LagrangeKernelEvaluationFrame], - domain: &StarkDomain, - ) -> Vec - where - A: Air, - E: FieldElement, - { - let mut combined_evaluations_acc = E::zeroed_vector(domain.ce_domain_size()); - let mut denominators: Vec = Vec::with_capacity(domain.ce_domain_size()); - - for trans_constraint_idx in 0..num_trans_constraints { - let num_non_repeating_denoms = - domain.ce_domain_size() / 2_usize.pow(trans_constraint_idx as u32); - - for step in 0..num_non_repeating_denoms { - let domain_point = domain.get_ce_x_at(step); - let denominator = self - .lagrange_kernel_constraints - .transition - .evaluate_ith_divisor(trans_constraint_idx, domain_point); - denominators.push(denominator); - } - let denominators_inv = batch_inversion(&denominators); - - for step in 0..domain.ce_domain_size() { - let numerator = self.lagrange_kernel_constraints.transition.evaluate_ith_numerator( - &lagrange_kernel_column_frames[step], - &self.rand_elements, - trans_constraint_idx, - ); - combined_evaluations_acc[step] += - numerator * denominators_inv[step % denominators_inv.len()]; - } - - denominators.truncate(0); - } - - combined_evaluations_acc - } - - /// Evaluate the boundary constraint where the divisors' evaluations are batched to reduce the - /// number of divisions performed (which has a big effect on performance). - fn evaluate_combined_boundary_constraints( - &self, - lagrange_kernel_column_frames: &[LagrangeKernelEvaluationFrame], - domain: &StarkDomain, - ) -> Vec - where - A: Air, - E: FieldElement, - { - let mut boundary_numerator_evals = Vec::with_capacity(domain.ce_domain_size()); - let mut boundary_denominator_evals = Vec::with_capacity(domain.ce_domain_size()); - - for (step, frame) in lagrange_kernel_column_frames.iter().enumerate() { - let domain_point = domain.get_ce_x_at(step); - - { - let boundary_numerator = - self.lagrange_kernel_constraints.boundary.evaluate_numerator_at(frame); - boundary_numerator_evals.push(boundary_numerator); - } - - { - let boundary_denominator = self - .lagrange_kernel_constraints - .boundary - .evaluate_denominator_at(domain_point.into()); - boundary_denominator_evals.push(boundary_denominator); - } - } - - let boundary_denominators_inv = batch_inversion(&boundary_denominator_evals); - - boundary_numerator_evals - .into_iter() - .zip(boundary_denominators_inv) - .map(|(numerator, denom_inv)| numerator * denom_inv) - .collect() - } } -/// Holds all the transition constraint inverse divisor evaluations over the constraint evaluation domain. +/// Holds all the transition constraint inverse divisor evaluations over the constraint evaluation +/// domain. +/// +/// [`LagrangeKernelTransitionConstraintsDivisor`] takes advantage of some structure in the +/// divisors' evaluations. Recall that the divisor for the i'th transition constraint is `x^(2^i) - +/// 1`. When substituting `x` for each value of the constraint evaluation domain, for constraints +/// `i>0`, the divisor evaluations "wrap-around" such that some values repeat. For example, +/// +/// i=0: no repetitions +/// i=1: the first half of the buffer is equal to the second half +/// i=2: each 1/4th of the buffer are equal +/// i=3: each 1/8th of the buffer are equal +/// ... +/// Therefore, we only compute the non-repeating section of the buffer in each iteration, and index +/// into it accordingly. struct LagrangeKernelTransitionConstraintsDivisor { divisor_evals_inv: Vec,