Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions ext/crates/sseq/src/coordinates/bze.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use std::fmt::{self, Display, Formatter};

use fp::matrix::Subquotient;

/// Classification of a spectral sequence generator by its role relative to a differential on a
/// given page. At page $r$, each generator in bidegree $b$ is exactly one of:
///
/// - **B** (boundary): in the image of $d_{r-1}$ from another bidegree.
/// - **Z** (cycle): in the kernel of $d_r$, and not a boundary.
/// - **E** (supports $d_r$): $d_r(x) \neq 0$.
///
/// Every spectral sequence admits this decomposition; the Adams spectral sequence for $S$ at $E_2$
/// has everything as **Z** (degenerate), while $S/\lambda^2$ at $E_3$ has a nontrivial splitting.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum BZE {
/// Boundary: in the image of an incoming differential.
B,
/// Cycle mod boundary: survives to the next page.
Z,
/// Supports a differential: $d_r(x) \neq 0$.
E,
}

impl BZE {
/// Classify generator `idx` from a page's [`Subquotient`].
///
/// The subquotient encodes $E_r = Z_r / B_r$ at a given bidegree:
/// - `page.zeros().pivots()[idx] >= 0` means `idx` is a boundary pivot (**B**).
/// - `page.complement_pivots()` yields generators not in the cycle subspace (**E**).
/// - Everything else is a cycle that is not a boundary (**Z**).
pub fn from_page_data(page: &Subquotient, idx: usize) -> Self {
if page.zeros().pivots()[idx] >= 0 {
return Self::B;
}
if page.complement_pivots().any(|p| p == idx) {
return Self::E;
}
Self::Z
}
}

impl Display for BZE {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self {
Self::B => write!(f, "B"),
Self::Z => write!(f, "Z"),
Self::E => write!(f, "E"),
}
}
}
2 changes: 2 additions & 0 deletions ext/crates/sseq/src/coordinates/mod.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
pub use bze::BZE;
pub use degree::MultiDegree;
pub use element::MultiDegreeElement;
pub use generator::MultiDegreeGenerator;
use maybe_rayon::prelude::*;
use ordered::OrderedMultiDegree;
pub use range::BidegreeRange;

pub mod bze;
pub mod degree;
pub mod element;
pub mod generator;
Expand Down
50 changes: 49 additions & 1 deletion ext/crates/sseq/src/sseq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ use fp::{
use once::MultiIndexed;

use crate::{
coordinates::{Bidegree, BidegreeGenerator, degree::MultiDegree, element::MultiDegreeElement},
coordinates::{
BZE, Bidegree, BidegreeGenerator, degree::MultiDegree, element::MultiDegreeElement,
},
differential::Differential,
};

Expand Down Expand Up @@ -39,6 +41,28 @@ impl SseqProfile<2> for Adams {
}
}

/// Trigraded Adams profile for S/λ². Coordinates are `(n, s, b)` = (stem, Adams filtration,
/// Bockstein degree). The d₂ differential maps `(n, s, b) → (n − 1, s + 2, b + 1)`.
pub struct AdamsLambda2;

impl SseqProfile<3> for AdamsLambda2 {
const MIN_R: i32 = 2;

fn profile(r: i32, b: MultiDegree<3>) -> MultiDegree<3> {
let [n, s, bock] = b.coords();
MultiDegree::new([n - 1, s + r, bock + 1])
}

fn profile_inverse(r: i32, b: MultiDegree<3>) -> MultiDegree<3> {
let [n, s, bock] = b.coords();
MultiDegree::new([n + 1, s - r, bock - 1])
}

fn differential_length(offset: MultiDegree<3>) -> i32 {
offset.coords()[1]
}
}

pub struct Product<const N: usize> {
pub b: MultiDegree<N>,
/// Whether the product acts on the left or not. This affects the sign in the Leibniz rule.
Expand Down Expand Up @@ -368,6 +392,30 @@ impl<const N: usize, P: SseqProfile<N>> Sseq<N, P> {
&self.data[b].page_data
}

/// Classify generator `i` at degree `b` on page `r` as B (boundary), Z (cycle), or E
/// (supports a differential). Panics if the degree or page is not defined.
pub fn classify(&self, b: MultiDegree<N>, r: i32, i: usize) -> BZE {
let pd = &self.data[b].page_data;
let page = &pd[std::cmp::min(r, pd.len() - 1)];
BZE::from_page_data(page, i)
}

/// The B, Z, E generator indices at degree `b` on page `r`.
pub fn bze_indices(&self, b: MultiDegree<N>, r: i32) -> (Vec<usize>, Vec<usize>, Vec<usize>) {
let dim = self.data[b].dimension;
let mut bs = Vec::new();
let mut zs = Vec::new();
let mut es = Vec::new();
for i in 0..dim {
match self.classify(b, r, i) {
BZE::B => bs.push(i),
BZE::Z => zs.push(i),
BZE::E => es.push(i),
}
}
(bs, zs, es)
}

/// Compute the product between `product` and the class `class`. Returns `None` if
/// the product is not yet computed.
pub fn multiply(
Expand Down
22 changes: 11 additions & 11 deletions ext/examples/benchmarks/secondary-C2
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
secondary -- C2 "" 30 7 ""
d_2 x_(9, 2, 0) = [0]
d_2 x_(10, 3, 0) = [0]
d_2 x_(17, 3, 0) = [0]
d_2 x_(17, 4, 0) = [1]
d_2 x_(18, 2, 0) = [0]
d_2 x_(18, 4, 0) = [0]
d_2 x_(19, 5, 0) = [1]
d_2 x_(20, 3, 0) = [0]
d_2 x_(22, 3, 0) = [0]
d_2 x_(22, 4, 0) = [0]
d_2 x_(24, 5, 0) = [0]
Z x_(9, 2, 0)
Z x_(10, 3, 0)
Z x_(17, 3, 0)
E d_2 x_(17, 4, 0) = [1]
Z x_(18, 2, 0)
Z x_(18, 4, 0)
E d_2 x_(19, 5, 0) = [1]
Z x_(20, 3, 0)
Z x_(22, 3, 0)
Z x_(22, 4, 0)
Z x_(24, 5, 0)
22 changes: 11 additions & 11 deletions ext/examples/benchmarks/secondary-C2-nassau
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
secondary -- C2 /tmp/test_nassau_c2 30 7 ""
d_2 x_(9, 2, 0) = [0]
d_2 x_(10, 3, 0) = [0]
d_2 x_(17, 3, 0) = [0]
d_2 x_(17, 4, 0) = [1]
d_2 x_(18, 2, 0) = [0]
d_2 x_(18, 4, 0) = [0]
d_2 x_(19, 5, 0) = [1]
d_2 x_(20, 3, 0) = [0]
d_2 x_(22, 3, 0) = [0]
d_2 x_(22, 4, 0) = [0]
d_2 x_(24, 5, 0) = [0]
Z x_(9, 2, 0)
Z x_(10, 3, 0)
Z x_(17, 3, 0)
E d_2 x_(17, 4, 0) = [1]
Z x_(18, 2, 0)
Z x_(18, 4, 0)
E d_2 x_(19, 5, 0) = [1]
Z x_(20, 3, 0)
Z x_(22, 3, 0)
Z x_(22, 4, 0)
Z x_(24, 5, 0)
36 changes: 18 additions & 18 deletions ext/examples/benchmarks/secondary-S_2
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
secondary -- S_2 "" 30 7 ""
d_2 x_(1, 1, 0) = [0]
d_2 x_(8, 2, 0) = [0]
d_2 x_(15, 1, 0) = [1]
d_2 x_(15, 2, 0) = [0]
d_2 x_(15, 3, 0) = [0]
d_2 x_(15, 4, 0) = [0]
d_2 x_(16, 2, 0) = [0]
d_2 x_(17, 4, 0) = [1]
d_2 x_(17, 5, 0) = [0]
d_2 x_(18, 2, 0) = [0]
d_2 x_(18, 3, 0) = [0]
d_2 x_(18, 4, 0) = [0]
d_2 x_(18, 4, 1) = [1]
d_2 x_(18, 5, 0) = [1]
d_2 x_(19, 3, 0) = [0]
d_2 x_(21, 3, 0) = [0]
d_2 x_(24, 5, 0) = [0]
d_2 x_(30, 5, 0) = [0]
Z x_(1, 1, 0)
Z x_(8, 2, 0)
E d_2 x_(15, 1, 0) = [1]
Z x_(15, 2, 0)
Z x_(15, 3, 0)
Z x_(15, 4, 0)
Z x_(16, 2, 0)
E d_2 x_(17, 4, 0) = [1]
Z x_(17, 5, 0)
Z x_(18, 2, 0)
Z x_(18, 3, 0)
Z x_(18, 4, 0)
E d_2 x_(18, 4, 1) = [1]
E d_2 x_(18, 5, 0) = [1]
Z x_(19, 3, 0)
Z x_(21, 3, 0)
Z x_(24, 5, 0)
Z x_(30, 5, 0)
24 changes: 12 additions & 12 deletions ext/examples/benchmarks/secondary-tmf
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
secondary -- A-mod-Sq1-Sq2-Sq4 "" 30 7 ""
d_2 x_(1, 1, 0) = [0]
d_2 x_(9, 4, 0) = [0]
d_2 x_(9, 5, 0) = [0]
d_2 x_(12, 3, 0) = [1]
d_2 x_(12, 4, 0) = [1]
d_2 x_(12, 5, 0) = [1]
d_2 x_(15, 3, 0) = [1]
d_2 x_(15, 4, 0) = [1]
d_2 x_(17, 5, 0) = [0]
d_2 x_(18, 4, 0) = [1]
d_2 x_(21, 5, 0) = [0]
d_2 x_(25, 5, 0) = [0]
Z x_(1, 1, 0)
Z x_(9, 4, 0)
Z x_(9, 5, 0)
E d_2 x_(12, 3, 0) = [1]
E d_2 x_(12, 4, 0) = [1]
E d_2 x_(12, 5, 0) = [1]
E d_2 x_(15, 3, 0) = [1]
E d_2 x_(15, 4, 0) = [1]
Z x_(17, 5, 0)
E d_2 x_(18, 4, 0) = [1]
Z x_(21, 5, 0)
Z x_(25, 5, 0)
74 changes: 37 additions & 37 deletions ext/examples/benchmarks/secondary_product-h_0-S_2
Original file line number Diff line number Diff line change
@@ -1,38 +1,38 @@
secondary_product -- S_2 "" 30 7 h_0 0 1 [1]
[h_0] [x_(0, 0, 0)] = [1] + λ [0]
[h_0] [x_(0, 1, 0)] = [1] + λ [1]
[h_0] [x_(0, 2, 0)] = [1] + λ [0]
[h_0] [x_(0, 3, 0)] = [1] + λ [1]
[h_0] [x_(0, 4, 0)] = [1] + λ [0]
[h_0] [x_(0, 5, 0)] = [1] + λ [1]
[h_0] [x_(3, 1, 0)] = [1] + λ [1]
[h_0] [x_(3, 2, 0)] = [1] + λ []
[h_0] [x_(7, 1, 0)] = [1] + λ [0]
[h_0] [x_(7, 2, 0)] = [1] + λ [1]
[h_0] [x_(7, 3, 0)] = [1] + λ []
[h_0] [x_(8, 2, 0)] = [0] + λ []
[h_0] [x_(9, 3, 0)] = [0] + λ [0]
[h_0] [x_(9, 4, 0)] = [0] + λ []
[h_0] [x_(11, 5, 0)] = [1] + λ [1]
[h_0] [x_(14, 2, 0)] = [1] + λ [1]
[h_0] [x_(14, 3, 0)] = [0] + λ [0]
[h_0] [x_(14, 4, 0)] = [1] + λ [1]
[h_0] [x_(14, 5, 0)] = [1] + λ []
[h_0] λ x_(15, 1, 0) = λ [1]
[h_0] [x_(15, 2, 0)] = [1] + λ [1]
[h_0] [x_(15, 3, 0)] = [1] + λ [0, 0]
[h_0] [x_(15, 4, 0)] = [1, 0] + λ [1]
[h_0] [x_(15, 5, 0)] = [1] + λ [0]
[h_0] [x_(15, 5, 1)] = [0] + λ [0]
[h_0] [x_(17, 3, 0)] = [0] + λ [0]
[h_0] λ x_(17, 4, 0) = λ [1]
[h_0] [x_(17, 5, 0)] = [1] + λ [0]
[h_0] [x_(18, 2, 0)] = [1] + λ [1, 1]
[h_0] [x_(18, 3, 0)] = [1, 0] + λ [1]
[h_0] λ x_(18, 4, 1) = λ [1]
[h_0] [x_(18, 4, 0)] = [0] + λ []
[h_0] [x_(20, 4, 0)] = [1] + λ [0]
[h_0] [x_(20, 5, 0)] = [1] + λ []
[h_0] [x_(21, 3, 0)] = [] + λ [0]
[h_0] [x_(23, 4, 0)] = [0] + λ [0]
[h_0] [x_(23, 5, 0)] = [1] + λ [0]
Z [h_0] [x_(0, 0, 0)] = [x_(0, 1, 0)]
Z [h_0] [x_(0, 1, 0)] = [x_(0, 2, 0)] + λx_(0, 3, 0)
Z [h_0] [x_(0, 2, 0)] = [x_(0, 3, 0)]
Z [h_0] [x_(0, 3, 0)] = [x_(0, 4, 0)] + λx_(0, 5, 0)
Z [h_0] [x_(0, 4, 0)] = [x_(0, 5, 0)]
Z [h_0] [x_(0, 5, 0)] = [x_(0, 6, 0)] + λx_(0, 7, 0)
Z [h_0] [x_(3, 1, 0)] = [x_(3, 2, 0)] + λx_(3, 3, 0)
Z [h_0] [x_(3, 2, 0)] = [x_(3, 3, 0)]
Z [h_0] [x_(7, 1, 0)] = [x_(7, 2, 0)]
Z [h_0] [x_(7, 2, 0)] = [x_(7, 3, 0)] + λx_(7, 4, 0)
Z [h_0] [x_(7, 3, 0)] = [x_(7, 4, 0)]
Z [h_0] [x_(8, 2, 0)] = 0
Z [h_0] [x_(9, 3, 0)] = 0
Z [h_0] [x_(9, 4, 0)] = 0
Z [h_0] [x_(11, 5, 0)] = [x_(11, 6, 0)] + λx_(11, 7, 0)
Z [h_0] [x_(14, 2, 0)] = [x_(14, 3, 0)] + λx_(14, 4, 0)
B [h_0] [x_(14, 3, 0)] = 0
Z [h_0] [x_(14, 4, 0)] = [x_(14, 5, 0)] + λx_(14, 6, 0)
Z [h_0] [x_(14, 5, 0)] = [x_(14, 6, 0)]
E [h_0] λ x_(15, 1, 0) = λ [1]
Z [h_0] [x_(15, 2, 0)] = [x_(15, 3, 0)] + λx_(15, 4, 0)
Z [h_0] [x_(15, 3, 0)] = [x_(15, 4, 0)]
Z [h_0] [x_(15, 4, 0)] = [x_(15, 5, 0)] + λx_(15, 6, 0)
Z [h_0] [x_(15, 5, 0)] = [x_(15, 6, 0)]
Z [h_0] [x_(15, 5, 1)] = 0
Z [h_0] [x_(17, 3, 0)] = 0
E [h_0] λ x_(17, 4, 0) = λ [1]
Z [h_0] [x_(17, 5, 0)] = [x_(17, 6, 0)]
Z [h_0] [x_(18, 2, 0)] = [x_(18, 3, 0)] + λ(x_(18, 4, 0) + x_(18, 4, 1))
Z [h_0] [x_(18, 3, 0)] = [x_(18, 4, 0)] + λx_(18, 5, 0)
E [h_0] λ x_(18, 4, 1) = λ [1]
Z [h_0] [x_(18, 4, 0)] = 0
Z [h_0] [x_(20, 4, 0)] = [x_(20, 5, 0)]
Z [h_0] [x_(20, 5, 0)] = [x_(20, 6, 0)]
Z [h_0] [x_(21, 3, 0)] = 0
Z [h_0] [x_(23, 4, 0)] = 0
Z [h_0] [x_(23, 5, 0)] = [x_(23, 6, 0)]
74 changes: 37 additions & 37 deletions ext/examples/benchmarks/secondary_product-h_0-S_2-nassau
Original file line number Diff line number Diff line change
@@ -1,38 +1,38 @@
secondary_product -- S_2 /tmp/test_nassau_s_2 30 7 h_0 0 1 [1]
[h_0] [x_(0, 0, 0)] = [1] + λ [0]
[h_0] [x_(0, 1, 0)] = [1] + λ [1]
[h_0] [x_(0, 2, 0)] = [1] + λ [0]
[h_0] [x_(0, 3, 0)] = [1] + λ [1]
[h_0] [x_(0, 4, 0)] = [1] + λ [0]
[h_0] [x_(0, 5, 0)] = [1] + λ [1]
[h_0] [x_(3, 1, 0)] = [1] + λ [1]
[h_0] [x_(3, 2, 0)] = [1] + λ []
[h_0] [x_(7, 1, 0)] = [1] + λ [0]
[h_0] [x_(7, 2, 0)] = [1] + λ [1]
[h_0] [x_(7, 3, 0)] = [1] + λ []
[h_0] [x_(8, 2, 0)] = [0] + λ []
[h_0] [x_(9, 3, 0)] = [0] + λ [0]
[h_0] [x_(9, 4, 0)] = [0] + λ []
[h_0] [x_(11, 5, 0)] = [1] + λ [1]
[h_0] [x_(14, 2, 0)] = [1] + λ [0]
[h_0] [x_(14, 3, 0)] = [0] + λ [1]
[h_0] [x_(14, 4, 0)] = [1] + λ [0]
[h_0] [x_(14, 5, 0)] = [1] + λ []
[h_0] λ x_(15, 1, 0) = λ [1]
[h_0] [x_(15, 2, 0)] = [1] + λ [1]
[h_0] [x_(15, 3, 0)] = [1] + λ [0, 0]
[h_0] [x_(15, 4, 0)] = [1, 0] + λ [1]
[h_0] [x_(15, 5, 0)] = [1] + λ [0]
[h_0] [x_(15, 5, 1)] = [0] + λ [0]
[h_0] [x_(17, 3, 0)] = [0] + λ [0]
[h_0] λ x_(17, 4, 0) = λ [1]
[h_0] [x_(17, 5, 0)] = [1] + λ [0]
[h_0] [x_(18, 2, 0)] = [1] + λ [1, 0]
[h_0] [x_(18, 3, 0)] = [1, 0] + λ [0]
[h_0] λ x_(18, 4, 1) = λ [1]
[h_0] [x_(18, 4, 0)] = [0] + λ []
[h_0] [x_(20, 4, 0)] = [1] + λ [1]
[h_0] [x_(20, 5, 0)] = [1] + λ []
[h_0] [x_(21, 3, 0)] = [] + λ [0]
[h_0] [x_(23, 4, 0)] = [0] + λ [0]
[h_0] [x_(23, 5, 0)] = [1] + λ [0]
Z [h_0] [x_(0, 0, 0)] = [x_(0, 1, 0)]
Z [h_0] [x_(0, 1, 0)] = [x_(0, 2, 0)] + λx_(0, 3, 0)
Z [h_0] [x_(0, 2, 0)] = [x_(0, 3, 0)]
Z [h_0] [x_(0, 3, 0)] = [x_(0, 4, 0)] + λx_(0, 5, 0)
Z [h_0] [x_(0, 4, 0)] = [x_(0, 5, 0)]
Z [h_0] [x_(0, 5, 0)] = [x_(0, 6, 0)] + λx_(0, 7, 0)
Z [h_0] [x_(3, 1, 0)] = [x_(3, 2, 0)] + λx_(3, 3, 0)
Z [h_0] [x_(3, 2, 0)] = [x_(3, 3, 0)]
Z [h_0] [x_(7, 1, 0)] = [x_(7, 2, 0)]
Z [h_0] [x_(7, 2, 0)] = [x_(7, 3, 0)] + λx_(7, 4, 0)
Z [h_0] [x_(7, 3, 0)] = [x_(7, 4, 0)]
Z [h_0] [x_(8, 2, 0)] = 0
Z [h_0] [x_(9, 3, 0)] = 0
Z [h_0] [x_(9, 4, 0)] = 0
Z [h_0] [x_(11, 5, 0)] = [x_(11, 6, 0)] + λx_(11, 7, 0)
Z [h_0] [x_(14, 2, 0)] = [x_(14, 3, 0)]
B [h_0] [x_(14, 3, 0)] = λx_(14, 5, 0)
Z [h_0] [x_(14, 4, 0)] = [x_(14, 5, 0)]
Z [h_0] [x_(14, 5, 0)] = [x_(14, 6, 0)]
E [h_0] λ x_(15, 1, 0) = λ [1]
Z [h_0] [x_(15, 2, 0)] = [x_(15, 3, 0)] + λx_(15, 4, 0)
Z [h_0] [x_(15, 3, 0)] = [x_(15, 4, 0)]
Z [h_0] [x_(15, 4, 0)] = [x_(15, 5, 0)] + λx_(15, 6, 0)
Z [h_0] [x_(15, 5, 0)] = [x_(15, 6, 0)]
Z [h_0] [x_(15, 5, 1)] = 0
Z [h_0] [x_(17, 3, 0)] = 0
E [h_0] λ x_(17, 4, 0) = λ [1]
Z [h_0] [x_(17, 5, 0)] = [x_(17, 6, 0)]
Z [h_0] [x_(18, 2, 0)] = [x_(18, 3, 0)] + λx_(18, 4, 0)
Z [h_0] [x_(18, 3, 0)] = [x_(18, 4, 0)]
E [h_0] λ x_(18, 4, 1) = λ [1]
Z [h_0] [x_(18, 4, 0)] = 0
Z [h_0] [x_(20, 4, 0)] = [x_(20, 5, 0)] + λx_(20, 6, 0)
Z [h_0] [x_(20, 5, 0)] = [x_(20, 6, 0)]
Z [h_0] [x_(21, 3, 0)] = 0
Z [h_0] [x_(23, 4, 0)] = 0
Z [h_0] [x_(23, 5, 0)] = [x_(23, 6, 0)]
Loading
Loading