diff --git a/src/core/air/evaluation.rs b/src/core/air/evaluation.rs index 9e7f8d36c..cca111d2e 100644 --- a/src/core/air/evaluation.rs +++ b/src/core/air/evaluation.rs @@ -7,7 +7,7 @@ use crate::core::backend::{Backend, CPUBackend, Col, Column}; use crate::core::fields::m31::BaseField; use crate::core::fields::qm31::SecureField; use crate::core::fields::{ExtensionOf, FieldExpOps}; -use crate::core::poly::circle::{CircleDomain, CirclePoly, SecureCirclePoly}; +use crate::core::poly::circle::{CanonicCoset, CirclePoly, SecureCirclePoly}; use crate::core::poly::BitReversedOrder; use crate::core::utils::IteratorMutExt; @@ -169,7 +169,7 @@ impl DomainEvaluationAccumulator { let coeffs = SecureColumn { cols: values.cols.map(|c| { CPUCircleEvaluation::<_, BitReversedOrder>::new( - CircleDomain::constraint_evaluation_domain(log_size as u32), + CanonicCoset::new(log_size as u32).circle_domain(), c, ) .interpolate() @@ -304,12 +304,9 @@ mod tests { let mut res = SecureField::default(); for (log_size, values) in pairs.into_iter() { res = res * alpha - + CPUCircleEvaluation::new( - CircleDomain::constraint_evaluation_domain(log_size), - values, - ) - .interpolate() - .eval_at_point(point); + + CPUCircleEvaluation::new(CanonicCoset::new(log_size).circle_domain(), values) + .interpolate() + .eval_at_point(point); } assert_eq!(accumulator_res, res); diff --git a/src/core/air/mod.rs b/src/core/air/mod.rs index 0f9024585..f90d34d49 100644 --- a/src/core/air/mod.rs +++ b/src/core/air/mod.rs @@ -63,8 +63,7 @@ pub trait Component { /// Returns the degree bounds of each trace column. fn trace_log_degree_bounds(&self) -> Vec; - /// Evaluates the constraint quotients of the component on constraint evaluation domains. - /// See [`super::poly::circle::CircleDomain::constraint_evaluation_domain`]. + /// Evaluates the constraint quotients of the component on the evaluation domain. /// Accumulates quotients in `evaluation_accumulator`. // Note: This will be computed using a MaterializedGraph. fn evaluate_constraint_quotients_on_domain( diff --git a/src/core/backend/avx512/circle.rs b/src/core/backend/avx512/circle.rs index c8e085ff9..72dcf5239 100644 --- a/src/core/backend/avx512/circle.rs +++ b/src/core/backend/avx512/circle.rs @@ -180,7 +180,7 @@ mod tests { use crate::core::backend::avx512::AVX512Backend; use crate::core::backend::Column; use crate::core::fields::m31::BaseField; - use crate::core::poly::circle::{CanonicCoset, CircleDomain, CircleEvaluation, CirclePoly}; + use crate::core::poly::circle::{CanonicCoset, CircleEvaluation, CirclePoly}; use crate::core::poly::{BitReversedOrder, NaturalOrder}; #[test] @@ -203,8 +203,8 @@ mod tests { fn test_eval_extension() { for log_size in MIN_FFT_LOG_SIZE..(CACHED_FFT_LOG_SIZE + 4) { let log_size = log_size as u32; - let domain = CircleDomain::constraint_evaluation_domain(log_size); - let domain_ext = CircleDomain::constraint_evaluation_domain(log_size + 3); + let domain = CanonicCoset::new(log_size).circle_domain(); + let domain_ext = CanonicCoset::new(log_size + 3).circle_domain(); let evaluation = CircleEvaluation::::new( domain, (0..(1 << log_size)) @@ -213,9 +213,10 @@ mod tests { ); let poly = evaluation.clone().interpolate(); let evaluation2 = poly.evaluate(domain_ext); + let poly2 = evaluation2.interpolate(); assert_eq!( - evaluation2.values.to_vec()[..(1 << log_size)], - evaluation.values.to_vec() + poly.extend(log_size + 3).coeffs.to_vec(), + poly2.coeffs.to_vec() ); } } diff --git a/src/core/circle.rs b/src/core/circle.rs index 8c4b1cea6..c0a7b9cf5 100644 --- a/src/core/circle.rs +++ b/src/core/circle.rs @@ -461,26 +461,7 @@ mod tests { use crate::core::circle::{CirclePoint, SECURE_FIELD_CIRCLE_GEN}; use crate::core::fields::qm31::{SecureField, P4}; use crate::core::fields::FieldExpOps; - use crate::core::poly::circle::{CanonicCoset, CircleDomain}; - - #[test] - fn test_domains() { - let log_size = 4; - let canonic_cosets_extensions = [ - CanonicCoset::new(2).evaluation_domain(log_size + 1), - CanonicCoset::new(2).evaluation_domain(log_size + 2), - CanonicCoset::new(log_size - 1).evaluation_domain(log_size), - ]; - - let subgroup_gen = CirclePointIndex::subgroup_gen(log_size); - let constraint_evaluation_domain = CircleDomain::constraint_evaluation_domain(log_size - 1); - - for point_index in constraint_evaluation_domain.iter_indices() { - for eval in &canonic_cosets_extensions { - assert!(eval.find(point_index - subgroup_gen).is_some()); - } - } - } + use crate::core::poly::circle::CanonicCoset; #[test] fn test_iterator() { diff --git a/src/core/poly/circle/canonic.rs b/src/core/poly/circle/canonic.rs index 2e6f37ddc..0e571d51a 100644 --- a/src/core/poly/circle/canonic.rs +++ b/src/core/poly/circle/canonic.rs @@ -45,17 +45,6 @@ impl CanonicCoset { CircleDomain::new(Coset::half_odds(self.coset.log_size - 1)) } - /// Gets a good [CircleDomain] for extension of a poly defined on this coset. - /// The reason the domain looks like this is a bit more intricate, and not covered here. - pub fn evaluation_domain(&self, log_size: u32) -> CircleDomain { - assert!(log_size > self.coset.log_size); - // TODO(spapini): Document why this is like this. - CircleDomain::new(Coset::new( - CirclePointIndex::generator() + CirclePointIndex::subgroup_gen(self.coset.log_size + 1), - log_size - 1, - )) - } - /// Returns the log size of the coset. pub fn log_size(&self) -> u32 { self.coset.log_size diff --git a/src/core/poly/circle/domain.rs b/src/core/poly/circle/domain.rs index 3a69d4611..5dcab4b51 100644 --- a/src/core/poly/circle/domain.rs +++ b/src/core/poly/circle/domain.rs @@ -18,12 +18,6 @@ impl CircleDomain { Self { half_coset } } - /// Constructs a domain for constraint evaluation. - pub fn constraint_evaluation_domain(log_size: u32) -> Self { - assert!(log_size > 0); - CircleDomain::new(Coset::new(CirclePointIndex::generator(), log_size - 1)) - } - pub fn iter(&self) -> CircleDomainIterator { self.half_coset .iter() @@ -106,26 +100,6 @@ mod tests { use crate::core::circle::{CirclePointIndex, Coset}; use crate::core::poly::circle::CanonicCoset; - #[test] - fn test_circle_domain_iterator() { - let domain = CircleDomain::constraint_evaluation_domain(3); - for (i, point) in domain.iter().enumerate() { - if i < 4 { - assert_eq!( - point, - (CirclePointIndex::generator() + CirclePointIndex::subgroup_gen(2) * i) - .to_point() - ); - } else { - assert_eq!( - point, - (-(CirclePointIndex::generator() + CirclePointIndex::subgroup_gen(2) * i)) - .to_point() - ); - } - } - } - #[test] fn is_canonic_invalid_domain() { let half_coset = Coset::new(CirclePointIndex::generator(), 4); diff --git a/src/core/poly/circle/evaluation.rs b/src/core/poly/circle/evaluation.rs index 5c52f953d..1d50559ed 100644 --- a/src/core/poly/circle/evaluation.rs +++ b/src/core/poly/circle/evaluation.rs @@ -154,13 +154,13 @@ mod tests { use crate::core::backend::cpu::CPUCircleEvaluation; use crate::core::circle::Coset; use crate::core::fields::m31::BaseField; - use crate::core::poly::circle::{CanonicCoset, CircleDomain}; + use crate::core::poly::circle::CanonicCoset; use crate::core::poly::NaturalOrder; use crate::m31; #[test] fn test_interpolate_non_canonic() { - let domain = CircleDomain::constraint_evaluation_domain(3); + let domain = CanonicCoset::new(3).circle_domain(); assert_eq!(domain.log_size(), 3); let evaluation = CPUCircleEvaluation::<_, NaturalOrder>::new( domain, diff --git a/src/core/poly/circle/mod.rs b/src/core/poly/circle/mod.rs index a6810f259..639696bae 100644 --- a/src/core/poly/circle/mod.rs +++ b/src/core/poly/circle/mod.rs @@ -14,16 +14,14 @@ pub use secure_poly::{combine_secure_value, SecureCirclePoly}; #[cfg(test)] mod tests { - use super::{CanonicCoset, CircleDomain}; + use super::CanonicCoset; use crate::core::backend::cpu::CPUCircleEvaluation; use crate::core::fields::m31::BaseField; - use crate::core::fields::FieldExpOps; - use crate::core::poly::NaturalOrder; use crate::core::utils::bit_reverse_index; #[test] fn test_interpolate_and_eval() { - let domain = CircleDomain::constraint_evaluation_domain(3); + let domain = CanonicCoset::new(3).circle_domain(); assert_eq!(domain.log_size(), 3); let evaluation = CPUCircleEvaluation::new(domain, (0..8).map(BaseField::from_u32_unchecked).collect()); @@ -32,44 +30,6 @@ mod tests { assert_eq!(evaluation.values, evaluation2.values); } - #[test] - fn test_mixed_degree_example() { - let log_size = 4; - - // Compute domains. - let domain0 = CanonicCoset::new(log_size); - let eval_domain0 = domain0.evaluation_domain(log_size + 4); - let domain1 = CanonicCoset::new(log_size + 2); - let eval_domain1 = domain1.evaluation_domain(log_size + 3); - let constraint_domain = CircleDomain::constraint_evaluation_domain(log_size + 1); - - // Compute values. - let values1: Vec<_> = (0..(domain1.size() as u32)) - .map(BaseField::from_u32_unchecked) - .collect(); - let values0: Vec<_> = values1[1..].iter().step_by(4).map(|x| *x * *x).collect(); - - // Extend. - let trace_eval0 = CPUCircleEvaluation::new_canonical_ordered(domain0, values0); - let eval0 = trace_eval0.interpolate().evaluate(eval_domain0); - let trace_eval1 = CPUCircleEvaluation::new_canonical_ordered(domain1, values1); - let eval1 = trace_eval1.interpolate().evaluate(eval_domain1); - - // Compute constraint. - let constraint_eval = CPUCircleEvaluation::::new( - constraint_domain, - constraint_domain - .iter_indices() - .map(|ind| { - // The constraint is poly0(x+off0)^2 = poly1(x+off1). - eval0.get_at(ind).square() - eval1.get_at(domain1.index_at(1) + ind).square() - }) - .collect(), - ); - // TODO(spapini): Check low degree. - println!("{:?}", constraint_eval); - } - #[test] fn is_canonic_valid_domain() { let canonic_domain = CanonicCoset::new(4).circle_domain(); diff --git a/src/fibonacci/component.rs b/src/fibonacci/component.rs index a1ec44770..77bd89853 100644 --- a/src/fibonacci/component.rs +++ b/src/fibonacci/component.rs @@ -10,7 +10,7 @@ use crate::core::constraints::{coset_vanishing, pair_vanishing}; use crate::core::fields::m31::BaseField; use crate::core::fields::qm31::SecureField; use crate::core::fields::{ExtensionOf, FieldExpOps}; -use crate::core::poly::circle::{CanonicCoset, CircleDomain}; +use crate::core::poly::circle::CanonicCoset; use crate::core::utils::bit_reverse_index; use crate::core::ColumnVec; @@ -85,14 +85,13 @@ impl Component for FibonacciComponent { ) { let poly = &trace.columns[0]; let trace_domain = CanonicCoset::new(self.log_size); - let trace_eval_domain = trace_domain.evaluation_domain(self.log_size + 1); + let trace_eval_domain = CanonicCoset::new(self.log_size + 1).circle_domain(); let trace_eval = poly.evaluate(trace_eval_domain).bit_reverse(); // Step constraint. let constraint_log_degree_bound = trace_domain.log_size() + 1; let [mut accum] = evaluation_accumulator.columns([(constraint_log_degree_bound, 1)]); - let constraint_eval_domain = - CircleDomain::constraint_evaluation_domain(constraint_log_degree_bound); + let constraint_eval_domain = trace_eval_domain; for (off, point_coset) in [ (0, constraint_eval_domain.half_coset), ( @@ -106,25 +105,7 @@ impl Component for FibonacciComponent { let mask = [eval[i], eval[i as isize + mul], eval[i as isize + 2 * mul]]; let res = self.step_constraint_eval_quotient_by_mask(point, &mask); accum.accumulate(bit_reverse_index(i + off, constraint_log_degree_bound), res); - } - } - - // Boundary constraint. - let constraint_log_degree_bound = trace_domain.log_size(); - let [mut accum] = evaluation_accumulator.columns([(constraint_log_degree_bound, 1)]); - let constraint_eval_domain = - CircleDomain::constraint_evaluation_domain(constraint_log_degree_bound); - for (off, point_coset) in [ - (0, constraint_eval_domain.half_coset), - ( - constraint_eval_domain.half_coset.size(), - constraint_eval_domain.half_coset.conjugate(), - ), - ] { - let eval = trace_eval.fetch_eval_on_coset(point_coset.shift(trace_domain.index_at(0))); - for (i, point) in point_coset.iter().enumerate() { - let mask = [eval[i]]; - let res = self.boundary_constraint_eval_quotient_by_mask(point, &mask); + let res = self.boundary_constraint_eval_quotient_by_mask(point, &[mask[0]]); accum.accumulate(bit_reverse_index(i + off, constraint_log_degree_bound), res); } } @@ -146,7 +127,7 @@ impl Component for FibonacciComponent { evaluation_accumulator.accumulate(constraint_log_degree_bound, res); let res = self .boundary_constraint_eval_quotient_by_mask(point, &mask[0][..1].try_into().unwrap()); - let constraint_log_degree_bound = self.log_size; + let constraint_log_degree_bound = self.log_size + 1; evaluation_accumulator.accumulate(constraint_log_degree_bound, res); } }