13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program Tester Core
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ----------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Interval arithmetic.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuInterval.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMath.h"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <cmath>
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace tcu
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::ldexp;
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
353c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterval applyMonotone (DoubleFunc1& func, const Interval& arg0)
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Interval ret;
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TCU_INTERVAL_APPLY_MONOTONE1(ret, x, arg0, val,
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								 TCU_SET_INTERVAL(val, point, point = func(x)));
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return ret;
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
433c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterval applyMonotone (DoubleIntervalFunc1& func, const Interval& arg0)
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return Interval(func(arg0.lo()), func(arg0.hi()));
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
483c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterval applyMonotone (DoubleFunc2& func, const Interval& arg0, const Interval& arg1)
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Interval ret;
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TCU_INTERVAL_APPLY_MONOTONE2(ret, x, arg0, y, arg1, val,
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								 TCU_SET_INTERVAL(val, point, point = func(x, y)));
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return ret;
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
583c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterval applyMonotone (DoubleIntervalFunc2& func, const Interval& arg0, const Interval& arg1)
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	double	lo0 = arg0.lo(), hi0 = arg0.hi(), lo1 = arg1.lo(), hi1 = arg1.hi();
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return Interval(Interval(func(lo0, lo1), func(lo0, hi1)),
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					Interval(func(hi0, lo1), func(hi0, hi1)));
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
653c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterval operator+ (const Interval& x, const Interval& y)
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Interval ret;
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!x.empty() && !y.empty())
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_SET_INTERVAL_BOUNDS(ret, p, p = x.lo() + y.lo(), p = x.hi() + y.hi());
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (x.hasNaN() || y.hasNaN())
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ret |= TCU_NAN;
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return ret;
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
773c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterval operator- (const Interval& x, const Interval& y)
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Interval ret;
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TCU_INTERVAL_APPLY_MONOTONE2(ret, xp, x, yp, y, val,
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								 TCU_SET_INTERVAL(val, point, point = xp - yp));
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return ret;
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
863c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterval operator* (const Interval& x, const Interval& y)
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Interval ret;
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TCU_INTERVAL_APPLY_MONOTONE2(ret, xp, x, yp, y, val,
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								 TCU_SET_INTERVAL(val, point, point = xp * yp));
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return ret;
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
953c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterval operator/ (const Interval& nom, const Interval& den)
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (den.contains(0.0))
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// \todo [2014-03-21 lauri] Non-inf endpoint when one den endpoint is
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// zero and nom doesn't cross zero?
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return Interval::unbounded();
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Interval ret;
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_INTERVAL_APPLY_MONOTONE2(ret, nomp, nom, denp, den, val,
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									 TCU_SET_INTERVAL(val, point, point = nomp / denp));
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return ret;
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic double negate (double x)
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return -x;
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1183c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterval operator- (const Interval& x)
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return applyMonotone(negate, x);
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1233c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterval exp2 (const Interval& x)
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return applyMonotone(std::pow, 2.0, x);
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1283c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterval exp (const Interval& x)
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return applyMonotone(std::exp, x);
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1333c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterval sqrt (const Interval& x)
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return applyMonotone(std::sqrt, x);
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1383c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterval inverseSqrt (const Interval& x)
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return 1.0 / sqrt(x);
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1433c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterval abs (const Interval& x)
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Interval mono = applyMonotone(std::abs, x);
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (x.contains(0.0))
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return Interval(0.0, mono);
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return mono;
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& os, const Interval& interval)
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (interval.empty())
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (interval.hasNaN())
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			os << "[NaN]";
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			os << "()";
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		os << (interval.hasNaN() ? "~" : "")
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   << "[" << interval.lo() << ", " << interval.hi() << "]";
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return os;
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // tcu
167