pub trait Scalar:
Field
+ Copy
+ Display
+ Default {
const ZERO: Self;
const ONE: Self;
const TWO: Self;
const E: Self;
const PI: Self;
const INFINITY: Self;
const ENTIRE: Self;
Show 26 methods
// Required methods
fn from_i64(v: i64) -> Self;
fn from_f64(v: f64) -> Self;
fn from_ratio(num: i64, den: i64) -> GeopResult<Self>;
fn to_f64(self) -> f64;
fn abs(self) -> Self;
fn sqrt(self) -> GeopResult<Self>;
fn sin(self) -> Self;
fn cos(self) -> Self;
fn could_be_equal(self, other: Self) -> bool;
fn definitely_not_equal(self, other: Self) -> bool;
fn could_be_greater(self, other: Self) -> bool;
fn definitely_greater(self, other: Self) -> bool;
fn could_be_less(self, other: Self) -> bool;
fn definitely_less(self, other: Self) -> bool;
fn is_infinite(self) -> bool;
fn is_finite(self) -> bool;
fn midpoint(self) -> Self;
fn is_sharp(self) -> bool;
fn width(self) -> Self;
fn lower(self) -> Self;
fn upper(self) -> Self;
fn intersect(self, other: Self) -> Self;
fn union(self, other: Self) -> Self;
fn is_subset_of(self, other: Self) -> bool;
// Provided methods
fn sharpen(self) -> Self { ... }
fn interpolate(a: Self, b: Self, alpha: Self) -> Self { ... }
}Required Associated Constants§
const ZERO: Self
const ONE: Self
const TWO: Self
const E: Self
const PI: Self
Sourceconst ENTIRE: Self
const ENTIRE: Self
The “entire” interval (-inf, inf) — the top element of the interval
lattice. could_be_equal/could_be_greater/could_be_less against
it are always true, and it never satisfies definitely_*. Used to
represent a value or a whole curve/surface whose position is not yet
known — an unsharp placeholder that automatically passes any
overlap/equality check made against it.
Required Methods§
fn from_i64(v: i64) -> Self
fn from_f64(v: f64) -> Self
fn from_ratio(num: i64, den: i64) -> GeopResult<Self>
Sourcefn to_f64(self) -> f64
fn to_f64(self) -> f64
Approximate f64 midpoint. For point scalars returns the value; for interval scalars returns (lo + hi) / 2. Used only for rendering/debugging.
fn abs(self) -> Self
fn sqrt(self) -> GeopResult<Self>
Sourcefn sin(self) -> Self
fn sin(self) -> Self
Outward-rounded enclosure of sin/cos over the whole interval
(radians). Total — never fails, even for Scalar::ENTIRE or an
Scalar::INFINITY-adjacent value, which just widen to [-1, 1].
fn cos(self) -> Self
fn could_be_equal(self, other: Self) -> bool
fn definitely_not_equal(self, other: Self) -> bool
fn could_be_greater(self, other: Self) -> bool
fn definitely_greater(self, other: Self) -> bool
fn could_be_less(self, other: Self) -> bool
fn definitely_less(self, other: Self) -> bool
fn is_infinite(self) -> bool
fn is_finite(self) -> bool
fn midpoint(self) -> Self
Sourcefn is_sharp(self) -> bool
fn is_sharp(self) -> bool
True iff this value carries no width — it’s a single, exactly-known point, not a genuine range of possibility.
Sourcefn width(self) -> Self
fn width(self) -> Self
How much possibility this enclosure carries: hi - lo, as a sharp,
non-negative value. Zero exactly when Scalar::is_sharp.
This is how much a computed quantity is not known. Being sharp
itself is what makes it usable as a threshold — comparing an uncertain
width against an uncertain bound could never be decided three-valuedly
(see validation::numerical_accuracy).
Sourcefn lower(self) -> Self
fn lower(self) -> Self
The sharp lower / upper endpoint of this enclosure. Every value
self could be is >= lower() and <= upper(), so these are the
outer bounds to cut at when a search restricts a domain to an
enclosure of its answer: a cut there never loses a solution (unlike
Scalar::sharpen, which would cut through the enclosure).
fn upper(self) -> Self
Sourcefn intersect(self, other: Self) -> Self
fn intersect(self, other: Self) -> Self
The largest value contained in both self and other — the dual
of Scalar::union. Callers must only intersect two enclosures of
the same underlying exact value (as Scalar::interpolate does);
given that, the result is still an honest enclosure, just a tighter
one. Implementations may return either input if the two somehow
don’t overlap, rather than fabricating an empty/inverted interval.
Sourcefn union(self, other: Self) -> Self
fn union(self, other: Self) -> Self
The smallest value definitely containing both self and other —
the scalar-level analog of Set::union.
Sourcefn is_subset_of(self, other: Self) -> bool
fn is_subset_of(self, other: Self) -> bool
True iff self is contained in other as sets: other.lo <= self.lo
and self.hi <= other.hi. This is the rigorous existence/uniqueness
test a Krawczyk-style contraction relies on (K(X) ⊆ X) — distinct
from Scalar::could_be_equal, which only asks whether the two
enclosures overlap. self.intersect(other).could_be_equal(self)
would answer the same question but at the cost of rebuilding an
enclosure just to throw it away; implementations should compare
bounds directly.
Provided Methods§
Sourcefn sharpen(self) -> Self
fn sharpen(self) -> Self
Collapse to a single representative point (currently the midpoint,
like Scalar::midpoint, but named for its distinct purpose: use
this only when you are free to pick any value within self and
don’t need to preserve which one — e.g. choosing where to place a
new knot when subdividing a curve at an arbitrary interior point.
Never use this to compress a value that represents a genuinely
uncertain physical quantity (a search’s converged bound, a measured
position) — that would silently discard real uncertainty rather than
making an arbitrary, harmless choice.
Exists to break a specific class of interval blowup: repeatedly
re-deriving a split point as (t0 + t1) / 2 from an already-widened
domain propagates and compounds that width forever, even though nothing
downstream actually cares which interior point was chosen — only
that some valid one was. Sharpening throws that unneeded width away
at the source instead of letting every later alpha = (t - e) / (s - e)
division amplify it further.
Sourcefn interpolate(a: Self, b: Self, alpha: Self) -> Self
fn interpolate(a: Self, b: Self, alpha: Self) -> Self
Point a fraction alpha of the way from a to b: a at
alpha=0, b at alpha=1.
Deliberately a.add(alpha.mul(b.sub(a))), not the equally-valid
a.mul(S::ONE.sub(alpha)).add(b.mul(alpha)) — both give the same
exact real result, but the latter computes alpha and 1-alpha as
two decorrelated intervals before ever relating a and b, so
interval arithmetic can’t recognize when they cancel. This form
computes b.sub(a) first: when a and b are honestly the same
value (e.g. a weight that should stay exactly 1.0 across many
subdivisions), that subtraction is exactly 0 regardless of
alpha’s own width, and the whole expression collapses to exactly
a instead of needlessly widening with every call.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".