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