Function dominates
pub fn dominates(a: &[f64], b: &[f64], directions: &[Direction]) -> boolExpand description
Direction-aware Pareto dominance: a dominates b iff it is no worse in
every objective and strictly better in at least one.
Each objective is compared through its own Direction, so a study that
minimises loss while maximising return needs no sign flipping at the call
site.
§Degenerate and hostile inputs
| Case | Answer |
|---|---|
| equal vectors | false both ways — nothing is strictly better |
| a single objective | ordinary ranking: a dominates b iff it is strictly better |
a carries a NaN, or has the wrong arity | false — a NaN never dominates |
b carries a NaN (and a does not) | true — well-formed beats rubbish |
both carry a NaN | false both ways — they tie at the back |
directions is empty | false — there is nothing to compare |
±∞ is an ordinary float and compares normally; only NaN is special. The
relation is irreflexive, antisymmetric and transitive on every input,
including the NaN cases — which is what makes
fast_non_dominated_sort terminate.
use atune_core::pareto::dominates;
use atune_core::study::Direction::{Maximize, Minimize};
let dirs = [Minimize, Maximize];
assert!(dominates(&[1.0, 5.0], &[2.0, 5.0], &dirs)); // better in objective 0
assert!(!dominates(&[1.0, 5.0], &[1.0, 5.0], &dirs)); // equal: no strict gain
assert!(!dominates(&[1.0, 4.0], &[2.0, 5.0], &dirs)); // a trade-off: neither wins
assert!(!dominates(&[f64::NAN, 9.0], &[2.0, 5.0], &dirs), "NaN never dominates");
assert!(dominates(&[2.0, 5.0], &[f64::NAN, 9.0], &dirs), "…and is dominated");