use crate::low_level_analysis::{
analyse_complexity,
analyse_set_resizing_iterator_complexity,
types::*,
};
pub fn analyse_time_complexity(passes_info: &AlgorithmPassesInfo,
measurements: &BigOTimeMeasurements)
-> BigOAlgorithmComplexity {
let t1 = measurements.pass_1_measurements.as_secs_f64();
let t2 = measurements.pass_2_measurements.as_secs_f64();
let n1 = passes_info.pass1_n as f64;
let n2 = passes_info.pass2_n as f64;
analyse_complexity(t1, t2, n1, n2)
}
pub fn analyse_time_complexity_for_constant_set_iterator_algorithm(passes_info: &ConstantSetIteratorAlgorithmPassesInfo,
measurements: &BigOTimeMeasurements)
-> BigOAlgorithmComplexity {
let t1 = measurements.pass_1_measurements.as_secs_f64();
let t2 = measurements.pass_2_measurements.as_secs_f64();
let n1 = std::cmp::min(passes_info.pass_1_set_size, passes_info.pass_2_set_size) as f64;
let n2 = std::cmp::max(passes_info.pass_1_set_size, passes_info.pass_2_set_size) as f64;
analyse_complexity(t1, t2, n1, n2)
}
pub fn analyse_time_complexity_for_set_resizing_iterator_algorithm(passes_info: &SetResizingIteratorAlgorithmPassesInfo,
measurements: &BigOTimeMeasurements) -> BigOAlgorithmComplexity {
let n = passes_info.delta_set_size as f64;
let t1 = measurements.pass_1_measurements.as_secs_f64();
let t2 = measurements.pass_2_measurements.as_secs_f64();
analyse_set_resizing_iterator_complexity(t1, t2, n)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::features::*;
use std::time::Duration;
use serial_test::serial;
#[test]
#[serial]
fn analyse_algorithm_theoretical_test() {
let assert = |measurement_name, expected_complexity, passes_info: AlgorithmPassesInfo, time_measurements: BigOTimeMeasurements| {
let observed_time_complexity = analyse_time_complexity(&passes_info, &time_measurements);
assert_eq!(observed_time_complexity, expected_complexity, "Algorithm Analysis on regular, non-iterator algorithm for '{}' check failed!", measurement_name);
};
assert("Theoretical better than O(1) algorithm", BigOAlgorithmComplexity::BetterThanO1,
AlgorithmPassesInfo { pass1_n: 1000, pass2_n: 2000 },
BigOTimeMeasurements {
pass_1_measurements: Duration::from_micros(100),
pass_2_measurements: Duration::from_micros(89)
});
assert("Theoretical O(1) algorithm", BigOAlgorithmComplexity::O1,
AlgorithmPassesInfo { pass1_n: 1000, pass2_n: 2000 },
BigOTimeMeasurements {
pass_1_measurements: Duration::from_micros(100),
pass_2_measurements: Duration::from_micros(100)
});
assert("Theoretical O(log(n)) algorithm", BigOAlgorithmComplexity::OLogN,
AlgorithmPassesInfo { pass1_n: 1000, pass2_n: 2000 },
BigOTimeMeasurements {
pass_1_measurements: Duration::from_micros(100),
pass_2_measurements: Duration::from_micros(111)
});
assert("Theoretical between O(log(n)) and O(n) algorithm", BigOAlgorithmComplexity::BetweenOLogNAndON,
AlgorithmPassesInfo { pass1_n: 1000, pass2_n: 2000 },
BigOTimeMeasurements {
pass_1_measurements: Duration::from_micros(100),
pass_2_measurements: Duration::from_micros(150)
});
assert("Theoretical O(n) algorithm", BigOAlgorithmComplexity::ON,
AlgorithmPassesInfo { pass1_n: 1000, pass2_n: 2000 },
BigOTimeMeasurements {
pass_1_measurements: Duration::from_micros(100),
pass_2_measurements: Duration::from_micros(200)
});
assert("Theoretical O(n.log(n)) algorithm", BigOAlgorithmComplexity::ONLogN,
AlgorithmPassesInfo { pass1_n: 1000, pass2_n: 2000 },
BigOTimeMeasurements {
pass_1_measurements: Duration::from_micros(1000),
pass_2_measurements: Duration::from_micros(2220)
});
assert("Theoretical between O(n.log(n)) and O(n²) algorithm", BigOAlgorithmComplexity::BetweenONLogNAndON2,
AlgorithmPassesInfo { pass1_n: 1000, pass2_n: 2000 },
BigOTimeMeasurements {
pass_1_measurements: Duration::from_micros(1000),
pass_2_measurements: Duration::from_micros(3000)
});
assert("Theoretical O(n²) algorithm", BigOAlgorithmComplexity::ON2,
AlgorithmPassesInfo { pass1_n: 1000, pass2_n: 2000 },
BigOTimeMeasurements {
pass_1_measurements: Duration::from_micros(1000),
pass_2_measurements: Duration::from_micros(4000)
});
assert("Theoretical O(n³) algorithm", BigOAlgorithmComplexity::ON3,
AlgorithmPassesInfo { pass1_n: 1000, pass2_n: 2000 },
BigOTimeMeasurements {
pass_1_measurements: Duration::from_micros(1000),
pass_2_measurements: Duration::from_micros(8000)
});
assert("Theoretical O(n^4) algorithm", BigOAlgorithmComplexity::ON4,
AlgorithmPassesInfo { pass1_n: 1000, pass2_n: 2000 },
BigOTimeMeasurements {
pass_1_measurements: Duration::from_micros( 1000),
pass_2_measurements: Duration::from_micros(16000)
});
assert("Theoretical O(k^n) algorithm", BigOAlgorithmComplexity::OkN,
AlgorithmPassesInfo { pass1_n: 10, pass2_n: 70 },
BigOTimeMeasurements {
pass_1_measurements: Duration::from_secs_f64(1.0e1),
pass_2_measurements: Duration::from_secs_f64(1.0e7)
});
assert("O(k^n) algorithm (10% lower than the theoretical value)", BigOAlgorithmComplexity::OkN,
AlgorithmPassesInfo { pass1_n: 10, pass2_n: 70 },
BigOTimeMeasurements {
pass_1_measurements: Duration::from_secs_f64(1.0e1),
pass_2_measurements: Duration::from_secs_f64(1.0e7 * 0.901)
});
assert("O(k^n) algorithm (10% greater than the theoretical value)", BigOAlgorithmComplexity::OkN,
AlgorithmPassesInfo { pass1_n: 10, pass2_n: 70 },
BigOTimeMeasurements {
pass_1_measurements: Duration::from_secs_f64(1.0e1),
pass_2_measurements: Duration::from_secs_f64(1.0e7 * 1.099)
});
assert("Worse than exponential algorithm", BigOAlgorithmComplexity::WorseThanExponential,
AlgorithmPassesInfo { pass1_n: 10, pass2_n: 70 },
BigOTimeMeasurements {
pass_1_measurements: Duration::from_secs_f64(1.0e1),
pass_2_measurements: Duration::from_secs_f64(1.0e7 * 1.101)
});
}
#[test]
#[serial]
fn analyse_constant_set_iterator_algorithm_theoretical_test() {
let assert = |measurement_name, expected_complexity, passes_info: ConstantSetIteratorAlgorithmPassesInfo, time_measurements: BigOTimeMeasurements| {
let observed_time_complexity = analyse_time_complexity_for_constant_set_iterator_algorithm(&passes_info, &time_measurements);
assert_eq!(observed_time_complexity, expected_complexity, "Algorithm Analysis on CONSTANT SET iterator algorithm for '{}' check failed!", measurement_name);
};
assert("Theoretical better than O(1) Update/Select", BigOAlgorithmComplexity::BetterThanO1,
ConstantSetIteratorAlgorithmPassesInfo { pass_1_set_size: 1000, pass_2_set_size: 2000, repetitions: 1000 },
BigOTimeMeasurements {
pass_1_measurements: Duration::from_micros(100),
pass_2_measurements: Duration::from_micros(100 - (PERCENT_TOLERANCE*100.0) as u64 - 1),
});
assert("Theoretical O(1) Update/Select", BigOAlgorithmComplexity::O1,
ConstantSetIteratorAlgorithmPassesInfo { pass_1_set_size: 1000, pass_2_set_size: 2000, repetitions: 1000 },
BigOTimeMeasurements {
pass_1_measurements: Duration::from_micros(100),
pass_2_measurements: Duration::from_micros(100),
});
assert("Theoretical O(log(n)) Update/Select", BigOAlgorithmComplexity::OLogN,
ConstantSetIteratorAlgorithmPassesInfo { pass_1_set_size: 1000, pass_2_set_size: 2000, repetitions: 1000 },
BigOTimeMeasurements {
pass_1_measurements: Duration::from_micros(100),
pass_2_measurements: Duration::from_micros(111),
});
assert("Theoretical between O(log(n)) and O(n) Update/Select", BigOAlgorithmComplexity::BetweenOLogNAndON,
ConstantSetIteratorAlgorithmPassesInfo { pass_1_set_size: 1000, pass_2_set_size: 2000, repetitions: 1000 },
BigOTimeMeasurements {
pass_1_measurements: Duration::from_micros(100),
pass_2_measurements: Duration::from_micros(150),
});
assert("Theoretical O(n) Update/Select", BigOAlgorithmComplexity::ON,
ConstantSetIteratorAlgorithmPassesInfo { pass_1_set_size: 1000, pass_2_set_size: 2000, repetitions: 1000 },
BigOTimeMeasurements {
pass_1_measurements: Duration::from_micros(100),
pass_2_measurements: Duration::from_micros(200),
});
assert("Theoretical worse than O(n) Update/Select", BigOAlgorithmComplexity::ONLogN,
ConstantSetIteratorAlgorithmPassesInfo { pass_1_set_size: 1000, pass_2_set_size: 2000, repetitions: 1000 },
BigOTimeMeasurements {
pass_1_measurements: Duration::from_micros(100),
pass_2_measurements: Duration::from_micros(226),
});
}
#[test]
#[serial]
fn analyse_set_resizing_iterator_algorithm_theoretical_test() {
let assert = |measurement_name, expected_complexity, passes_info: SetResizingIteratorAlgorithmPassesInfo, time_measurements: BigOTimeMeasurements| {
let observed_complexity = analyse_time_complexity_for_set_resizing_iterator_algorithm(&passes_info, &time_measurements);
assert_eq!(observed_complexity, expected_complexity, "Algorithm Analysis on SET RESIZING iterator algorithm for '{}' check failed!", measurement_name);
};
assert("Theoretical better than O(1) Insert/Delete", BigOAlgorithmComplexity::BetterThanO1,
SetResizingIteratorAlgorithmPassesInfo { delta_set_size: 1000 },
BigOTimeMeasurements {
pass_1_measurements: Duration::from_micros(100),
pass_2_measurements: Duration::from_micros(100 - (PERCENT_TOLERANCE*100.0) as u64),
});
assert("Theoretical O(1) Insert/Delete", BigOAlgorithmComplexity::O1,
SetResizingIteratorAlgorithmPassesInfo { delta_set_size: 1000 },
BigOTimeMeasurements {
pass_1_measurements: Duration::from_micros(100),
pass_2_measurements: Duration::from_micros(100),
});
assert("Theoretical O(log(n)) Insert/Delete", BigOAlgorithmComplexity::OLogN,
SetResizingIteratorAlgorithmPassesInfo { delta_set_size: 1000 },
BigOTimeMeasurements {
pass_1_measurements: Duration::from_micros(100),
pass_2_measurements: Duration::from_micros(122),
});
assert("Theoretical between O(log(n)) and O(n) Insert/Delete", BigOAlgorithmComplexity::BetweenOLogNAndON,
SetResizingIteratorAlgorithmPassesInfo { delta_set_size: 1000 },
BigOTimeMeasurements {
pass_1_measurements: Duration::from_micros(100),
pass_2_measurements: Duration::from_micros(200),
});
assert("Theoretical O(n) Insert/Delete", BigOAlgorithmComplexity::ON,
SetResizingIteratorAlgorithmPassesInfo { delta_set_size: 1000 },
BigOTimeMeasurements {
pass_1_measurements: Duration::from_micros(100),
pass_2_measurements: Duration::from_micros(300),
});
assert("Theoretical worse than O(n) Insert/Delete", BigOAlgorithmComplexity::BetweenONAndONLogN,
SetResizingIteratorAlgorithmPassesInfo { delta_set_size: 1000 },
BigOTimeMeasurements {
pass_1_measurements: Duration::from_micros(100),
pass_2_measurements: Duration::from_micros(333),
});
}
}