catlog/stdlib/analyses/ode/
signed_coefficients.rs1use nalgebra::DMatrix;
4
5use std::collections::{BTreeMap, HashMap};
6use std::hash::Hash;
7
8use crate::dbl::model::FgDblModel;
9
10pub struct SignedCoefficientBuilder<ObType, MorType> {
16 var_ob_type: ObType,
17 positive_mor_types: Vec<MorType>,
18 negative_mor_types: Vec<MorType>,
19}
20
21impl<ObType, MorType> SignedCoefficientBuilder<ObType, MorType> {
22 pub fn new(var_ob_type: ObType) -> Self {
24 Self {
25 var_ob_type,
26 positive_mor_types: Vec::new(),
27 negative_mor_types: Vec::new(),
28 }
29 }
30
31 pub fn add_positive(mut self, mor_type: MorType) -> Self {
33 self.positive_mor_types.push(mor_type);
34 self
35 }
36
37 pub fn add_negative(mut self, mor_type: MorType) -> Self {
39 self.negative_mor_types.push(mor_type);
40 self
41 }
42
43 pub fn build_matrix<Id>(
49 &self,
50 model: &impl FgDblModel<ObType = ObType, MorType = MorType, Ob = Id, ObGen = Id, MorGen = Id>,
51 coeffs: &HashMap<Id, f32>,
52 ) -> (DMatrix<f32>, BTreeMap<Id, usize>)
53 where
54 Id: Eq + Clone + Hash + Ord,
55 {
56 let ob_index: BTreeMap<_, _> = model
57 .ob_generators_with_type(&self.var_ob_type)
58 .enumerate()
59 .map(|(i, x)| (x, i))
60 .collect();
61
62 let n = ob_index.len();
63 let mut mat = DMatrix::from_element(n, n, 0.0f32);
64 for mor_type in self.positive_mor_types.iter() {
65 for mor in model.mor_generators_with_type(mor_type) {
66 let i = *ob_index.get(&model.mor_generator_dom(&mor)).unwrap();
67 let j = *ob_index.get(&model.mor_generator_cod(&mor)).unwrap();
68 mat[(j, i)] += coeffs.get(&mor).copied().unwrap_or_default();
69 }
70 }
71 for mor_type in self.negative_mor_types.iter() {
72 for mor in model.mor_generators_with_type(mor_type) {
73 let i = *ob_index.get(&model.mor_generator_dom(&mor)).unwrap();
74 let j = *ob_index.get(&model.mor_generator_cod(&mor)).unwrap();
75 mat[(j, i)] -= coeffs.get(&mor).copied().unwrap_or_default();
76 }
77 }
78
79 (mat, ob_index)
80 }
81}