Skip to main content

sva_formula/spectral_sum/
mod.rs

1// Concern: declares SpectralSum and Lane, the canonical form of a closed form | Non-concern: producing one (build.rs) | IO: none
2
3pub mod atom;
4pub mod build;
5pub mod image;
6pub mod merge;
7pub mod product;
8pub mod spread;
9
10use crate::closed_form::{ModalBank, Series, Var};
11use atom::SpectralAtom;
12
13/// The infinite two sit beside the atoms because they carry their own truncation.
14#[derive(Clone, Debug, PartialEq, Default)]
15pub struct Lane {
16    pub atoms: Vec<SpectralAtom>,
17    pub series: Vec<Series>,
18    pub modal: Vec<ModalBank>,
19}
20
21#[derive(Clone, Debug, PartialEq)]
22pub struct SpectralSum {
23    pub var: Var,
24    pub lanes: Vec<Lane>,
25}
26
27impl Lane {
28    pub fn of(atoms: Vec<SpectralAtom>) -> Lane {
29        Lane {
30            atoms,
31            ..Lane::default()
32        }
33    }
34
35    pub fn is_empty(&self) -> bool {
36        self.atoms.is_empty() && self.series.is_empty() && self.modal.is_empty()
37    }
38
39    /// Finitely many atoms is what every product rule is written over.
40    pub fn is_finite_sum(&self) -> bool {
41        self.series.is_empty() && self.modal.is_empty()
42    }
43
44    pub fn expanded(mut self) -> Lane {
45        for bank in std::mem::take(&mut self.modal) {
46            self.atoms
47                .extend(crate::modal::atoms(&bank, crate::origin::Origin::UNKNOWN));
48        }
49        self
50    }
51}
52
53impl SpectralSum {
54    pub fn of(var: Var, lanes: Vec<Lane>) -> SpectralSum {
55        SpectralSum { var, lanes }
56    }
57
58    pub fn mono(var: Var, atoms: Vec<SpectralAtom>) -> SpectralSum {
59        SpectralSum {
60            var,
61            lanes: vec![Lane::of(atoms)],
62        }
63    }
64
65    pub fn width(&self) -> usize {
66        self.lanes.len()
67    }
68
69    pub fn atoms(&self) -> impl Iterator<Item = &SpectralAtom> {
70        self.lanes.iter().flat_map(|l| l.atoms.iter())
71    }
72}