diff --git a/src/expand_n_contract.rs b/src/expand_n_contract.rs index 18c60e58268e50c2480da87a3ca30bf69a0437d5..f16949b784d03f419e6976427381a778c206f8a4 100644 --- a/src/expand_n_contract.rs +++ b/src/expand_n_contract.rs @@ -9,7 +9,7 @@ pub fn expand_n_contract( ) -> Result<(usize, usize, usize), std::io::Error> { let mut cocycle_graphs: Vec<UndirectedGraph> = vec![]; let mut cocycle_graph_index: HashMap<UndirectedGraph, usize> = HashMap::new(); - let mut cocycle_graph_vertex_orbits: Vec<HashMap<usize, usize>> = vec![]; + let mut cocycle_graph_vertex_orbits: Vec<Vec<usize>> = vec![]; let mut cocycle_differential_graphs: Vec<UndirectedGraph> = vec![]; let mut cocycle_differential_graph_index: HashMap<UndirectedGraph, usize> = HashMap::new(); @@ -51,7 +51,7 @@ pub fn expand_n_contract( writeln!(sparse_matrix_file, "{} {} {}", dg_idx + 1, g_idx + 1, c)?; num_nonzeros += 1; - let cg_data: HashMap<UndirectedGraph, HashMap<usize, usize>> = + let cg_data: HashMap<UndirectedGraph, Vec<usize>> = dg.contractions(&dg_edge_orbits); for (cg, cg_vertex_orbits) in cg_data { // eprintln!("{:?}", cg); diff --git a/src/undirected_graph.rs b/src/undirected_graph.rs index a18cab99bed23dcd899b075cd8ad6554c9a86524..b297db669ed36f51cf891ffee3451a031ef4d81b 100644 --- a/src/undirected_graph.rs +++ b/src/undirected_graph.rs @@ -241,10 +241,7 @@ impl UndirectedGraph { } } - pub fn normal_form( - &mut self, - compute_edge_orbits: bool, - ) -> (i32, HashMap<usize, usize>, Vec<usize>) { + pub fn normal_form(&mut self, compute_edge_orbits: bool) -> (i32, Vec<usize>, Vec<usize>) { let mut options: nauty_Traces_sys::optionblk = nauty_Traces_sys::optionblk { getcanon: nauty_Traces_sys::TRUE, userautomproc: Some(Self::process_nauty_automorphism), @@ -295,16 +292,10 @@ impl UndirectedGraph { lab_inv[lab[i] as usize] = i as i32; } - // TODO: Check that passing around hashmaps is not too expensive. - let mut normal_self_orbits: HashMap<usize, usize> = HashMap::new(); - for i in 0..n { - let orbit_rep: usize = lab_inv[orbits[i] as usize] as usize; - if let Some(orbit_size) = normal_self_orbits.get_mut(&orbit_rep) { - *orbit_size += 1; - } else { - normal_self_orbits.insert(orbit_rep, 1); - } - } + let normal_self_orbits: Vec<usize> = orbits + .iter() + .map(|&v| lab_inv[v as usize] as usize) + .collect(); let mut sign: i32 = 1; let mut normal_self_edge_orbits: Vec<usize> = vec![]; @@ -468,11 +459,20 @@ impl UndirectedGraph { pub fn expanding_differential( &self, - orbits: &HashMap<usize, usize>, + orbits: &[usize], ) -> HashMap<UndirectedGraph, (i64, Vec<usize>)> { let mut diff: HashMap<UndirectedGraph, (i64, Vec<usize>)> = HashMap::new(); - for (&orbit_rep, &orbit_size) in orbits { + let mut orbit_reps: HashMap<usize, usize> = HashMap::new(); + for &orbit_rep in orbits { + if let Some(orbit_size) = orbit_reps.get_mut(&orbit_rep) { + *orbit_size += 1; + } else { + orbit_reps.insert(orbit_rep, 1); + } + } + + for (orbit_rep, orbit_size) in orbit_reps { for (c, mut dg) in self.expand_vertex(&orbit_rep) { // TODO: Avoid computing orbits when not used. let (normal_dg_sign, _normal_dg_orbits, normal_dg_edge_orbits) = @@ -493,12 +493,8 @@ impl UndirectedGraph { diff } - pub fn contractions( - &self, - edge_orbits: &Vec<usize>, - ) -> HashMap<UndirectedGraph, HashMap<usize, usize>> { - // TODO: Check that passing around hashmaps is not too expensive. - let mut contractions: HashMap<UndirectedGraph, HashMap<usize, usize>> = HashMap::new(); + pub fn contractions(&self, edge_orbits: &Vec<usize>) -> HashMap<UndirectedGraph, Vec<usize>> { + let mut contractions: HashMap<UndirectedGraph, Vec<usize>> = HashMap::new(); let mut edge_orbit_reps: HashSet<usize> = HashSet::new(); for &edge_orbit_rep in edge_orbits { // Skip orbits already seen.