xref: /aosp_15_r20/external/deqp/framework/common/tcuInterval.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program Tester Core
3*35238bceSAndroid Build Coastguard Worker  * ----------------------------------------
4*35238bceSAndroid Build Coastguard Worker  *
5*35238bceSAndroid Build Coastguard Worker  * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker  *
7*35238bceSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker  *
11*35238bceSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker  *
13*35238bceSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker  * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker  *
19*35238bceSAndroid Build Coastguard Worker  *//*!
20*35238bceSAndroid Build Coastguard Worker  * \file
21*35238bceSAndroid Build Coastguard Worker  * \brief Interval arithmetic.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "tcuInterval.hpp"
25*35238bceSAndroid Build Coastguard Worker 
26*35238bceSAndroid Build Coastguard Worker #include "deMath.h"
27*35238bceSAndroid Build Coastguard Worker 
28*35238bceSAndroid Build Coastguard Worker #include <cmath>
29*35238bceSAndroid Build Coastguard Worker 
30*35238bceSAndroid Build Coastguard Worker namespace tcu
31*35238bceSAndroid Build Coastguard Worker {
32*35238bceSAndroid Build Coastguard Worker 
33*35238bceSAndroid Build Coastguard Worker using std::ldexp;
34*35238bceSAndroid Build Coastguard Worker 
applyMonotone(DoubleFunc1 & func,const Interval & arg0)35*35238bceSAndroid Build Coastguard Worker Interval applyMonotone(DoubleFunc1 &func, const Interval &arg0)
36*35238bceSAndroid Build Coastguard Worker {
37*35238bceSAndroid Build Coastguard Worker     Interval ret;
38*35238bceSAndroid Build Coastguard Worker     TCU_INTERVAL_APPLY_MONOTONE1(ret, x, arg0, val, TCU_SET_INTERVAL(val, point, point = func(x)));
39*35238bceSAndroid Build Coastguard Worker     return ret;
40*35238bceSAndroid Build Coastguard Worker }
41*35238bceSAndroid Build Coastguard Worker 
applyMonotone(DoubleIntervalFunc1 & func,const Interval & arg0)42*35238bceSAndroid Build Coastguard Worker Interval applyMonotone(DoubleIntervalFunc1 &func, const Interval &arg0)
43*35238bceSAndroid Build Coastguard Worker {
44*35238bceSAndroid Build Coastguard Worker     return Interval(func(arg0.lo()), func(arg0.hi()));
45*35238bceSAndroid Build Coastguard Worker }
46*35238bceSAndroid Build Coastguard Worker 
applyMonotone(DoubleFunc2 & func,const Interval & arg0,const Interval & arg1)47*35238bceSAndroid Build Coastguard Worker Interval applyMonotone(DoubleFunc2 &func, const Interval &arg0, const Interval &arg1)
48*35238bceSAndroid Build Coastguard Worker {
49*35238bceSAndroid Build Coastguard Worker     Interval ret;
50*35238bceSAndroid Build Coastguard Worker 
51*35238bceSAndroid Build Coastguard Worker     TCU_INTERVAL_APPLY_MONOTONE2(ret, x, arg0, y, arg1, val, TCU_SET_INTERVAL(val, point, point = func(x, y)));
52*35238bceSAndroid Build Coastguard Worker 
53*35238bceSAndroid Build Coastguard Worker     return ret;
54*35238bceSAndroid Build Coastguard Worker }
55*35238bceSAndroid Build Coastguard Worker 
applyMonotone(DoubleIntervalFunc2 & func,const Interval & arg0,const Interval & arg1)56*35238bceSAndroid Build Coastguard Worker Interval applyMonotone(DoubleIntervalFunc2 &func, const Interval &arg0, const Interval &arg1)
57*35238bceSAndroid Build Coastguard Worker {
58*35238bceSAndroid Build Coastguard Worker     double lo0 = arg0.lo(), hi0 = arg0.hi(), lo1 = arg1.lo(), hi1 = arg1.hi();
59*35238bceSAndroid Build Coastguard Worker     return Interval(Interval(func(lo0, lo1), func(lo0, hi1)), Interval(func(hi0, lo1), func(hi0, hi1)));
60*35238bceSAndroid Build Coastguard Worker }
61*35238bceSAndroid Build Coastguard Worker 
operator +(const Interval & x,const Interval & y)62*35238bceSAndroid Build Coastguard Worker Interval operator+(const Interval &x, const Interval &y)
63*35238bceSAndroid Build Coastguard Worker {
64*35238bceSAndroid Build Coastguard Worker     Interval ret;
65*35238bceSAndroid Build Coastguard Worker 
66*35238bceSAndroid Build Coastguard Worker     if (!x.empty() && !y.empty())
67*35238bceSAndroid Build Coastguard Worker         TCU_SET_INTERVAL_BOUNDS(ret, p, p = x.lo() + y.lo(), p = x.hi() + y.hi());
68*35238bceSAndroid Build Coastguard Worker     if (x.hasNaN() || y.hasNaN())
69*35238bceSAndroid Build Coastguard Worker         ret |= TCU_NAN;
70*35238bceSAndroid Build Coastguard Worker 
71*35238bceSAndroid Build Coastguard Worker     return ret;
72*35238bceSAndroid Build Coastguard Worker }
73*35238bceSAndroid Build Coastguard Worker 
operator -(const Interval & x,const Interval & y)74*35238bceSAndroid Build Coastguard Worker Interval operator-(const Interval &x, const Interval &y)
75*35238bceSAndroid Build Coastguard Worker {
76*35238bceSAndroid Build Coastguard Worker     Interval ret;
77*35238bceSAndroid Build Coastguard Worker 
78*35238bceSAndroid Build Coastguard Worker     TCU_INTERVAL_APPLY_MONOTONE2(ret, xp, x, yp, y, val, TCU_SET_INTERVAL(val, point, point = xp - yp));
79*35238bceSAndroid Build Coastguard Worker     return ret;
80*35238bceSAndroid Build Coastguard Worker }
81*35238bceSAndroid Build Coastguard Worker 
operator *(const Interval & x,const Interval & y)82*35238bceSAndroid Build Coastguard Worker Interval operator*(const Interval &x, const Interval &y)
83*35238bceSAndroid Build Coastguard Worker {
84*35238bceSAndroid Build Coastguard Worker     Interval ret;
85*35238bceSAndroid Build Coastguard Worker 
86*35238bceSAndroid Build Coastguard Worker     TCU_INTERVAL_APPLY_MONOTONE2(ret, xp, x, yp, y, val, TCU_SET_INTERVAL(val, point, point = xp * yp));
87*35238bceSAndroid Build Coastguard Worker     return ret;
88*35238bceSAndroid Build Coastguard Worker }
89*35238bceSAndroid Build Coastguard Worker 
operator /(const Interval & nom,const Interval & den)90*35238bceSAndroid Build Coastguard Worker Interval operator/(const Interval &nom, const Interval &den)
91*35238bceSAndroid Build Coastguard Worker {
92*35238bceSAndroid Build Coastguard Worker     if (den.contains(0.0))
93*35238bceSAndroid Build Coastguard Worker     {
94*35238bceSAndroid Build Coastguard Worker         // \todo [2014-03-21 lauri] Non-inf endpoint when one den endpoint is
95*35238bceSAndroid Build Coastguard Worker         // zero and nom doesn't cross zero?
96*35238bceSAndroid Build Coastguard Worker         return Interval::unbounded();
97*35238bceSAndroid Build Coastguard Worker     }
98*35238bceSAndroid Build Coastguard Worker     else
99*35238bceSAndroid Build Coastguard Worker     {
100*35238bceSAndroid Build Coastguard Worker         Interval ret;
101*35238bceSAndroid Build Coastguard Worker 
102*35238bceSAndroid Build Coastguard Worker         TCU_INTERVAL_APPLY_MONOTONE2(ret, nomp, nom, denp, den, val, TCU_SET_INTERVAL(val, point, point = nomp / denp));
103*35238bceSAndroid Build Coastguard Worker         return ret;
104*35238bceSAndroid Build Coastguard Worker     }
105*35238bceSAndroid Build Coastguard Worker }
106*35238bceSAndroid Build Coastguard Worker 
negate(double x)107*35238bceSAndroid Build Coastguard Worker static double negate(double x)
108*35238bceSAndroid Build Coastguard Worker {
109*35238bceSAndroid Build Coastguard Worker     return -x;
110*35238bceSAndroid Build Coastguard Worker }
111*35238bceSAndroid Build Coastguard Worker 
operator -(const Interval & x)112*35238bceSAndroid Build Coastguard Worker Interval operator-(const Interval &x)
113*35238bceSAndroid Build Coastguard Worker {
114*35238bceSAndroid Build Coastguard Worker     return applyMonotone(negate, x);
115*35238bceSAndroid Build Coastguard Worker }
116*35238bceSAndroid Build Coastguard Worker 
exp2(const Interval & x)117*35238bceSAndroid Build Coastguard Worker Interval exp2(const Interval &x)
118*35238bceSAndroid Build Coastguard Worker {
119*35238bceSAndroid Build Coastguard Worker     return applyMonotone(std::pow, 2.0, x);
120*35238bceSAndroid Build Coastguard Worker }
121*35238bceSAndroid Build Coastguard Worker 
exp(const Interval & x)122*35238bceSAndroid Build Coastguard Worker Interval exp(const Interval &x)
123*35238bceSAndroid Build Coastguard Worker {
124*35238bceSAndroid Build Coastguard Worker     return applyMonotone(std::exp, x);
125*35238bceSAndroid Build Coastguard Worker }
126*35238bceSAndroid Build Coastguard Worker 
sqrt(const Interval & x)127*35238bceSAndroid Build Coastguard Worker Interval sqrt(const Interval &x)
128*35238bceSAndroid Build Coastguard Worker {
129*35238bceSAndroid Build Coastguard Worker     return applyMonotone(std::sqrt, x);
130*35238bceSAndroid Build Coastguard Worker }
131*35238bceSAndroid Build Coastguard Worker 
inverseSqrt(const Interval & x)132*35238bceSAndroid Build Coastguard Worker Interval inverseSqrt(const Interval &x)
133*35238bceSAndroid Build Coastguard Worker {
134*35238bceSAndroid Build Coastguard Worker     return 1.0 / sqrt(x);
135*35238bceSAndroid Build Coastguard Worker }
136*35238bceSAndroid Build Coastguard Worker 
abs(const Interval & x)137*35238bceSAndroid Build Coastguard Worker Interval abs(const Interval &x)
138*35238bceSAndroid Build Coastguard Worker {
139*35238bceSAndroid Build Coastguard Worker     const Interval mono = applyMonotone(std::abs, x);
140*35238bceSAndroid Build Coastguard Worker 
141*35238bceSAndroid Build Coastguard Worker     if (x.contains(0.0))
142*35238bceSAndroid Build Coastguard Worker         return Interval(0.0, mono);
143*35238bceSAndroid Build Coastguard Worker 
144*35238bceSAndroid Build Coastguard Worker     return mono;
145*35238bceSAndroid Build Coastguard Worker }
146*35238bceSAndroid Build Coastguard Worker 
operator <<(std::ostream & os,const Interval & interval)147*35238bceSAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &os, const Interval &interval)
148*35238bceSAndroid Build Coastguard Worker {
149*35238bceSAndroid Build Coastguard Worker     if (interval.empty())
150*35238bceSAndroid Build Coastguard Worker         if (interval.hasNaN())
151*35238bceSAndroid Build Coastguard Worker             os << "[NaN]";
152*35238bceSAndroid Build Coastguard Worker         else
153*35238bceSAndroid Build Coastguard Worker             os << "()";
154*35238bceSAndroid Build Coastguard Worker     else
155*35238bceSAndroid Build Coastguard Worker         os << (interval.hasNaN() ? "~" : "") << "[" << interval.lo() << ", " << interval.hi() << "]";
156*35238bceSAndroid Build Coastguard Worker     return os;
157*35238bceSAndroid Build Coastguard Worker }
158*35238bceSAndroid Build Coastguard Worker 
159*35238bceSAndroid Build Coastguard Worker } // namespace tcu
160