The Interval class
Main author: Simon Rohou
The Interval
class represents closed and connected subsets of \(\mathbb{R}\).
It is based on the gaol::interval
structure and extends it with many utility methods.
Creating Intervals
An interval \([a,b]\) can be created using the constructor Interval(a, b)
.
You can also create degenerate intervals, unbounded intervals, or intervals from collections.
x = Interval(3, 5) # [3.0, 5.0]
x = Interval(4.2) # [4.2, 4.2]
x = Interval() # [-∞, ∞]
x = Interval(-oo, -10) # [-∞, -10]
x = Interval([2.0, -3.0]) # [-3.0, 2.0]
x = Interval([3.14]) # [3.14, 3.14]
Interval x(3, 5); // [3.0, 5.0]
Interval x(4.2); // [4.2, 4.2]
Interval x; // [-∞, ∞]
Interval x(-oo, -10); // [-∞, -10]
Interval x(std::array<double,2>{2.0, -3.0}); // [-3.0, 2.0]
Interval x(std::array<double,1>{3.14}); // [3.14, 3.14]
x = Interval(3, 5) % [3.0, 5.0]
x = Interval(4.2) % [4.2, 4.2]
x = Interval() % [-∞, ∞]
x = Interval(-oo, -10) % [-∞, -10]
x = Interval([2.0, -3.0]) % [-3.0, 2.0]
x = Interval([3.14]) % [3.14, 3.14]
Note
Note that in Codac, the value positive infinity is represented by the constant oo
(and -oo
for negative infinity). One possible implementation of this constant is std::numeric_limits<double>::infinity()
in C++, or math.inf
in Python. Therefore, the declarations Interval()
and Interval(-oo,oo)
are equivalent.
Predefined constants
Some common intervals are predefined:
x = Interval() # [-∞,∞] (default value)
x = Interval.empty() # ∅
x = Interval.pi() # [π]
x = Interval.two_pi() # [2π]
x = Interval.half_pi() # [π/2]
x = Interval.zero() # [0]
x = Interval.one() # [1]
Interval x; // [-∞,∞] (default value)
Interval x = Interval::empty(); // ∅
Interval x = Interval::pi(); // [π]
Interval x = Interval::two_pi(); // [2π]
Interval x = Interval::half_pi(); // [π/2]
Interval x = Interval::zero(); // [0]
Interval x = Interval::one(); // [1]
x = Interval() % [-∞,∞] (default value)
x = Interval().empty % ∅
x = Interval().pi % [π]
x = Interval().two_pi % [2π]
x = Interval().half_pi % [π/2]
x = Interval().zero % [0]
x = Interval().one % [1]
Note
Note that the constant \([\pi]\) is a reliable enclosure of the \(\pi\) value, that cannot be exactly represented in a computer with a single floating-point value.
x = Interval.pi() # [π]
# x = [3.141592653589793, 3.141592653589794]
Interval x = Interval::pi(); // [π]
// x = [3.141592653589793, 3.141592653589794]
x = Interval().pi % [π]
% x = [3.14159, 3.1416]
In case you need a non-reliable floating point value for \(\pi\), you can use the PI
constant already available.
Interval properties
You can access key interval properties:
x.lb() # lower bound
x.ub() # upper bound
x.mid() # midpoint
x.rad() # radius
x.diam() # diameter
x.mag() # magnitude
x.mig() # mignitude
x.size() # dimension (always 1)
x.lb(); // lower bound
x.ub(); // upper bound
x.mid(); // midpoint
x.rad(); // radius
x.diam(); // diameter
x.mag(); // magnitude
x.mig(); // mignitude
x.size(); // dimension (always 1)
x.lb % lower bound
x.ub % upper bound
x.mid % midpoint
x.rad % radius
x.diam % diameter
x.mag % magnitude
x.mig % mignitude
x.size % dimension (always 1)
Testing intervals
Intervals support a wide range of predicates:
is_empty()
: test if the interval is emptyis_degenerated()
: test if it’s of the form [a,a]is_integer()
: test if it’s an integer singletonhas_integer_bounds()
: test if the bounds are integersis_unbounded()
: test if any bound is infinitecontains(x)
: test if it contains a real numberintersects(y)
: test if it intersects with another intervalis_subset(y)
: test if it is a subset of anotheris_strict_subset(y)
,is_interior_subset(y)
, etc.
Advanced operations
Method |
Description |
---|---|
|
Expands the interval by ±rad |
|
Splits into two intervals at given ratio (default is 0.49) |
|
Computes complement \(\mathbb{R} \setminus [x]\) |
|
Computes set difference \([x] \setminus [y]\) |
|
Returns a random sample within the interval |
|
Re-initializes to \([-\infty,\infty]\) |
|
Initializes using the hull of a list of values |
Interval arithmetic
All standard arithmetic operations are supported, both element-wise and with real numbers.
x = Interval(2,3)
y = Interval(1,2)
z = x + y # [3, 5]
z = x - 1 # [1, 2]
z = 2 * x # [4, 6]
z = x / y # [1, 3]
Interval x(2,3);
Interval y(1,2);
Interval z = x + y; // [3, 5]
z = x - 1; // [1, 2]
z = 2 * x; // [4, 6]
z = x / y; // [1, 3]
x = Interval(2,3)
y = Interval(1,2)
z = x + y % [3, 5]
z = x - 1 % [1, 2]
z = 2 * x % [4, 6]
z = x / y % [1, 3]
Unary and binary functions
Mathematical functions such as \(\sin\), \(\cos\), \(\exp\), \(\log\), \(\sqrt{\cdot}\), etc., are overloaded to work with intervals. Some examples:
x = Interval.half_pi()
x |= 0 # x = [0, π/2]
y = sin(x) # y = [0, 1]
z = exp(x) # z = [1, e^(π/2)]
Interval x = Interval::half_pi();
x |= 0; // x = [0, π/2]
Interval y = sin(x); // y = [0, 1]
Interval z = exp(x); // z = [1, e^(π/2)]
x = Interval.half_pi();
x.self_union(0); % x = [0, π/2]
y = sin(x); % y = [0, 1]
z = exp(x); % z = [1, exp(π/2)]
For a complete list of additional operations, see the page Analytic operators.
Literals
In C++, a user-defined literal is provided in C++ to construct an interval directly from a floating-point number:
Interval x = 2.5_i; // [2.5, 2.5]
Floating-point adjacency
The previous_float
and next_float
functions return the floating-point numbers directly adjacent to a given value.
These functions are useful in the context of interval arithmetic to tightly control rounding directions.
-
inline double codac2::previous_float(double x)
Returns the previous representable double-precision floating-point value before x.
This function computes the largest double value that is strictly less than the input value x, effectively moving one step down in the floating-point representation.
See also
For obtaining the next representable double value greater than x, use
next_float()
.- Parameters:
x – The input double value.
- Returns:
The previous representable double value before x.
x = previous_float(1.0)
# x = 0.9999999999999999
double x = previous_float(1.0);
// x = 0.9999999999999999
x = previous_float(1.0);
% x = 0.9999999999999999
Technical documentation
See the C++ API documentation of this class.