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