mod correlated;
mod extract;
mod flooder;
mod graph;
mod matcher;
mod paths;
mod state;
mod tracker;
pub(crate) mod union_find;
#[cfg(test)]
mod correlated_tests;
#[cfg(test)]
mod tests;
pub use correlated::Correlations;
pub(crate) use correlated::FaultEdges;
pub use graph::SparseGraph;
pub use state::Scratch;
pub use union_find::UfScratch;
use crate::dem_decoder::{DecodeError, Prediction};
pub(crate) struct Solver<'a> {
pub(crate) g: &'a SparseGraph,
pub(crate) s: &'a mut Scratch,
}
impl SparseGraph {
pub fn decode(&self, scratch: &mut Scratch, defects: &[u32]) -> Result<Prediction, DecodeError> {
self.check_scratch(scratch);
let mut solver = Solver { g: self, s: scratch };
solver.reset();
solver.run(defects, false)?;
Ok(solver.extract())
}
pub fn decode_with_weights(&self, scratch: &mut Scratch, defects: &[u32], edge_w: &[i64]) -> Result<Prediction, DecodeError> {
self.check_scratch(scratch);
assert_eq!(edge_w.len(), self.num_edges(), "one weight per edge");
for (halves, &wt) in self.halves.iter().zip(edge_w) {
for &slot in halves.iter().filter(|&&h| h != state::NONE) {
scratch.set_weight(slot as usize, wt);
}
}
let mut solver = Solver { g: self, s: scratch };
solver.reset();
let result = solver.run(defects, false).map(|()| solver.extract());
scratch.scan.copy_from_slice(&self.scan);
result
}
pub fn decode_edge_ids_patched(&self, scratch: &mut Scratch, defects: &[u32], patch: &[(u32, i64)]) -> Result<(Prediction, Vec<u32>), DecodeError> {
self.check_scratch(scratch);
for &(id, wt) in patch {
for &slot in self.halves[id as usize].iter().filter(|&&h| h != state::NONE) {
scratch.set_weight(slot as usize, wt);
}
}
let mut solver = Solver { g: self, s: scratch };
let result = solver.pass_one(defects).map(|p| (p, solver.s.edge_set.clone()));
for &(id, _) in patch {
for &slot in self.halves[id as usize].iter().filter(|&&h| h != state::NONE) {
scratch.scan[slot as usize] = self.scan[slot as usize];
}
}
result
}
pub fn decode_to_edges(&self, scratch: &mut Scratch, defects: &[u32]) -> Result<Vec<(u32, u32)>, DecodeError> {
self.check_scratch(scratch);
let mut solver = Solver { g: self, s: scratch };
solver.pass_one(defects)?;
Ok(solver.s.edge_set.iter().map(|&id| self.ends[id as usize]).collect())
}
pub fn decode_pairs(&self, scratch: &mut Scratch, defects: &[u32]) -> Result<(Prediction, Vec<(u32, u32)>), DecodeError> {
self.check_scratch(scratch);
let mut solver = Solver { g: self, s: scratch };
solver.reset();
solver.run(defects, false)?;
let prediction = solver.extract();
let n = self.num_nodes as u32;
Ok((prediction, solver.s.pairs.iter().map(|&(a, b)| (a, if b == state::BOUNDARY { n } else { b })).collect()))
}
pub(crate) fn decode_with_edges(&self, scratch: &mut Scratch, defects: &[u32]) -> Result<(Prediction, Vec<(u32, u32)>), DecodeError> {
self.check_scratch(scratch);
let mut solver = Solver { g: self, s: scratch };
let prediction = solver.pass_one(defects)?;
Ok((prediction, solver.s.edge_set.iter().map(|&id| self.ends[id as usize]).collect()))
}
pub fn decode_with_edge_ids(&self, scratch: &mut Scratch, defects: &[u32]) -> Result<(Prediction, Vec<u32>), DecodeError> {
self.check_scratch(scratch);
let mut solver = Solver { g: self, s: scratch };
let prediction = solver.pass_one(defects)?;
Ok((prediction, solver.s.edge_set.clone()))
}
pub fn decode_edge_ids(&self, scratch: &mut Scratch, defects: &[u32]) -> Result<Vec<u32>, DecodeError> {
self.check_scratch(scratch);
let mut solver = Solver { g: self, s: scratch };
solver.pass_one(defects)?;
Ok(solver.s.edge_set.clone())
}
pub fn decode_correlated_edge_ids(
&self,
corr: &Correlations,
scratch: &mut Scratch,
defects: &[u32],
) -> Result<Vec<u32>, DecodeError> {
self.check_scratch(scratch);
assert_eq!(corr.num_edges(), self.num_edges(), "Correlations serve the graph they were built for");
let mut solver = Solver { g: self, s: scratch };
solver.pass_one(defects)?;
solver.pass_two_edges(corr, defects)?;
Ok(solver.s.edge_set.clone())
}
pub fn decode_correlated(
&self,
corr: &Correlations,
scratch: &mut Scratch,
defects: &[u32],
) -> Result<Prediction, DecodeError> {
self.check_scratch(scratch);
assert_eq!(corr.num_edges(), self.num_edges(), "Correlations serve the graph they were built for");
let mut solver = Solver { g: self, s: scratch };
solver.pass_one(defects)?;
solver.pass_two(corr, defects)
}
pub fn decode_pass2(
&self,
corr: &Correlations,
scratch: &mut Scratch,
defects: &[u32],
edge_ids: &[u32],
) -> Result<Prediction, DecodeError> {
self.check_scratch(scratch);
assert_eq!(corr.num_edges(), self.num_edges(), "Correlations serve the graph they were built for");
let mut solver = Solver { g: self, s: scratch };
solver.s.edge_set.clear();
solver.s.edge_set.extend_from_slice(edge_ids);
solver.pass_two(corr, defects)
}
#[cfg(test)]
pub(crate) fn decode_checked(&self, scratch: &mut Scratch, defects: &[u32]) -> Result<Prediction, DecodeError> {
self.check_scratch(scratch);
let mut solver = Solver { g: self, s: scratch };
solver.reset();
solver.run(defects, true)?;
Ok(solver.extract())
}
}