#![allow(non_snake_case)]
use clap::Parser;
use mixingcut::io_operations;
use mixingcut::io_operations::write_dual_variables;
use mixingcut::maxcut_oracle::get_Q_norm;
use mixingcut::sdp_solver::compute_approx_perturbation;
use mixingcut::step_rules::generate_step_rule;
use std::time::{SystemTime, UNIX_EPOCH};
#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
struct Args {
#[clap(short, long)]
input_path: String,
#[clap(short, long, default_value = "output.txt")]
output_path: String,
#[clap(short, long, default_value = "0")]
rank: usize,
#[clap(short, long, default_value = "1e-2")]
tolerance: f64,
#[clap(short, long, default_value = "1000")]
max_iters: usize,
#[clap(short, long, default_value = "coord_no_step")]
step_rule: String,
#[clap(long, default_value = "1")]
index_correction: usize,
#[clap(short, long, default_value = "0")]
dual_bound: usize,
#[clap(short, long, default_value = "1")]
verbose: usize,
#[clap(long, default_value = "100")]
rounding_iters: usize,
#[clap(long, default_value = "128")]
beam_width: usize,
}
fn current_time() -> f64 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs_f64()
}
fn main() {
let args: Args = Args::parse();
let index_correction = args.index_correction;
let Q = io_operations::read_graph_matrix(&args.input_path, index_correction);
let alpha_safe = get_Q_norm(&Q);
let step_rule = generate_step_rule(&args.step_rule, alpha_safe);
let n = Q.shape().0;
let max_iters = args.max_iters;
let verbose = args.verbose;
let start = current_time();
let tolerance = args.tolerance;
let k = match args.rank {
0 => 2 * (n as f64).log2() as usize,
1 => (2.0 * n as f64).sqrt() as usize,
_ => args.rank,
};
let is_verbose = verbose > 0;
let y_sol = compute_approx_perturbation(
&Q,
Some(k),
None,
Some(max_iters),
Some(tolerance),
Some(step_rule),
is_verbose,
);
let end = current_time();
if verbose > 0 {
println!("Perturbation solution: {:?}", y_sol);
println!("Perturbation solution norm: {}", y_sol.sum());
println!("Solved in {:.5} seconds", end - start);
}
write_dual_variables(&args.output_path, y_sol);
}