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