Skip to main content

stwo_gpu/core/poly/circle/
canonic.rs

1use super::CircleDomain;
2use crate::core::circle::{CirclePoint, CirclePointIndex, Coset};
3use crate::core::fields::m31::BaseField;
4
5/// A coset of the form `G_{2n} + <G_n>`, where `G_n` is the generator of the subgroup of order `n`.
6///
7/// The ordering on this coset is `G_2n + i * G_n`.
8/// These cosets can be used as a [`CircleDomain`], and be interpolated on.
9/// Note that this changes the ordering on the coset to be like [`CircleDomain`],
10/// which is `G_{2n} + i * G_{n/2}` and then `-G_{2n} -i * G_{n/2}`.
11/// For example, the `X`s below are a canonic coset with `n=8`.
12///
13/// ```text
14///    X O X
15///  O       O
16/// X         X
17/// O         O
18/// X         X
19///  O       O
20///    X O X
21/// ```
22#[derive(Copy, Clone, Debug, PartialEq, Eq)]
23pub struct CanonicCoset {
24    pub coset: Coset,
25}
26
27impl CanonicCoset {
28    pub fn new(log_size: u32) -> Self {
29        assert!(log_size > 0);
30        Self {
31            coset: Coset::odds(log_size),
32        }
33    }
34
35    /// Gets the full coset represented G_{2n} + <G_n>.
36    pub const fn coset(&self) -> Coset {
37        self.coset
38    }
39
40    /// Gets half of the coset (its conjugate complements to the whole coset), G_{2n} + <G_{n/2}>
41    pub fn half_coset(&self) -> Coset {
42        Coset::half_odds(self.log_size() - 1)
43    }
44
45    /// Gets the [CircleDomain] representing the same point set (in another order).
46    pub fn circle_domain(&self) -> CircleDomain {
47        CircleDomain::new(self.half_coset())
48    }
49
50    /// Returns the log size of the coset.
51    pub const fn log_size(&self) -> u32 {
52        self.coset.log_size
53    }
54
55    /// Returns the size of the coset.
56    pub const fn size(&self) -> usize {
57        self.coset.size()
58    }
59
60    pub const fn initial_index(&self) -> CirclePointIndex {
61        self.coset.initial_index
62    }
63
64    pub const fn step_size(&self) -> CirclePointIndex {
65        self.coset.step_size
66    }
67
68    pub const fn step(&self) -> CirclePoint<BaseField> {
69        self.coset.step
70    }
71
72    pub fn index_at(&self, index: usize) -> CirclePointIndex {
73        self.coset.index_at(index)
74    }
75
76    pub fn at(&self, i: usize) -> CirclePoint<BaseField> {
77        self.coset.at(i)
78    }
79}