use crate::cover::OpenCover;
use crate::section::{LocalSection, SectionFamily};
use crate::cochain::compute_cohomology;
#[derive(Debug, Clone, PartialEq)]
pub enum GluingResult {
Success(Vec<f64>),
Failed { h1_dimension: usize },
}
pub fn glue(cover: &OpenCover, sections: &SectionFamily, tol: f64) -> GluingResult {
let (_h0, h1) = compute_cohomology(cover, tol);
if h1.dimension > 0 {
return GluingResult::Failed {
h1_dimension: h1.dimension,
};
}
let universe = cover.universe();
if universe.is_empty() {
return GluingResult::Success(vec![]);
}
let n = *universe.last().unwrap() + 1;
let mut global = vec![f64::NAN; n];
let mut assigned = vec![false; n];
let mut sorted: Vec<&LocalSection> = sections.sections.iter().collect();
sorted.sort_by_key(|s| s.agent_id);
for sec in &sorted {
let set = &cover.sets[sec.agent_id];
for (k, &global_idx) in set.iter().enumerate() {
if global_idx >= n {
continue;
}
if !assigned[global_idx] {
global[global_idx] = sec.data[k];
assigned[global_idx] = true;
}
}
}
for v in &mut global {
if v.is_nan() {
*v = 0.0;
}
}
GluingResult::Success(global)
}
pub fn glue_with_verification(
cover: &OpenCover,
sections: &SectionFamily,
tol: f64,
) -> GluingResult {
let result = glue(cover, sections, tol);
if let GluingResult::Success(ref global) = result {
for sec in §ions.sections {
let set = &cover.sets[sec.agent_id];
for (k, &idx) in set.iter().enumerate() {
if idx < global.len() && (global[idx] - sec.data[k]).abs() > tol {
return GluingResult::Failed { h1_dimension: 1 };
}
}
}
}
result
}