use crate::errors::QlResult;
use crate::require;
use crate::types::{Real, Size};
#[derive(Clone, Copy, Debug)]
pub struct IterativeBootstrapOptions {
pub accuracy: Option<Real>,
pub min_value: Option<Real>,
pub max_value: Option<Real>,
pub max_attempts: Size,
pub max_factor: Real,
pub min_factor: Real,
pub dont_throw: bool,
pub dont_throw_steps: Size,
pub max_evaluations: Size,
}
impl Default for IterativeBootstrapOptions {
fn default() -> Self {
Self {
accuracy: None,
min_value: None,
max_value: None,
max_attempts: 1,
max_factor: 2.0,
min_factor: 2.0,
dont_throw: false,
dont_throw_steps: 10,
max_evaluations: 100,
}
}
}
impl IterativeBootstrapOptions {
pub fn validate(&self) -> QlResult<()> {
require!(
self.accuracy.is_none_or(|x| x.is_finite() && x > 0.0),
"bootstrap accuracy must be finite and positive"
);
require!(
self.min_value.is_none_or(Real::is_finite)
&& self.max_value.is_none_or(Real::is_finite),
"bootstrap bounds must be finite"
);
if let (Some(min), Some(max)) = (self.min_value, self.max_value) {
require!(
min < max && (max - min).is_finite(),
"bootstrap minimum must be below maximum with finite width"
);
}
require!(
self.max_attempts > 0 && self.dont_throw_steps > 0 && self.max_evaluations > 0,
"bootstrap attempt, fallback step, and evaluation limits must be positive"
);
require!(
self.min_factor.is_finite()
&& self.min_factor >= 1.0
&& self.max_factor.is_finite()
&& self.max_factor >= 1.0,
"bootstrap widening factors must be finite and at least one"
);
Ok(())
}
}