save_bruner/
save_bruner.rs

1//! This saves a resolution to Bruner's format. This saves the resulting files to the current
2//! working directory. It is recommended that you run this in a dedicated subdirectory.
3
4use std::{
5    fmt::Write as _,
6    fs::File,
7    io::{BufWriter, Write as _},
8};
9
10use algebra::{Algebra, AlgebraType, MilnorAlgebra, module::Module};
11use ext::{chain_complex::ChainComplex, utils::query_module};
12use itertools::Itertools;
13
14fn main() -> anyhow::Result<()> {
15    ext::utils::init_logging()?;
16
17    let resolution = query_module(Some(AlgebraType::Milnor), false)?;
18
19    assert_eq!(resolution.prime(), 2);
20    let algebra = resolution.algebra();
21    let algebra: &MilnorAlgebra = algebra.as_ref().try_into()?;
22
23    let mut buffer = String::new();
24
25    for s in 0..resolution.next_homological_degree() {
26        let f = File::create(format!("hDiff.{s}"))?;
27        let mut f = BufWriter::new(f);
28        let module = resolution.module(s);
29        // We don't use this when s = 0
30        let dmodule = resolution.module(s.saturating_sub(1));
31        let min_degree = module.min_degree();
32        let max_degree = module.max_computed_degree();
33        let num_gens: usize = (min_degree..=max_degree)
34            .map(|t| module.number_of_gens_in_degree(t))
35            .sum();
36
37        writeln!(f, "        {num_gens}        {max_degree}\n")?;
38
39        let d = resolution.differential(s);
40        for t in min_degree..=max_degree {
41            for idx in 0..module.number_of_gens_in_degree(t) {
42                writeln!(f, "{t}\n")?;
43
44                if s == 0 {
45                    writeln!(f, "1\n0 0 1 i(0).\n\n\n")?;
46                    continue;
47                }
48                let mut row_count = 0;
49                buffer.clear();
50                let dx = d.output(t, idx);
51
52                let mut gen_count = 0;
53                for gen_deg in min_degree..t {
54                    for gen_idx in 0..dmodule.number_of_gens_in_degree(gen_deg) {
55                        let op_deg = t - gen_deg;
56                        let algebra_dim = algebra.dimension(op_deg);
57                        let start = dmodule.generator_offset(t, gen_deg, gen_idx);
58                        let slice = dx.slice(start, start + algebra_dim);
59                        if slice.is_zero() {
60                            gen_count += 1;
61                            continue;
62                        }
63                        row_count += 1;
64                        write!(buffer, "{gen_count} {op_deg} {algebra_dim} i").unwrap();
65                        for (op_idx, _) in slice.iter_nonzero() {
66                            let elt = algebra.basis_element_from_index(op_deg, op_idx);
67                            write!(buffer, "({:?})", elt.p_part.iter().format(",")).unwrap();
68                        }
69                        writeln!(buffer, ".").unwrap();
70                        gen_count += 1;
71                    }
72                }
73                writeln!(f, "{row_count}")?;
74                writeln!(f, "{buffer}")?; // buffer has one new line, writeln has one new line, add another one.
75            }
76        }
77    }
78
79    Ok(())
80}