use super::DiscoveredFormula;
impl DiscoveredFormula {
pub fn dominates(&self, other: &DiscoveredFormula) -> bool {
self.mse <= other.mse
&& self.complexity <= other.complexity
&& (self.mse < other.mse || self.complexity < other.complexity)
}
}
pub fn pareto_front(formulas: &[DiscoveredFormula]) -> Vec<DiscoveredFormula> {
let mut front: Vec<DiscoveredFormula> = formulas
.iter()
.filter(|candidate| !formulas.iter().any(|other| other.dominates(candidate)))
.cloned()
.collect();
front.sort_by(|a, b| {
a.complexity.cmp(&b.complexity).then_with(|| {
a.mse
.partial_cmp(&b.mse)
.unwrap_or(std::cmp::Ordering::Equal)
})
});
front
}
pub fn dominates_by<F>(a: &DiscoveredFormula, b: &DiscoveredFormula, objective: F) -> bool
where
F: Fn(&DiscoveredFormula) -> f64,
{
a.complexity <= b.complexity && objective(a) < objective(b)
}
pub fn pareto_front_ic(formulas: &[DiscoveredFormula], use_bic: bool) -> Vec<DiscoveredFormula> {
let ic_of = |f: &DiscoveredFormula| if use_bic { f.bic } else { f.aic };
let mut front: Vec<DiscoveredFormula> = formulas
.iter()
.filter(|candidate| {
!formulas
.iter()
.any(|other| dominates_by(other, candidate, ic_of))
})
.cloned()
.collect();
front.sort_by_key(|a| a.complexity);
front
}