use cobre_solver::{DEFAULT_PROFILE_HEURISTIC_SENTINEL, HighsProfile};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Phase {
Forward,
Backward,
Simulation,
}
pub const FORWARD_PROFILE: HighsProfile = HighsProfile {
primal_feasibility_tolerance: 1e-9,
dual_feasibility_tolerance: 1e-9,
simplex_iteration_limit: DEFAULT_PROFILE_HEURISTIC_SENTINEL,
ipm_iteration_limit: 10_000,
simplex_dual_edge_weight_strategy: 1, simplex_scale_strategy: 0, simplex_price_strategy: 1, };
pub const BACKWARD_PROFILE: HighsProfile = HighsProfile {
primal_feasibility_tolerance: 1e-9,
dual_feasibility_tolerance: 1e-9,
simplex_iteration_limit: DEFAULT_PROFILE_HEURISTIC_SENTINEL,
ipm_iteration_limit: 10_000,
simplex_dual_edge_weight_strategy: 1, simplex_scale_strategy: 0, simplex_price_strategy: 2, };
pub const SIMULATION_PROFILE: HighsProfile = HighsProfile {
primal_feasibility_tolerance: 1e-9,
dual_feasibility_tolerance: 1e-9,
simplex_iteration_limit: DEFAULT_PROFILE_HEURISTIC_SENTINEL,
ipm_iteration_limit: 10_000,
simplex_dual_edge_weight_strategy: 1, simplex_scale_strategy: 0, simplex_price_strategy: 1, };
impl Phase {
#[must_use]
pub fn profile(self) -> HighsProfile {
match self {
Phase::Forward => FORWARD_PROFILE,
Phase::Backward => BACKWARD_PROFILE,
Phase::Simulation => SIMULATION_PROFILE,
}
}
}
const _: () = {
assert!(FORWARD_PROFILE.primal_feasibility_tolerance == 1e-9);
assert!(FORWARD_PROFILE.dual_feasibility_tolerance == 1e-9);
assert!(FORWARD_PROFILE.simplex_iteration_limit == DEFAULT_PROFILE_HEURISTIC_SENTINEL);
assert!(FORWARD_PROFILE.ipm_iteration_limit == 10_000);
assert!(FORWARD_PROFILE.simplex_dual_edge_weight_strategy == 1);
assert!(FORWARD_PROFILE.simplex_scale_strategy == 0);
assert!(FORWARD_PROFILE.simplex_price_strategy == 1);
assert!(BACKWARD_PROFILE.primal_feasibility_tolerance == 1e-9);
assert!(BACKWARD_PROFILE.dual_feasibility_tolerance == 1e-9);
assert!(BACKWARD_PROFILE.simplex_iteration_limit == DEFAULT_PROFILE_HEURISTIC_SENTINEL);
assert!(BACKWARD_PROFILE.ipm_iteration_limit == 10_000);
assert!(BACKWARD_PROFILE.simplex_dual_edge_weight_strategy == 1);
assert!(BACKWARD_PROFILE.simplex_scale_strategy == 0);
assert!(BACKWARD_PROFILE.simplex_price_strategy == 2);
assert!(SIMULATION_PROFILE.primal_feasibility_tolerance == 1e-9);
assert!(SIMULATION_PROFILE.dual_feasibility_tolerance == 1e-9);
assert!(SIMULATION_PROFILE.simplex_iteration_limit == DEFAULT_PROFILE_HEURISTIC_SENTINEL);
assert!(SIMULATION_PROFILE.ipm_iteration_limit == 10_000);
assert!(SIMULATION_PROFILE.simplex_dual_edge_weight_strategy == 1);
assert!(SIMULATION_PROFILE.simplex_scale_strategy == 0);
assert!(SIMULATION_PROFILE.simplex_price_strategy == 1);
};
#[cfg(test)]
mod tests {
use cobre_solver::HighsProfile;
use super::{BACKWARD_PROFILE, FORWARD_PROFILE, Phase, SIMULATION_PROFILE};
#[test]
fn phase_profile_returns_matching_constant() {
assert_eq!(Phase::Forward.profile(), FORWARD_PROFILE);
assert_eq!(Phase::Backward.profile(), BACKWARD_PROFILE);
assert_eq!(Phase::Simulation.profile(), SIMULATION_PROFILE);
}
#[test]
fn forward_and_simulation_equal_default() {
let default = HighsProfile::default();
assert_eq!(FORWARD_PROFILE, default);
assert_eq!(SIMULATION_PROFILE, default);
}
#[test]
fn backward_profile_overrides_only_price_strategy() {
let default = HighsProfile::default();
assert_ne!(BACKWARD_PROFILE, default);
assert_eq!(BACKWARD_PROFILE.simplex_price_strategy, 2);
assert_eq!(
BACKWARD_PROFILE.simplex_dual_edge_weight_strategy,
default.simplex_dual_edge_weight_strategy
);
assert_eq!(
BACKWARD_PROFILE.primal_feasibility_tolerance,
default.primal_feasibility_tolerance
);
assert_eq!(
BACKWARD_PROFILE.dual_feasibility_tolerance,
default.dual_feasibility_tolerance
);
assert_eq!(
BACKWARD_PROFILE.simplex_iteration_limit,
default.simplex_iteration_limit
);
assert_eq!(
BACKWARD_PROFILE.ipm_iteration_limit,
default.ipm_iteration_limit
);
assert_eq!(
BACKWARD_PROFILE.simplex_scale_strategy,
default.simplex_scale_strategy
);
}
}