Skip to main content

MoReport

Struct MoReport 

pub struct MoReport {
    pub label: String,
    pub directions: Vec<Direction>,
    pub values: Vec<Vec<f64>>,
    pub constraints: Vec<Vec<f64>>,
    pub front: Vec<Vec<f64>>,
    pub front_constraints: Vec<Vec<f64>>,
}
Expand description

One searcher’s run over one multi-objective problem, and the front metrics computed from it.

The front is the one the framework itself reports (Study::pareto_front) — copied verbatim, not recomputed and not filtered here, so an assertion about it is an assertion about what a user would actually get. In particular front_is_feasible is a statement about atune’s constrained ranking rather than about this module’s bookkeeping.

Fields§

§label: String

The searcher’s label.

§directions: Vec<Direction>

The study directions the objectives were ranked under.

§values: Vec<Vec<f64>>

Every completed trial’s objective vector, in trial-number order.

§constraints: Vec<Vec<f64>>

Each trial’s constraint values, parallel to values; an empty entry means the trial declared none.

§front: Vec<Vec<f64>>

The Pareto front the study reports, in trial-number order.

§front_constraints: Vec<Vec<f64>>

Each front member’s constraint values, parallel to front.

Implementations§

§

impl MoReport

pub fn evaluations(&self) -> usize

How many trials the run completed.

pub fn front_size(&self) -> usize

How many points the reported front holds.

pub fn front_is_feasible(&self) -> bool

true if every member of the reported front is feasible.

The feasibility-first claim, stated on the framework’s own answer: because constrained_dominates ranks any feasible solution above any infeasible one, a study that evaluated at least one feasible point must report a wholly feasible front. Trivially true for an unconstrained problem, where nothing declared feasibility either way.

pub fn hypervolume(&self, reference: &[f64]) -> Result<f64>

The hypervolume the front covers against reference — the coverage axis.

Computed over the front’s feasible members, exactly as StudyView::hypervolume does: an infeasible solution has not earned the objective space it appears to cover. (It reaches the front at all only when nothing feasible exists, which none of the fixtures here produce — see front_is_feasible.)

§Errors

Everything hypervolume reports.

pub fn span(&self, objective: usize) -> f64

The front’s span in one objective: max − min over its members.

0 for an empty or single-point front — which is the honest answer, and the reason a clone farm fails spread.

pub fn spread(&self, problem: &MoProblem) -> f64

The diversity axis: the smallest fraction of the true front’s span that the reported front covers, over all objectives.

1.0 means the front reaches from one extreme of the true front to the other in every objective; 0.0 means it is a single point. The minimum over objectives — not the mean — because a front that spreads along one axis and collapses along another has not covered the trade-off, and a mean would hide exactly that.

This is the measurement crowding distance exists to move: a sampler that finds one good point and clones it scores 0 here while still scoring respectably on hypervolume, which is why the oracle asserts both.

pub fn spacing(&self) -> f64

Schott’s spacing metric: the standard deviation of each front member’s distance to its nearest neighbour on the front.

Lower is more evenly distributed. Reported rather than gated, and deliberately so: spacing measures evenness, not extent, so a front collapsed onto a single cluster scores a perfect 0. It is the classic example of a diversity metric that a degenerate front games, which is why spread is the one the assertions use.

0 for a front of fewer than two points.

pub fn convergence(&self, problem: &MoProblem) -> f64

The convergence axis: the mean distance from the reported front to the true one (the generational distance).

f64::INFINITY for an empty front — nothing to measure, never accidentally good.

pub fn inverted_generational_distance(&self, problem: &MoProblem) -> f64

The inverted generational distance: the mean, over a dense sample of the true front, of the distance to the nearest reported front member.

The metric that measures convergence and coverage in one number, and the one this oracle leads with. convergence (the plain generational distance) asks “is what I found near the front”, which a run can score well on while covering a tenth of it — and which an archive front is unfairly punished by, since a study’s reported front keeps every historical extreme, including the first trial’s stray minimum in one objective. IGD asks the complementary question, “is every part of the front near something I found”, so a gap costs and a stray does not.

f64::INFINITY for an empty front.

pub fn tail_convergence(&self, problem: &MoProblem, divisor: usize) -> f64

The mean distance to the true front of the last 1/divisor of the evaluated points — where the search ended up, as opposed to what it archived.

The complement to the two front metrics, and the sharpest statement of what a population-based sampler does: NSGA-II’s last generation is its answer, while a study’s reported front is an archive that keeps every historical extreme, and uniform random search’s “front” is the lucky tail of a stationary cloud. Measuring the tail of the trial sequence compares the searchers where they actually differ.

tail_convergence(problem, 4) is the last quarter. f64::INFINITY for an empty run.

pub fn feasible_rate(&self) -> f64

The fraction of completed trials that were feasible.

1.0 for an unconstrained problem (a trial that declared no constraints is not infeasible — it said nothing about feasibility).

pub fn tail_feasible_rate(&self, divisor: usize) -> f64

The feasible fraction of the last 1/divisor of the run.

Where the population ended up, as opposed to where it started: the first generation is a uniform random draw whatever the sampler, so a whole-run feasibility rate is diluted by it. tail_feasible_rate(4) is the last quarter.

pub fn infeasible_dominators(&self) -> usize

How many evaluated points were infeasible yet dominate a member of the reported front on the raw objectives alone.

The feasibility-first claim, stated so it can fail: if this is 0 the constrained problem never actually tempted the sampler, and asserting that the front is feasible would prove nothing. A positive count means the run really did evaluate better-looking illegal points and the front declined them.

Trait Implementations§

§

impl Clone for MoReport

§

fn clone(&self) -> MoReport

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for MoReport

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
§

impl PartialEq for MoReport

§

fn eq(&self, other: &MoReport) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
§

impl StructuralPartialEq for MoReport

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> ByRef<T> for T

§

fn by_ref(&self) -> &T

§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T, U> Imply<T> for U
where T: ?Sized, U: ?Sized,

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more