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