pub struct Interval { /* private fields */ }Expand description
A closed finite binary64 interval [lower, upper].
Construction keeps both endpoints finite and ordered. Arithmetic rounds
outward, so every successful result contains the exact-real result of the
corresponding operation on all represented inputs. Both IEEE-754 signed
zeros are accepted and canonicalized to +0.0; subnormal bounds are
retained.
This is a deliberately small proof-bearing surface, not a general-purpose interval arithmetic package. Division is intentionally absent.
§Examples
use la_stack::prelude::*;
let difference = Interval::try_from_subtraction(1.0, 0.1)?;
let square = difference.try_square()?;
assert!(difference.lower() < difference.upper());
assert!(square.contains((1.0_f64 - 0.1).powi(2)));Implementations§
Source§impl Interval
impl Interval
Sourcepub const fn try_new(lower: f64, upper: f64) -> Result<Self, LaError>
pub const fn try_new(lower: f64, upper: f64) -> Result<Self, LaError>
Construct a closed interval from finite ordered bounds.
Signed zero endpoints are canonicalized to +0.0.
§Examples
use core::assert_matches;
use la_stack::prelude::*;
let range = Interval::try_new(-2.0, 3.0)?;
assert!(range.contains(1.0));
assert!(!range.contains(4.0));
assert_matches!(
Interval::try_new(3.0, -2.0),
Err(LaError::InvertedInterval { lower: 3.0, upper: -2.0, .. })
);§Errors
Returns LaError::NonFinite when either endpoint is NaN or infinity.
Returns LaError::InvertedInterval when lower > upper.
Sourcepub const fn point(value: f64) -> Result<Self, LaError>
pub const fn point(value: f64) -> Result<Self, LaError>
Construct a point interval from a finite binary64 value.
This preserves the supplied value, including any earlier rounding.
Use try_from_subtraction to enclose a
subtraction before its rounding uncertainty is lost.
§Examples
use la_stack::prelude::*;
let half = Interval::point(0.5)?;
assert_eq!((half.lower(), half.upper()), (0.5, 0.5));
assert_eq!(half.try_add(&half)?, Interval::ONE);§Errors
Returns LaError::NonFinite when value is NaN or infinity.
Sourcepub const fn try_from_subtraction(
left: f64,
right: f64,
) -> Result<Self, LaError>
pub const fn try_from_subtraction( left: f64, right: f64, ) -> Result<Self, LaError>
Enclose the exact-real subtraction of two finite binary64 inputs.
Unlike subtracting first and then calling point, this
method preserves the rounding uncertainty introduced by the subtraction.
§Examples
use la_stack::prelude::*;
// The exact difference 1 - 2^-54 lies between adjacent binary64 values.
let difference = Interval::try_from_subtraction(1.0, f64::EPSILON / 4.0)?;
assert_eq!(difference.lower(), 1.0_f64.next_down());
assert_eq!(difference.upper(), 1.0);
// Subtracting first loses that uncertainty and produces a point at 1.
let rounded = Interval::point(1.0 - f64::EPSILON / 4.0)?;
assert_eq!(rounded, Interval::ONE);§Errors
Returns LaError::NonFinite for a non-finite input, preserving whether
it was the left or right operand. Returns
LaError::IntervalRangeExhausted when the exact difference has no
finite binary64 enclosure.
Sourcepub const fn contains(self, value: f64) -> bool
pub const fn contains(self, value: f64) -> bool
Return whether this interval contains the finite value.
Sourcepub const fn try_add(&self, other: &Self) -> Result<Self, LaError>
pub const fn try_add(&self, other: &Self) -> Result<Self, LaError>
Add two intervals with outward rounding.
§Examples
use la_stack::prelude::*;
let left = Interval::try_new(1.0, 2.0)?;
let right = Interval::try_new(0.5, 1.0)?;
assert_eq!(left.try_add(&right)?, Interval::try_new(1.5, 3.0)?);§Errors
Returns LaError::IntervalRangeExhausted when the exact result range
has no finite binary64 enclosure.
Sourcepub const fn try_mul(&self, other: &Self) -> Result<Self, LaError>
pub const fn try_mul(&self, other: &Self) -> Result<Self, LaError>
Multiply two intervals with outward rounding.
For a square of the same represented value, prefer
try_square, which can give a tighter enclosure.
§Examples
use la_stack::prelude::*;
let left = Interval::try_new(-2.0, 3.0)?;
let right = Interval::try_new(-4.0, -1.0)?;
assert_eq!(left.try_mul(&right)?, Interval::try_new(-12.0, 8.0)?);§Errors
Returns LaError::IntervalRangeExhausted when the exact result range
has no finite binary64 enclosure.
Sourcepub const fn negate(&self) -> Self
pub const fn negate(&self) -> Self
Negate an interval exactly by swapping and negating its endpoints.
§Examples
use la_stack::prelude::*;
let range = Interval::try_new(-2.0, 3.0)?;
assert_eq!(range.negate(), Interval::try_new(-3.0, 2.0)?);Sourcepub const fn try_square(&self) -> Result<Self, LaError>
pub const fn try_square(&self) -> Result<Self, LaError>
Square an interval with outward rounding.
An interval spanning zero has exact lower bound zero. The upper bound is the outward-rounded square of the endpoint with greatest magnitude.
§Examples
use la_stack::prelude::*;
let range = Interval::try_new(-2.0, 3.0)?;
assert_eq!(range.try_square()?, Interval::try_new(0.0, 9.0)?);
// Multiplication treats its two operands independently and is wider.
assert_eq!(range.try_mul(&range)?, Interval::try_new(-6.0, 9.0)?);§Errors
Returns LaError::IntervalRangeExhausted when the exact square range
has no finite binary64 enclosure.