Skip to content

Commit

Permalink
Use only canonic domains
Browse files Browse the repository at this point in the history
  • Loading branch information
spapinistarkware committed Mar 19, 2024
1 parent 4cf635a commit 6c0f065
Show file tree
Hide file tree
Showing 9 changed files with 22 additions and 140 deletions.
13 changes: 5 additions & 8 deletions src/core/air/evaluation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -169,7 +169,7 @@ impl DomainEvaluationAccumulator<CPUBackend> {
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()
Expand Down Expand Up @@ -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);
Expand Down
3 changes: 1 addition & 2 deletions src/core/air/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,7 @@ pub trait Component<B: Backend> {
/// Returns the degree bounds of each trace column.
fn trace_log_degree_bounds(&self) -> Vec<u32>;

/// 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(
Expand Down
11 changes: 6 additions & 5 deletions src/core/backend/avx512/circle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand All @@ -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::<AVX512Backend, _, BitReversedOrder>::new(
domain,
(0..(1 << log_size))
Expand All @@ -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()
);
}
}
Expand Down
21 changes: 1 addition & 20 deletions src/core/circle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
11 changes: 0 additions & 11 deletions src/core/poly/circle/canonic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
26 changes: 0 additions & 26 deletions src/core/poly/circle/domain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions src/core/poly/circle/evaluation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
44 changes: 2 additions & 42 deletions src/core/poly/circle/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand All @@ -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::<BaseField, NaturalOrder>::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();
Expand Down
29 changes: 5 additions & 24 deletions src/fibonacci/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -85,14 +85,13 @@ impl Component<CPUBackend> 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),
(
Expand All @@ -106,25 +105,7 @@ impl Component<CPUBackend> 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);
}
}
Expand All @@ -146,7 +127,7 @@ impl Component<CPUBackend> 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);
}
}

0 comments on commit 6c0f065

Please sign in to comment.