diff --git a/src/expand_n_contract.rs b/src/expand_n_contract.rs index a043c718cf4e13fa910438677939c4ae2e56fc85..7241a11edead3cf49c15d257c07302a3fe744d80 100644 --- a/src/expand_n_contract.rs +++ b/src/expand_n_contract.rs @@ -5,8 +5,42 @@ use std::io::{Seek, Write}; pub fn expand_n_contract( num_spokes: usize, - sparse_matrix_file: &mut File, + cocycle_graphs_filename: &String, + cocycle_differential_graphs_filename: &String, + cocycle_differential_matrix_filename: &String, ) -> Result<(usize, usize, usize), std::io::Error> { + // TODO: Avoid overwriting existing files. + + let cocycle_graphs_file_res: Result<File, std::io::Error> = + File::create(cocycle_graphs_filename); + if cocycle_graphs_file_res.is_err() { + eprintln!("Error opening file: {}", cocycle_graphs_filename); + std::process::exit(1); + } + let mut cocycle_graphs_file: File = cocycle_graphs_file_res.unwrap(); + + let cocycle_differential_graphs_file_res: Result<File, std::io::Error> = + File::create(cocycle_differential_graphs_filename); + if cocycle_differential_graphs_file_res.is_err() { + eprintln!( + "Error opening file: {}", + cocycle_differential_graphs_filename + ); + std::process::exit(1); + } + let mut cocycle_differential_graphs_file: File = cocycle_differential_graphs_file_res.unwrap(); + + let cocycle_differential_matrix_file_res: Result<File, std::io::Error> = + File::create(cocycle_differential_matrix_filename); + if cocycle_differential_matrix_file_res.is_err() { + eprintln!( + "Error opening file: {}", + cocycle_differential_matrix_filename + ); + std::process::exit(1); + } + let mut cocycle_differential_matrix_file: File = cocycle_differential_matrix_file_res.unwrap(); + let mut cocycle_graphs: Vec<UndirectedGraph> = vec![]; let mut cocycle_graph_index: HashMap<UndirectedGraph, usize> = HashMap::new(); let mut cocycle_graph_vertex_orbits: Vec<Vec<usize>> = vec![]; @@ -20,12 +54,18 @@ pub fn expand_n_contract( let (wheel_graph_sign, wheel_graph_vertex_orbits) = wheel_graph.normal_form(false); assert!(wheel_graph_sign != 0); cocycle_graphs.push(wheel_graph.clone()); - cocycle_graph_index.insert(wheel_graph, 0); + cocycle_graph_index.insert(wheel_graph.clone(), 0); cocycle_graph_vertex_orbits.push(wheel_graph_vertex_orbits); + writeln!(cocycle_graphs_file, "{}", wheel_graph.to_graph6())?; + // Write a placeholder for the header. let header_line_length: usize = 64; - writeln!(sparse_matrix_file, "{}", "x".repeat(header_line_length))?; + writeln!( + cocycle_differential_matrix_file, + "{}", + "x".repeat(header_line_length) + )?; let mut num_nonzeros: usize = 0; let mut g_idx: usize = 0; @@ -45,10 +85,17 @@ pub fn expand_n_contract( cocycle_differential_graphs.push(dg.clone()); cocycle_differential_graph_edge_orbits.push(dg_edge_orbits.clone()); cocycle_differential_graph_index.insert(dg.clone(), idx); + writeln!(cocycle_differential_graphs_file, "{}", dg.to_graph6())?; idx }; // TODO: Make the output lexicographically ordered? Strictly speaking this is not the SMS format right now. - writeln!(sparse_matrix_file, "{} {} {}", dg_idx + 1, g_idx + 1, c)?; + writeln!( + cocycle_differential_matrix_file, + "{} {} {}", + dg_idx + 1, + g_idx + 1, + c + )?; num_nonzeros += 1; let cg_data: Vec<(UndirectedGraph, Vec<usize>)> = dg.contractions(&dg_edge_orbits); @@ -60,6 +107,7 @@ pub fn expand_n_contract( cocycle_graphs.push(cg.clone()); cocycle_graph_vertex_orbits.push(cg_vertex_orbits); cocycle_graph_index.insert(cg.clone(), idx); + writeln!(cocycle_graphs_file, "{}", cg.to_graph6())?; } } } @@ -69,17 +117,15 @@ pub fn expand_n_contract( break; } } - writeln!(sparse_matrix_file, "0 0 0")?; - sparse_matrix_file.rewind()?; + writeln!(cocycle_differential_matrix_file, "0 0 0")?; + cocycle_differential_matrix_file.rewind()?; let mut header_line: String = format!( "{} {} M", cocycle_differential_graphs.len(), cocycle_graphs.len() ); header_line += &" ".repeat(header_line_length - header_line.len()); - writeln!(sparse_matrix_file, "{}", header_line)?; - - // TODO: Also output the ordered bases of graphs. + writeln!(cocycle_differential_matrix_file, "{}", header_line)?; Ok(( cocycle_differential_graphs.len(), diff --git a/src/main.rs b/src/main.rs index c7833078877077df059aea003b78a661c77bc6f2..1faa8acafbd367b6a393c1771ef15137ac959ca6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,16 +2,22 @@ mod expand_n_contract; mod expand_n_contract_sqlite; mod undirected_graph; use std::env; -use std::fs::File; use std::process; fn main() -> std::io::Result<()> { let args: Vec<String> = env::args().collect(); + let num_args: usize = args.len(); - if args.len() != 3 { + const NUM_ARGS_FOR_DB: usize = 3; + const NUM_ARGS_FOR_TXT: usize = 5; + + if num_args != NUM_ARGS_FOR_DB && num_args != NUM_ARGS_FOR_TXT { eprintln!( - "Usage: {} <number-of-spokes-in-wheel> <output-filename.txt | output-filename.db>", - args[0] + "Usage:\n\ + \x20 {} <number-of-spokes-in-wheel> <output-filename.db>\n\ + or\n\ + \x20 {} <number-of-spokes-in-wheel> <cocycle-graphs.txt> <cocycle-differential-graphs.txt> <cocycle-differential-matrix.txt>", + args[0], args[0] ); process::exit(1); } @@ -33,9 +39,9 @@ fn main() -> std::io::Result<()> { process::exit(1); } - let filename: &String = &args[2]; + if num_args == NUM_ARGS_FOR_DB { + let filename: &String = &args[2]; - if filename.ends_with(".db") { let result: Result<(usize, usize, usize), rusqlite::Error> = expand_n_contract_sqlite::expand_n_contract(num_spokes, filename); @@ -55,16 +61,18 @@ fn main() -> std::io::Result<()> { )) } } - } else if filename.ends_with(".txt") { - let sparse_matrix_file_res: Result<File, std::io::Error> = File::create(filename); - if sparse_matrix_file_res.is_err() { - eprintln!("Error opening file: {}", filename); - process::exit(1); - } - let mut sparse_matrix_file: File = sparse_matrix_file_res.unwrap(); + } else if num_args == NUM_ARGS_FOR_TXT { + let cocycle_graphs_filename: &String = &args[2]; + let cocycle_differential_graphs_filename: &String = &args[3]; + let cocycle_differential_matrix_filename: &String = &args[4]; let result: Result<(usize, usize, usize), std::io::Error> = - expand_n_contract::expand_n_contract(num_spokes, &mut sparse_matrix_file); + expand_n_contract::expand_n_contract( + num_spokes, + cocycle_graphs_filename, + cocycle_differential_graphs_filename, + cocycle_differential_matrix_filename, + ); match result { Ok((num_rows, num_columns, num_nonzeros)) => {