diff --git a/src/main.rs b/src/main.rs index 5673df18ea838cb4b125d2a9481a28930ff0a681..c8cec4c23213174d696d46c7853ed1bc4fefd153 100644 --- a/src/main.rs +++ b/src/main.rs @@ -46,15 +46,15 @@ fn main() -> std::io::Result<()> { let mut cocycle_differential_graph_edge_orbits: Vec<Vec<usize>> = vec![]; // NOTE: Start with the normal form of the wheel graph. - let wheel_graph: UndirectedGraph = UndirectedGraph::wheel_graph(num_spokes); - let (wheel_graph_sign, wheel_graph_normal, wheel_graph_vertex_orbits, _) = + let mut wheel_graph: UndirectedGraph = UndirectedGraph::wheel_graph(num_spokes); + let (wheel_graph_sign, wheel_graph_vertex_orbits, _) = wheel_graph.normal_form(false); if wheel_graph_sign == 0 { eprintln!("The {}-wheel graph has an automorphism that induces an odd permutation on edges, so it is equal to zero in the graph complex.", num_spokes); process::exit(1); } - cocycle_graphs.push(wheel_graph_normal.clone()); - cocycle_graph_index.insert(wheel_graph_normal.clone(), 0); + cocycle_graphs.push(wheel_graph.clone()); + cocycle_graph_index.insert(wheel_graph, 0); cocycle_graph_vertex_orbits.push(wheel_graph_vertex_orbits); // Write a placeholder for the header. diff --git a/src/undirected_graph.rs b/src/undirected_graph.rs index 4e06b91c392d77f27e8e9ce4aaa308bef948a3b3..b78a280d95b4b748f580625ef59483d7d74e330d 100644 --- a/src/undirected_graph.rs +++ b/src/undirected_graph.rs @@ -83,20 +83,6 @@ impl UndirectedGraph { UndirectedGraph::new(num_spokes + 1, wheel_edges) } - pub fn from_nauty(nauty_graph: &[u64]) -> UndirectedGraph { - // Number of edges = (sum of vertex degrees) / 2. - let num_edges: usize = nauty_graph - .iter() - .map(|&setword| setword.count_ones() as usize) - .sum::<usize>() - >> 1; - UndirectedGraph { - num_vertices: nauty_graph.len(), - num_edges, - nauty_graph: nauty_graph.to_vec(), - } - } - fn induced_edge_permutation( g: &UndirectedGraph, h: &UndirectedGraph, @@ -201,9 +187,9 @@ impl UndirectedGraph { } pub fn normal_form( - &self, + &mut self, compute_edge_orbits: bool, - ) -> (i32, UndirectedGraph, HashMap<usize, usize>, Vec<usize>) { + ) -> (i32, HashMap<usize, 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), @@ -229,7 +215,7 @@ impl UndirectedGraph { unsafe { nauty_Traces_sys::densenauty( - self.nauty_graph.clone().as_mut_ptr(), // TODO: Remove this clone... + self.nauty_graph.as_mut_ptr(), lab.as_mut_ptr(), ptn.as_mut_ptr(), orbits.as_mut_ptr(), @@ -241,7 +227,12 @@ impl UndirectedGraph { ); } - let normal_self: UndirectedGraph = Self::from_nauty(&normal_graph); + // TODO: Avoid the extra struct here? + let normal_self: UndirectedGraph = UndirectedGraph { + num_vertices: self.num_vertices, + num_edges: self.num_edges, + nauty_graph: normal_graph + }; // NOTE: The map k -> lab[k] relabels normal_self to self, so we need the inverse to get the orbits in normal_self. let mut lab_inv: Vec<i32> = vec![0; n]; @@ -282,12 +273,9 @@ impl UndirectedGraph { } }); - ( - sign, - normal_self, - normal_self_orbits, - normal_self_edge_orbits, - ) + self.nauty_graph = normal_self.nauty_graph; + + (sign, normal_self_orbits, normal_self_edge_orbits) } fn expand_vertex(&self, &position: &usize) -> Vec<(i64, UndirectedGraph)> { @@ -425,19 +413,19 @@ impl UndirectedGraph { let mut diff: HashMap<UndirectedGraph, (i64, Vec<usize>)> = HashMap::new(); for (&orbit_rep, &orbit_size) in orbits { - for (c, dg) in self.expand_vertex(&orbit_rep) { + for (c, mut dg) in self.expand_vertex(&orbit_rep) { // TODO: Avoid computing orbits when not used. - let (normal_dg_sign, normal_dg, _normal_dg_orbits, normal_dg_edge_orbits) = + let (normal_dg_sign, _normal_dg_orbits, normal_dg_edge_orbits) = dg.normal_form(true); if normal_dg_sign == 0 { continue; } // TODO: Fix coefficient types. let normal_dg_coeff: i64 = (normal_dg_sign as i64) * (orbit_size as i64) * c; - if let Some((diff_coeff, _)) = diff.get_mut(&normal_dg) { + if let Some((diff_coeff, _)) = diff.get_mut(&dg) { *diff_coeff += normal_dg_coeff; } else { - diff.insert(normal_dg, (normal_dg_coeff, normal_dg_edge_orbits)); + diff.insert(dg, (normal_dg_coeff, normal_dg_edge_orbits)); } } } @@ -518,18 +506,18 @@ impl UndirectedGraph { continue; } - let cg: UndirectedGraph = UndirectedGraph { + let mut cg: UndirectedGraph = UndirectedGraph { num_vertices: self.num_vertices - 1, num_edges: self.num_edges - 1, nauty_graph: contracted_graph, }; - let (normal_cg_sign, normal_cg, normal_cg_orbits, _) = cg.normal_form(false); + let (normal_cg_sign, normal_cg_orbits, _) = cg.normal_form(false); if normal_cg_sign == 0 { continue; } - contractions.insert(normal_cg, normal_cg_orbits); + contractions.insert(cg, normal_cg_orbits); } contractions }