diff --git a/src/bottomup.rs b/src/bottomup.rs index 056921a..ff19f72 100644 --- a/src/bottomup.rs +++ b/src/bottomup.rs @@ -263,7 +263,7 @@ pub(crate) fn bottomup( args.block * args.block_size_multiple, args.deg, ); - println!("phase one {:.2?}", start.elapsed()); + println!("Phase one finished in {:.2?}.", start.elapsed()); start = Instant::now(); let r = phase_two( args.k, @@ -274,6 +274,6 @@ pub(crate) fn bottomup( args.block * args.block_size_multiple, args.max_bits, ); - println!("phase two {:.2?}", start.elapsed()); + println!("Phase two finished in {:.2?}.", start.elapsed()); r } diff --git a/src/common.rs b/src/common.rs index d4922d3..1c227f7 100644 --- a/src/common.rs +++ b/src/common.rs @@ -53,6 +53,10 @@ pub(crate) struct Args { #[arg(long)] pub(crate) hist: bool, + /// Significance level + #[arg(short, long, default_value_t = 0.0004)] + pub(crate) alpha: f64, + /// Config file with list of CoolTest configurations to run. #[arg(long, short)] pub(crate) config: bool, @@ -148,11 +152,7 @@ pub(crate) fn prepare_data( } else { training_data = transform_training_data(data, block_size, block_size_multiple); } - println!( - "tr {}, te {}", - training_data.data.len(), - testing_data_option.as_ref().unwrap().data.len() - ); + (training_data, validation_data_option, testing_data_option) } diff --git a/src/main.rs b/src/main.rs index fdd86ef..5821df8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,9 +15,19 @@ use std::fs::File; use std::io::{BufRead, BufReader}; use std::time::Instant; -fn print_results(p_value: f64, z_score: f64) { +fn print_results(p_value: f64, z_score: f64, alpha: f64) { + println!("---------------------------------------------------"); println!("z-score: {z_score}"); println!("p-value: {p_value:.0e}"); + if p_value >= alpha { + println!( + "As the p-value >= alpha {alpha:.0e}, the randomness hypothesis cannot be rejected." + ); + println!("= CoolTest could not find statistically significant non-randomness."); + } else { + println!("As the p-value < alpha {alpha:.0e}, the randomness hypothesis is REJECTED."); + println!("= Data is not random."); + } } fn results( @@ -25,9 +35,7 @@ fn results( start: Instant, training_data: &Data, testing_data: &Data, - patterns_combined: usize, - top_n: usize, - hist: bool, + args: Args, ) -> (f64, f64) { final_patterns.sort_by(|a, b| { f64::abs(b.z_score.unwrap()) @@ -35,26 +43,32 @@ fn results( .unwrap() }); - if hist { - hist_result(final_patterns, training_data, testing_data, start) + if args.hist { + hist_result( + final_patterns, + training_data, + testing_data, + start, + args.alpha, + ) } else { let mut best_mp = best_multi_pattern( training_data, - &final_patterns.into_iter().take(top_n).collect_vec(), - patterns_combined, + &final_patterns.into_iter().take(args.top_n).collect_vec(), + args.patterns_combined, ); - println!("trained in {:.2?}", start.elapsed()); + println!("Trained in {:.2?}.", start.elapsed()); - println!("training z-score: {}", best_mp.z_score.unwrap()); - println!("best multi-pattern: {best_mp:?}"); + println!("Training z-score: {}.", best_mp.z_score.unwrap()); + println!("Best multi-pattern: {best_mp:?}"); let z_score = evaluate_distinguisher(&mut best_mp, testing_data); let p_value = p_value( best_mp.get_count(), testing_data.num_of_blocks, best_mp.probability, ); - print_results(p_value, z_score); + print_results(p_value, z_score, args.alpha); (p_value, z_score) } } @@ -64,10 +78,12 @@ fn hist_result( training_data: &Data, testing_data: &Data, start: Instant, + alpha: f64, ) -> (f64, f64) { let bits = final_patterns[0].bits.clone(); - println!("number of bits: {}", bits.len()); + println!("Number of bits in histogram: {}.", bits.len()); + println!("Selected bits: {:?}", bits); if bits.len() > 20 { println!("Too many bits in pattern, can't produce hist result."); @@ -76,16 +92,15 @@ fn hist_result( let hist = Histogram::get_hist(&bits, training_data); - println!("trained in {:.2?}", start.elapsed()); - println!("training z-score: {}", hist.z_score); + println!("Trained in {:.2?}.", start.elapsed()); + println!("Training z-score: {}.", hist.z_score); let count = hist.evaluate(testing_data); let prob = 2.0_f64.powf(-(hist.bits.len() as f64)) * (hist.best_division as f64); let z = z_score(testing_data.num_of_blocks, count, prob); let p_val = p_value(count, testing_data.num_of_blocks, prob); - - print_results(p_val, z); + print_results(p_val, z, alpha); (p_val, z) } @@ -98,7 +113,7 @@ fn run_bottomup(args: Args) -> (f64, f64) { true, args.validation_and_testing_split, ); - println!("data loaded in: {:?}", s.elapsed()); + println!("Data loaded in {:?}.", s.elapsed()); let start = Instant::now(); let final_patterns = bottomup(&training_data, validation_data_option.as_ref(), &args); @@ -107,9 +122,7 @@ fn run_bottomup(args: Args) -> (f64, f64) { start, &training_data, &testing_data_option.unwrap(), - args.patterns_combined, - args.top_n, - args.hist, + args, ) } @@ -126,6 +139,7 @@ fn parse_args(s: Vec<&str>) -> Args { deg: s[8].trim().parse().unwrap(), validation_and_testing_split: s[9].trim().parse().unwrap(), hist: s[10].trim().parse().unwrap(), + alpha: 0.0004, config: false, } }