ext/lib.rs
1//! `ext-rs` is a collection of libraries for doing homological algebra over $\F_p$. The main and
2//! original purpose is to compute Ext of a Steenrod module, but the library is written to be
3//! sufficiently generic to deal with more general applications.
4//!
5//! # Examples
6//!
7//! The library comes with a number of "example" binaries that use the library for various purposes.
8//! These can be used directly to perform specific computations, or act as actual examples for how
9//! to use the library.
10//!
11//! ## Running an example
12//!
13//! An example can be run by executing the command
14//! ```sh
15//! $ cargo run --example EXAMPLE_NAME
16//! ```
17//!
18//! There are various flags that can be useful to supply:
19//!
20//! - `--release` compiles the code in release mode. This increases compilation time, but results
21//! in a much faster binary. This also disables some expensive run-time sanity checks.
22//! - `--no-default-features` disables support for odd primes.
23//! - `--features concurrent` compiles the program with multi-threading support. It defaults to
24//! using all CPU cores, and can be configured via `RAYON_NUM_THREADS`.
25//!
26//! These are supplied right after `cargo run`, in any order. In general, one should set all of
27//! these flags for any non-trivial calculation at the prime 2. See the [Features](#features)
28//! section for other features that can be enabled.
29//!
30//! Each example runs interactively, and prompts the user for input. For example, the following
31//! session computes all filtration one products in $\Ext(C2, \F_2)$ and prints them to `stdout`:
32//!
33//! ```sh
34//! $ cargo run --features concurrent --example filtration_one
35//! Module (default: S_2): C2
36//! Module save directory (optional):
37//! Max n (default: 30): 40
38//! Max s (default: 7): 20
39//! ```
40//! In each line, the text after the final `:` is input by the user.
41//!
42//! In general, we write the output to `stdout` and the prompts to `stderr`. This allows the user to
43//! redirect the output to another file or program.
44//!
45//! ## Prompts and arguments
46//! Each prompt asks the user for an input, which is submitted by pressing the Enter/Return key. If
47//! the input is invalid, an error message is produced and the user is queried for the same input
48//! again. To exit the program early, one sends a `SIGTERM`, e.g. via `Ctrl-C`.
49//!
50//! Some prompts are optional or have default values. To select the `None` or default option, simply
51//! supply an empty input.
52//!
53//! To facilitate batch processing, answers to the prompt can be supplied as command line arguments
54//! instead; the nth command line argument is treated as the answer to the nth prompt. For example,
55//! the previous interaction can be called by
56//! ```sh
57//! $ cargo run --features concurrent --example filtration_one -- C2 "" 2 40 20
58//! ```
59//!
60//! ## Conventions
61//!
62//! ### Module specification
63//! Each Steenrod module is defined in a `json` file, and a collection of such modules are available
64//! in the `steenrod_modules/` subdirectory. New modules can be defined using the
65//! [`define_module`](../define_module/index.html) example.
66//!
67//! Modules are specified using their file names, excluding the `.json` extension. Module files are
68//! searched in the following order:
69//!
70//! 1. The current working directory
71//! 2. The `steenrod_modules/` subdirectory of the current directory
72//! 3. The fixed directory `ext/steenrod_modules/` relative to the repository.
73//!
74//! For example, the module defined by `steenrod_modules/Ceta.json` can be specified with the name
75//! `Ceta`. It is possible to apply a degree shift to the module without having to define a new one.
76//! For example, to shift `Ceta` by one, we supply `Ceta[1]`.
77//!
78//! When resolving a module, we have to pick a basis of the Steenrod algebra, which is either the
79//! Adem basis or the Milnor basis. The default choice is the Milnor basis. We can specify the basis
80//! by appending `@basis_name`. For example, if we want to resolve `Ceta[1]` with the Adem basis, we
81//! can specify it as `Ceta[1]@adem`.
82//!
83//! ### Ext elements
84//! Each Ext group comes with a basis. The ith basis element of $\Ext^{s, n + s}$ is denoted `x_(n,
85//! s, i)`. If we want to specify an element in a particular Ext group, we either write it as a
86//! linear combination of the `x_(n, s, i)`, or written as a vector of the form e.g. `[0, 1, 0]`. In
87//! the latter case, the bidegree is implicit.
88//!
89//! ### Save directory
90//! For most scripts, one can specify a save directory for each module. All save data relating to
91//! the module will be saved in this directory, including resolution data, products, secondary
92//! Steenrod algebra computations etc. For products, the data is saved in the save directory of the
93//! source of the chain map.
94//!
95//! In general, the data for each bidegree (or each generator in some cases) is stored in a separate
96//! file in an appropriate directory. This lets us only load the data we need when doing a
97//! computation, and protects against corruption when the program is terminated halfway through
98//! writing (only the data for said bidegree would be corrupted).
99//!
100//! For products, the subdirectory will be named after the name of the product. One must not reuse a
101//! name for different products; the script may produce and write erroneous results silently in such
102//! cases (though it practice it is likely to hit some error sooner or later).
103//!
104//! If the script is compiled with the `zstd` feature, then it supports reading from zstd compressed
105//! save files, where each save file is individually compressed. The script will first look for the
106//! uncompressed file. If it does not exist, it then looks for the file with the same name but with
107//! a `.zst` extension.
108//!
109//! Note that any new save file will still be written uncompressed. To compress the files, one must
110//! run the `zstd` program on each file in the save directory. It is safe to remove the original
111//! file after compression (i.e. run with the `--rm` option).
112//!
113//! # List of examples
114//! Click on the individual examples for further information.
115//!
116//! | Name | Description |
117//! | --- | --- |
118//! | [algebra_dim](../algebra_dim/index.html) | Print the dimension of the Steenrod algebra in each degree. |
119//! | [bruner](../bruner/index.html) | Compare our basis with Bruner's. |
120//! | [define_module](../define_module/index.html) | Interactively define a Steenrod module. |
121//! | [differentials](../differentials/index.html) | Print all differentials in the minimal resolution. |
122//! | [filtration_one](../filtration_one/index.html) | Print all filtration one products. |
123//! | [lift_hom](../lift_hom/index.html) | Compute the map $\Ext(N, k) \to \Ext(M, k)$ induced by an element in $\Ext(M, N)$. |
124//! | [mahowald_invariant](../mahowald_invariant/index.html) | Compute (algebraic) Mahowald invariants. |
125//! | [massey](../massey/index.html) | Compute Massey products. |
126//! | [num_gens](../num_gens/index.html) | Compute the dimension of Ext in each bidegree. |
127//! | [resolution_size](../resolution_size/index.html) | Compute the size of the minimal resolution in each bidegree |
128//! | [resolve](../resolve/index.html) | Resolve a module to a fixed $(s, t)$ and potentially save the resolution. |
129//! | [resolve_through_stem](../resolve_through_stem/index.html) | Resolve a module to a fixed $(s, n)$ and potentially save the resolution. |
130//! | [save_bruner](../save_bruner/index.html) | Save the resolution in the format used by Bruner's [ext](http://www.rrb.wayne.edu/papers/index.html). |
131//! | [secondary](../secondary/index.html) | Compute $d_2$ differentials using the secondary Steenrod algebra. |
132//! | [secondary_product](../secondary_product/index.html) | Compute products in $\Mod_{C\lambda^2}$ using the secondary Steenrod algebra. |
133//! | [secondary_massey](../secondary_massey/index.html) | Compute Massey products in $\Mod_{C\lambda^2}$ using the secondary Steenrod algebra. |
134//! | [steenrod](../steenrod/index.html) | Compute Steenrod operations in Ext. |
135//! | [tensor](../tensor/index.html) | Compute the tensor product of two modules. |
136//! | [yoneda](../yoneda/index.html) | Compute a Yoneda representative of an Ext class. |
137//!
138//! # Subcrates
139//! This contains a number of sub-crates, which each have their own documentation. A brief overview
140//! is as follows:
141//!
142//! | Name | Description |
143//! | --- | --- |
144//! | [algebra] | This defines algebras, modules and module homomorphisms |
145//! | [bivec] | This is a small crate that provides [`BiVec`](`bivec::BiVec`) - a variant of [`Vec`] indexed by an `i32` whose starting index may be non-zero. |
146//! | [fp] | This implements linear algebra over $\mathbb{F}_p$, as well as general helper functions about primes. |
147//! | [once] | This provides `OnceVec` and `OnceBiVec`, a push-only vector with non-blocking reads. This models some partially computed infinite data structure, and we think of pushing as simply finding out more of this infinite data structure instead of genuinely mutating it. |
148//! | [query] | This contains some helper functions for a command line interface. |
149//!
150//! # Features
151//!
152//! - `odd-primes`: This enables support for odd primes, and is enabled by default. Disabling this
153//! feature offers significant improvements at the prime 2.
154//! - `concurrent`: Use multiple threads for computations. The number of threads used can be
155//! configured via the `RAYON_NUM_THREADS` environment variable.
156//! - `zstd`: Support reading zstd-compressed save files. Note that the save files are still written
157//! uncompressed. If compression is desired, output files need to be compressed manually.
158//! - `cache-multiplication`: Precompute and cache the multiplication table under the Milnor basis.
159//! This is only feasible when using a small, finite subalgebra, e.g. when working with
160//! $\mathrm{tmf}$ modules.
161//! - `logging`: Print timing information of the computations to stderr. Note that this has no
162//! effect unless the `RUST_LOG` environment variable is set appropriately.
163//! - `nassau`: Use Nassau's algorithm to compute the minimal resolution instead of the usual
164//! minimal resolution algorithm. When this feature is enabled, only finite dimensional modules
165//! at the prime 2 can be resolved.
166
167#![allow(clippy::upper_case_acronyms)]
168#![deny(clippy::use_self, unsafe_op_in_unsafe_fn)]
169
170pub mod chain_complex;
171pub mod resolution;
172pub mod resolution_homomorphism;
173pub mod save;
174
175pub mod yoneda;
176
177use algebra::module::SteenrodModule;
178
179use crate::chain_complex::FiniteChainComplex;
180pub type CCC = FiniteChainComplex<SteenrodModule>;
181
182pub mod nassau;
183pub mod secondary;
184pub mod utils;
185
186// Ensure dependencies don't accidentally activate odd primes
187#[cfg(not(feature = "odd-primes"))]
188const _: () = assert!(!fp::ODD_PRIMES);