10#include "rapid/numeric_array.hpp"
28template<numeric_limited T>
47 if constexpr (std::is_floating_point_v<value_type>) {
54 tt_axiom(holds_invariant());
65 tt_axiom(holds_invariant());
77 tt_axiom(r.holds_invariant());
81 [[nodiscard]]
constexpr bool holds_invariant() const noexcept
90 [[nodiscard]]
constexpr value_type
lower() const noexcept
99 [[nodiscard]]
constexpr value_type
upper() const noexcept
108 [[nodiscard]]
constexpr value_type
delta() const noexcept
117 [[nodiscard]]
constexpr bool is_value() const noexcept
126 [[nodiscard]]
constexpr bool is_range() const noexcept
133 template<numeric_limited T>
141 template<numeric_limited T>
151 operator bool () const noexcept
153 return v[0] != 0 or v[1] != 0;
156 [[nodiscard]]
constexpr interval operator-() const noexcept
161 [[nodiscard]]
constexpr interval operator+(
interval const &rhs)
const noexcept
166 [[nodiscard]]
constexpr interval operator-(
interval const &rhs)
const noexcept
168 return *
this + (-rhs);
171 [[nodiscard]]
constexpr interval operator*(
interval const &rhs)
const noexcept
173 ttlet ge_zero = ge(v, bound_type{});
174 ttlet lt_zero = ~ge_zero;
176 ttlet ac = (ge_zero & rhs.v.xx()) | (lt_zero & -rhs.v.yy());
177 ttlet db = (ge_zero & rhs.v.yy()) | (lt_zero & -rhs.v.xx());
179 ttlet ac_mul = ac * v;
180 ttlet db_mul = db * v;
182 return raw(
min(ac_mul, db_mul.yx()));
189 tt_axiom(v[0] >= 0 and rhs.v[0] >= 0);
191 return raw(v * neg<0b10>(rhs.v));
194 [[nodiscard]]
constexpr interval operator/(
interval const &rhs)
const noexcept
196 if (rhs.v[0] <= 0 and 0 <= rhs.v[1]) {
201 ttlet rhs_ge_zero = ge(rhs.v, bound_type{});
202 ttlet rhs_lt_zero = ~rhs_ge_zero;
204 ttlet b_ma = (rhs_ge_zero & v.yy()) | (rhs_lt_zero & -v.xx());
205 ttlet a_mb = -b_ma.yx();
207 ttlet a_mb_mul = a_mb / rhs.v;
208 ttlet b_ma_mul = b_ma / rhs.v;
210 return raw(
min(a_mb, b_ma));
213 [[nodiscard]]
constexpr interval operator%(
interval const &rhs)
const noexcept
215 if (rhs.v[0] <= 0 and 0 <= rhs.v[1]) {
221 ttlet rhs_abs = abs(rhs);
224 }
else if (v[1] > 0) {
227 return raw(rhs_abs.yy());
231 [[nodiscard]]
friend constexpr interval reciprocal(
interval const &rhs)
noexcept
233 if (rhs.v[0] <= 0 and 0 <= rhs.v[1]) {
238 return raw(bound_type::broadcast(value_type{-1}) / rhs.yx());
244 r[0] =
std::max({value_type{0}, rhs.v[0], rhs.v[1]});
245 r[1] =
std::min(rhs.v[0], rhs.v[1]);
249 [[nodiscard]]
friend constexpr interval square(
interval const &rhs)
noexcept
251 ttlet abs_rhs = abs(rhs);
252 return abs_rhs.positive_mul(abs_rhs);
257 return *
this = *
this + rhs;
262 return *
this = *
this - rhs;
267 return *
this = *
this * rhs;
270 [[nodiscard]]
friend constexpr bool operator==(value_type
const &lhs,
interval const &rhs)
noexcept
272 return rhs.
lower() <= lhs and lhs <= rhs.
upper();
275 [[nodiscard]]
friend constexpr auto operator<=>(value_type
const &lhs,
interval const &rhs)
noexcept
277 if constexpr (std::is_floating_point_v<value_type>) {
278 if (lhs < rhs.
lower()) {
279 return std::partial_ordering::less;
280 }
else if (lhs > rhs.
upper()) {
281 return std::partial_ordering::greater;
282 }
else if (lhs >= rhs.
lower() and lhs <= rhs.
upper()) {
283 return std::partial_ordering::equivalent;
285 return std::partial_ordering::unordered;
288 if (lhs < rhs.
lower()) {
289 return std::weak_ordering::less;
290 }
else if (lhs > rhs.
upper()) {
291 return std::weak_ordering::greater;
293 return std::weak_ordering::equivalent;
305 return ge(v, other.v) == 0b11;
310using finterval = interval<float>;
311using dinterval = interval<double>;
Interval arithmetic.
Definition interval.hpp:29
constexpr interval(value_type lower, value_type upper) noexcept
Construct an interval from a lower and upper bounds.
Definition interval.hpp:62
constexpr interval() noexcept
Default construct an interval.
Definition interval.hpp:45
constexpr bool is_value() const noexcept
Check if the interval is one value.
Definition interval.hpp:117
constexpr bool range_contains_type() const noexcept
Check if all the values in a type is inside the interval.
Definition interval.hpp:142
constexpr interval positive_mul(interval const &rhs) const noexcept
Multiply two positive intervals.
Definition interval.hpp:187
constexpr value_type delta() const noexcept
The distance between lower and upper bound.
Definition interval.hpp:108
constexpr bool type_contains_range() const noexcept
Check if a given type can hold all values in the interval.
Definition interval.hpp:134
constexpr value_type upper() const noexcept
Get the upper bound of the interval.
Definition interval.hpp:99
constexpr bool is_range() const noexcept
Check if the interval is a range of values.
Definition interval.hpp:126
static constexpr interval raw(bound_type bounds) noexcept
Construct an interval from a bound_type value.
Definition interval.hpp:73
constexpr value_type lower() const noexcept
Get the lower bound of the interval.
Definition interval.hpp:90
constexpr bool is_fully_inside(interval const &other) const noexcept
Check if the current interval is fully inside the other interval.
Definition interval.hpp:303