Skip to main content

gammalooprs/uv/
spinney.rs

1use std::hash::{Hash, Hasher};
2
3use gammaloop_tracing_filter::LogMessage;
4use linnet::half_edge::{
5    HedgeGraph,
6    subgraph::{Inclusion, InternalSubGraph, SuBitGraph, SubSetLike},
7};
8use tracing::debug;
9
10use crate::{
11    graph::{LMBext, LoopMomentumBasis, cuts::CutSet},
12    uv::{ApproximationType, UltravioletGraph},
13};
14
15#[derive(Clone, Debug, Eq)]
16pub struct Spinney {
17    pub subgraph: InternalSubGraph,
18    components: Vec<SuBitGraph>,
19    pub dod: i32,
20    pub lmb: LoopMomentumBasis,
21    pub renormalization_scheme: ApproximationType,
22    max_comp_loop_count: usize,
23}
24
25impl LogMessage for Spinney {
26    fn log_display(&self) -> String {
27        format!(
28            "Spinney {{ dod: {}, components: {}, max_comp_loop_count: {},subgraph: {} }}",
29            self.dod,
30            self.components.len(),
31            self.max_comp_loop_count,
32            self.subgraph.string_label(),
33        )
34    }
35}
36
37impl Spinney {
38    pub fn compatible_with(&self, cut: &CutSet) -> bool {
39        !self.subgraph.filter.intersects(&cut.union)
40    }
41
42    pub fn empty<E, V, H, G: AsRef<HedgeGraph<E, V, H>> + LMBext + ?Sized>(g: &G) -> Self {
43        Self {
44            subgraph: InternalSubGraph::empty(g.as_ref().n_hedges()),
45            components: vec![],
46            dod: 0,
47            lmb: g.empty_lmb(),
48            renormalization_scheme: ApproximationType::MUV,
49            max_comp_loop_count: 0,
50        }
51    }
52
53    pub fn new<E, V, H, G: UltravioletGraph + AsRef<HedgeGraph<E, V, H>> + ?Sized>(
54        subgraph: InternalSubGraph,
55        g: &G,
56        lmb: &LoopMomentumBasis,
57    ) -> Option<Self> {
58        let dod = g.compute_dod(&subgraph);
59        Self::with_scheme(subgraph, g, lmb, ApproximationType::MUV, dod)
60    }
61
62    pub fn with_scheme<E, V, H, G: UltravioletGraph + AsRef<HedgeGraph<E, V, H>> + ?Sized>(
63        subgraph: InternalSubGraph,
64        g: &G,
65        lmb: &LoopMomentumBasis,
66        renormalization_scheme: ApproximationType,
67        dod: i32,
68    ) -> Option<Self> {
69        let components = g.as_ref().connected_components(&subgraph);
70        let max_comp_loop_count = components
71            .iter()
72            .map(|component| g.as_ref().cyclotomatic_number(component))
73            .max()
74            .unwrap_or(0);
75        let lmb = g
76            .try_compatible_sub_lmb(&subgraph, g.dummy_less_full_crown(&subgraph), lmb)
77            .ok()?;
78
79        if dod < 0 {
80            return None;
81        }
82
83        debug!(
84            dod = %dod,
85            graph = %g.dot_lmb_of(&subgraph,&lmb),
86            renormalization_scheme = %renormalization_scheme,
87            string_label =%subgraph.string_label(),
88            "Constucted spinney with scheme: {:?}",
89            renormalization_scheme
90        );
91
92        Some(Self {
93            components,
94            dod,
95            lmb,
96            subgraph,
97            renormalization_scheme,
98            max_comp_loop_count,
99        })
100    }
101
102    pub fn filter(&self) -> &SuBitGraph {
103        &self.subgraph.filter
104    }
105
106    pub fn max_comp_loop_count(&self) -> usize {
107        self.max_comp_loop_count
108    }
109
110    pub fn n_components(&self) -> usize {
111        self.components.len()
112    }
113}
114
115impl Hash for Spinney {
116    fn hash<H: Hasher>(&self, state: &mut H) {
117        self.subgraph.hash(state);
118    }
119}
120
121impl PartialEq for Spinney {
122    fn eq(&self, other: &Self) -> bool {
123        self.subgraph == other.subgraph
124    }
125}
126
127impl PartialOrd for Spinney {
128    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
129        if self.subgraph == other.subgraph {
130            Some(std::cmp::Ordering::Equal)
131        } else if self.subgraph.includes(&other.subgraph) {
132            Some(std::cmp::Ordering::Greater)
133        } else if other.subgraph.includes(&self.subgraph) {
134            Some(std::cmp::Ordering::Less)
135        } else {
136            None
137        }
138    }
139}