use std::ops::Add;
use crate::structs::GeneroGraph;
use crate::traits::HgBasis;
use super::EdgeWeight;
#[derive(Debug, Clone)]
pub struct HgPath<B: HgBasis> {
sites: Vec<B>,
weight: EdgeWeight,
}
impl<B: HgBasis> HgPath<B> {
pub fn new(start: B) -> Self {
HgPath {
sites: vec![start],
weight: 0.0,
}
}
pub fn len(&self) -> usize {
self.sites.len() - 1
}
pub fn last_basis(&self) -> B {
self.sites
.last()
.map(|b| b.clone())
.expect("path should be non-empty.")
}
pub fn first_basis(&self) -> Option<B> {
self.sites.first().map(|b| b.clone())
}
pub fn weight(&self) -> EdgeWeight {
self.weight
}
pub fn extend(self, graph: &GeneroGraph<B>) -> Vec<HgPath<B>> {
if self.sites.len() == 0 {
return Vec::new();
}
let mut ret = Vec::new();
let outputs = graph.map_basis(self.sites.last().expect("Checked for 0 length previously."));
for (new_site, weight) in outputs.to_tuples() {
let mut tmp = self.clone();
tmp.sites.push(new_site);
tmp.weight += weight;
ret.push(tmp);
}
ret
}
}
impl<B: HgBasis> Add<(B, EdgeWeight)> for HgPath<B> {
type Output = HgPath<B>;
fn add(self, rhs: (B, EdgeWeight)) -> Self::Output {
let mut new_sites = self.sites;
new_sites.push(rhs.0);
HgPath {
sites: new_sites,
weight: self.weight + rhs.1,
}
}
}
mod test {
use std::collections::HashSet;
use crate::{structs::HgPath, DGraph, SparseBasis};
#[test]
fn test_simple_extension() {
let mut hg = DGraph::new();
let mut nodes = hg.add_nodes(10);
nodes.sort();
for ix in 0..9 {
hg.create_edge(
&nodes[ix..=ix],
&nodes[ix + 1..=ix + 1],
1.,
crate::EdgeDirection::Directed,
);
}
let p = HgPath::new(SparseBasis::from(HashSet::from([nodes[0]])));
println!("nodes: {:#?}", nodes);
}
}