summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-conf/checkout/deqp/framework/common/tcuInterval.js
diff options
context:
space:
mode:
Diffstat (limited to 'dom/canvas/test/webgl-conf/checkout/deqp/framework/common/tcuInterval.js')
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/framework/common/tcuInterval.js609
1 files changed, 609 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/framework/common/tcuInterval.js b/dom/canvas/test/webgl-conf/checkout/deqp/framework/common/tcuInterval.js
new file mode 100644
index 000000000..23296c1f3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/framework/common/tcuInterval.js
@@ -0,0 +1,609 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program Tester Core
+ * ----------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Interval arithmetic and floating point precisions.
+ *//*--------------------------------------------------------------------*/
+ 'use strict';
+ goog.provide('framework.common.tcuInterval');
+ goog.require('framework.delibs.debase.deMath');
+
+ goog.scope(function() {
+
+ var tcuInterval = framework.common.tcuInterval;
+ var deMath = framework.delibs.debase.deMath;
+
+ /**
+ * @typedef {function(number):number}
+ */
+ tcuInterval.DoubleFunc1;
+
+ /**
+ * @typedef {function(number, number):number}
+ */
+ tcuInterval.DoubleFunc2;
+
+ /**
+ * @typedef {function(number,number,number):number}
+ */
+ tcuInterval.DoubleFunc3;
+
+ /**
+ * @typedef {function(number):tcuInterval.Interval}
+ */
+ tcuInterval.DoubleIntervalFunc1;
+
+ /**
+ * @typedef {function(number,number):tcuInterval.Interval}
+ */
+ tcuInterval.DoubleIntervalFunc2;
+
+ /**
+ * @typedef {function(number,number,number):tcuInterval.Interval}
+ */
+ tcuInterval.DoubleIntervalFunc3;
+
+ /**
+ * @param {function(number): number} func
+ * @param {tcuInterval.Interval} arg0
+ * @return {tcuInterval.Interval}
+ */
+ tcuInterval.applyMonotone1p = function(func, arg0) {
+ /**
+ * @param {number=} x
+ * @param {number=} y
+ * @return {number}
+ */
+ var body = function(x, y) {
+ x = x || 0;
+ return func(x);
+ };
+ return tcuInterval.applyMonotone1(arg0,
+ function(x) { return tcuInterval.setInterval(body, x); });
+ };
+
+ /**
+ * @param {function(number): tcuInterval.Interval} func
+ * @param {tcuInterval.Interval} arg0
+ * @return {tcuInterval.Interval}
+ */
+ tcuInterval.applyMonotone1i = function(func, arg0) {
+ return tcuInterval.withIntervals(func(arg0.lo()), func(arg0.hi()));
+ };
+
+ /**
+ * @param {function(number, number): number} func
+ * @param {tcuInterval.Interval} arg0
+ * @param {tcuInterval.Interval} arg1
+ * @return {tcuInterval.Interval}
+ */
+ tcuInterval.applyMonotone2p = function(func, arg0, arg1) {
+ /**
+ * @param {number=} x
+ * @param {number=} y
+ * @return {number}
+ */
+ var body = function(x, y) {
+ x = x || 0;
+ y = y || 0;
+ return func(x, y);
+ };
+ return tcuInterval.applyMonotone2(arg0, arg1,
+ function(x, y) { return tcuInterval.setInterval(body, x, y); });
+ };
+
+ /**
+ * @param {function(number, number): tcuInterval.Interval} func
+ * @param {tcuInterval.Interval} arg0
+ * @param {tcuInterval.Interval} arg1
+ * @return {tcuInterval.Interval}
+ */
+ tcuInterval.applyMonotone2i = function(func, arg0, arg1) {
+ /** @type {number} */ var lo0 = arg0.lo();
+ /** @type {number} */ var hi0 = arg0.hi();
+ /** @type {number} */ var lo1 = arg1.lo();
+ /** @type {number} */ var hi1 = arg1.hi();
+ var a = tcuInterval.withIntervals(func(lo0, lo1), func(lo0, hi1));
+ var b = tcuInterval.withIntervals(func(hi0, lo1), func(hi0, hi1));
+ return tcuInterval.withIntervals(a, b);
+ };
+
+ /**
+ * @constructor
+ * @param {number=} val
+ */
+ tcuInterval.Interval = function(val) {
+ if (val === undefined) {
+ this.m_hasNaN = false;
+ this.m_lo = Number.POSITIVE_INFINITY;
+ this.m_hi = Number.NEGATIVE_INFINITY;
+ } else {
+ this.m_hasNaN = isNaN(val);
+ this.m_lo = this.m_hasNaN ? Number.POSITIVE_INFINITY : val;
+ this.m_hi = this.m_hasNaN ? Number.NEGATIVE_INFINITY : val;
+ }
+ };
+
+ tcuInterval.Interval.prototype.toString = function() {
+ var str = 'Interval(' + this.m_lo + ', ' + this.m_hi;
+ if (this.m_hasNaN)
+ str += ', hasNaN';
+ str += ')';
+ return str;
+ };
+
+ /**
+ * @param {tcuInterval.Interval} a
+ * @param {tcuInterval.Interval} b
+ * @return {tcuInterval.Interval}
+ */
+ tcuInterval.withIntervals = function(a, b) {
+ /** @type {tcuInterval.Interval} */ var interval = new tcuInterval.Interval();
+ interval.m_hasNaN = (a.m_hasNaN || b.m_hasNaN);
+ interval.m_lo = Math.min(a.m_lo, b.m_lo);
+ interval.m_hi = Math.max(a.m_hi, b.m_hi);
+ return interval;
+ };
+
+ /**
+ * @param {number} a
+ * @param {number} b
+ * @return {tcuInterval.Interval}
+ */
+ tcuInterval.withNumbers = function(a, b) {
+ var x = new tcuInterval.Interval(a);
+ var y = new tcuInterval.Interval(b);
+ return tcuInterval.withIntervals(x, y);
+ };
+
+ /**
+ * @param {boolean} hasNaN_
+ * @param {number} lo_
+ * @param {number} hi_
+ * @return {tcuInterval.Interval}
+ */
+ tcuInterval.withParams = function(hasNaN_, lo_, hi_) {
+ /** @type {tcuInterval.Interval} */ var interval = new tcuInterval.Interval();
+ interval.m_hasNaN = hasNaN_;
+ interval.m_lo = lo_;
+ interval.m_hi = hi_;
+ return interval;
+ };
+
+ /**
+ * @return {number}
+ */
+ tcuInterval.Interval.prototype.length = function() {
+ return this.m_hi - this.m_lo;
+ };
+
+ /**
+ * @return {number}
+ */
+ tcuInterval.Interval.prototype.lo = function() {
+ return this.m_lo;
+ };
+
+ /**
+ * @return {number}
+ */
+ tcuInterval.Interval.prototype.hi = function() {
+ return this.m_hi;
+ };
+
+ /**
+ * @return {boolean}
+ */
+ tcuInterval.Interval.prototype.hasNaN = function() {
+ return this.m_hasNaN;
+ };
+
+ /**
+ * @return {tcuInterval.Interval}
+ */
+ tcuInterval.Interval.prototype.nan = function() {
+ return this.m_hasNaN ? new tcuInterval.Interval(NaN) : new tcuInterval.Interval();
+ };
+
+ /**
+ * @return {boolean}
+ */
+ tcuInterval.Interval.prototype.empty = function() {
+ return this.m_lo > this.m_hi;
+ };
+
+ /**
+ * @return {boolean}
+ */
+ tcuInterval.Interval.prototype.isFinite = function() {
+ return isFinite(this.m_lo) && isFinite(this.m_hi);
+ };
+
+ /**
+ * @return {boolean}
+ */
+ tcuInterval.Interval.prototype.isOrdinary = function() {
+ return !this.hasNaN() && !this.empty() && this.isFinite();
+ };
+
+ /**
+ * @param {tcuInterval.Interval} other
+ * @return {tcuInterval.Interval}
+ */
+ tcuInterval.Interval.prototype.operatorOrBinary = function(other) {
+ /** @type {tcuInterval.Interval} */ var temp = new tcuInterval.Interval();
+ temp.m_hasNaN = this.m_hasNaN || other.m_hasNaN;
+ temp.m_lo = Math.min(this.m_lo, other.m_lo);
+ temp.m_hi = Math.max(this.m_hi, other.m_hi);
+ return temp;
+ };
+
+ /**
+ * @param {tcuInterval.Interval} other
+ */
+ tcuInterval.Interval.prototype.operatorOrAssignBinary = function(other) {
+ /** @type {tcuInterval.Interval} */ var temp = this.operatorOrBinary(other);
+ this.m_hasNaN = temp.m_hasNaN;
+ this.m_lo = temp.m_lo;
+ this.m_hi = temp.m_hi;
+ };
+
+ /**
+ * @param {tcuInterval.Interval} other
+ * @return {tcuInterval.Interval}
+ */
+ tcuInterval.Interval.prototype.operatorAndBinary = function(other) {
+ /** @type {tcuInterval.Interval} */ var temp = new tcuInterval.Interval();
+ temp.m_hasNaN = this.m_hasNaN && other.m_hasNaN;
+ temp.m_lo = Math.max(this.m_lo, other.m_lo);
+ temp.m_hi = Math.min(this.m_hi, other.m_hi);
+ return temp;
+ };
+
+ /**
+ * @param {tcuInterval.Interval} other
+ */
+ tcuInterval.Interval.prototype.operatorAndAssignBinary = function(other) {
+ /** @type {tcuInterval.Interval} */ var temp = this.operatorAndBinary(other);
+ this.m_hasNaN = temp.m_hasNaN;
+ this.m_lo = temp.m_lo;
+ this.m_hi = temp.m_hi;
+ };
+
+ /**
+ * @param {tcuInterval.Interval} other
+ * @return {boolean}
+ */
+ tcuInterval.Interval.prototype.contains = function(other) {
+ return (other.lo() >= this.lo() && other.hi() <= this.hi() &&
+ (!other.hasNaN() || this.hasNaN()));
+ };
+
+ /**
+ * @param {tcuInterval.Interval} other
+ * @return {boolean}
+ */
+ tcuInterval.Interval.prototype.intersects = function(other) {
+ return ((other.hi() >= this.lo() && other.lo() >= this.hi()) ||
+ (other.hasNaN() && this.hasNaN()));
+ };
+
+ /**
+ * @return {tcuInterval.Interval}
+ */
+ tcuInterval.Interval.prototype.operatorNegative = function() {
+ /** @type {tcuInterval.Interval} */ var temp = new tcuInterval.Interval();
+ temp.m_hasNaN = this.m_hasNaN;
+ temp.m_lo = -this.m_hi;
+ temp.m_hi = -this.m_lo;
+ return temp;
+ };
+
+ /**
+ * @param {boolean=} nan
+ * @return {tcuInterval.Interval}
+ */
+ tcuInterval.unbounded = function(nan) {
+ if (nan === undefined)
+ nan = false;
+ return tcuInterval.withParams(nan, Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY);
+ };
+
+ /**
+ * @return {number}
+ */
+ tcuInterval.Interval.prototype.midpoint = function() {
+ return 0.5 * (this.hi() + this.lo()); // returns NaN when not bounded
+ };
+
+ /**
+ * @param {tcuInterval.Interval} other
+ * @return {boolean}
+ */
+ tcuInterval.Interval.prototype.operatorCompare = function(other) {
+ return ((this.m_hasNaN == other.m_hasNaN) &&
+ ((this.empty() && other.empty()) ||
+ (this.m_lo == other.m_lo && this.m_hi == other.m_hi)));
+ };
+
+ /**
+ * @param {tcuInterval.Interval} x
+ * @return {tcuInterval.Interval}
+ */
+ tcuInterval.Interval.operatorPositive = function(x) {
+ return x;
+ };
+
+ /**
+ * @param {tcuInterval.Interval} x
+ * @return {tcuInterval.Interval}
+ */
+ tcuInterval.Interval.exp2 = function(x) {
+ // std::pow
+ return tcuInterval.applyMonotone2p(Math.pow, new tcuInterval.Interval(2), x);
+ };
+
+ /**
+ * @param {tcuInterval.Interval} x
+ * @return {tcuInterval.Interval}
+ */
+ tcuInterval.Interval.exp = function(x) {
+ // std::exp
+ return tcuInterval.applyMonotone1p(Math.exp, x);
+ };
+
+ /**
+ * @param {tcuInterval.Interval} x
+ * @return {tcuInterval.Interval}
+ */
+ tcuInterval.Interval.sign = function(x) {
+ // TODO
+ throw new Error('Unimplemented');
+ };
+
+ /**
+ * @param {tcuInterval.Interval} x
+ * @param {tcuInterval.Interval} y
+ * @return {tcuInterval.Interval}
+ */
+ tcuInterval.Interval.operatorSum = function(x, y) {
+ /** @type {tcuInterval.Interval} */ var ret = new tcuInterval.Interval();
+
+ if (!x.empty() && !y.empty())
+ ret = tcuInterval.setIntervalBounds(function(dummy) {return x.lo() + y.lo();}, function(dummy) {return x.hi() + y.hi();});
+ if (x.hasNaN() || y.hasNaN())
+ ret.operatorOrAssignBinary(new tcuInterval.Interval(NaN));
+
+ return ret;
+ };
+
+ /**
+ * @param {tcuInterval.Interval} x
+ * @param {tcuInterval.Interval} y
+ * @return {tcuInterval.Interval}
+ */
+ tcuInterval.Interval.operatorSub = function(x, y) {
+ /** @type {tcuInterval.Interval} */ var ret = new tcuInterval.Interval();
+
+ /**
+ * @param {number=} x
+ * @param {number=} y
+ * @return {tcuInterval.Interval}
+ */
+ var body = function(x, y) {
+ return new tcuInterval.Interval(x - y);
+ };
+
+ ret = tcuInterval.applyMonotone2(x, y, body);
+ return ret;
+ };
+
+ /**
+ * @param {tcuInterval.Interval} x
+ * @param {tcuInterval.Interval} y
+ * @return {tcuInterval.Interval}
+ */
+ tcuInterval.Interval.operatorMul = function(x, y) {
+ /** @type {tcuInterval.Interval} */ var ret = new tcuInterval.Interval();
+
+ /**
+ * @param {number=} x
+ * @param {number=} y
+ * @return {tcuInterval.Interval}
+ */
+ var body = function(x, y) {
+ return new tcuInterval.Interval(x * y);
+ };
+
+ ret = tcuInterval.applyMonotone2(x, y, body);
+
+ return ret;
+ };
+
+ /**
+ * @param {tcuInterval.Interval} nom
+ * @param {tcuInterval.Interval} den
+ * @return {tcuInterval.Interval}
+ */
+ tcuInterval.Interval.operatorDiv = function(nom, den) {
+ if (den.contains(new tcuInterval.Interval(0))) {
+ // \todo [2014-03-21 lauri] Non-inf endpoint when one den endpoint is
+ // zero and nom doesn't cross zero?
+ return tcuInterval.unbounded();
+ } else {
+ /** @type {tcuInterval.Interval} */ var ret = new tcuInterval.Interval();
+ /**
+ * @param {number=} x
+ * @param {number=} y
+ * @return {tcuInterval.Interval}
+ */
+ var body = function(x, y) {
+ return new tcuInterval.Interval(x / y);
+ };
+
+ ret = tcuInterval.applyMonotone2(nom, den, body);
+
+ return ret;
+ }
+ };
+
+ /**
+ * @param {tcuInterval.Interval} x
+ * @return {tcuInterval.Interval}
+ */
+ tcuInterval.Interval.prototype.abs = function(x) {
+ //std::abs
+ /** @type {tcuInterval.Interval} */ var mono = tcuInterval.applyMonotone1p(Math.abs, x);
+ var zero = new tcuInterval.Interval(0);
+ if (x.contains(zero))
+ return tcuInterval.withIntervals(zero, mono);
+
+ return mono;
+ };
+
+ /**
+ * @param {tcuInterval.Interval} x
+ * @return {tcuInterval.Interval}
+ */
+ tcuInterval.Interval.sqrt = function(x) {
+ return tcuInterval.applyMonotone1p(Math.sqrt, x);
+ };
+
+ /**
+ * @param {tcuInterval.Interval} x
+ * @return {tcuInterval.Interval}
+ */
+ tcuInterval.Interval.inverseSqrt = function(x) {
+ var ret = new tcuInterval.Interval(1);
+ ret = tcuInterval.Interval.operatorDiv(ret, tcuInterval.Interval.sqrt(x));
+ return ret;
+ };
+
+/**
+ * @param {function(number=, number=): number} setLow
+ * @param {function(number=, number=): number} setHigh
+ * @param {number=} arg0
+ * @param {number=} arg1
+ * @return {tcuInterval.Interval}
+ */
+tcuInterval.setIntervalBounds = function(setLow, setHigh, arg0, arg1) {
+ // TODO: No support for rounding modes. Originally, setLow() was rounded down and setHigh() rounded up
+ var lo = new tcuInterval.Interval(setLow(arg0, arg1));
+ var hi = new tcuInterval.Interval(setHigh(arg0, arg1));
+ return lo.operatorOrBinary(hi);
+};
+
+/**
+ * @param {function(number=, number=): number} set
+ * @param {number=} arg0
+ * @param {number=} arg1
+ * @return {tcuInterval.Interval}
+ */
+tcuInterval.setInterval = function(set, arg0, arg1) {
+ return tcuInterval.setIntervalBounds(set, set, arg0, arg1);
+};
+
+/**
+ * @param {tcuInterval.Interval} arg
+ * @param {function(number): tcuInterval.Interval} body
+ * @return {tcuInterval.Interval}
+ */
+tcuInterval.applyMonotone1 = function(arg, body) {
+ var ret = new tcuInterval.Interval();
+
+ if (!arg.empty()) {
+ var lo = body(arg.lo());
+ var hi = body(arg.hi());
+ ret = lo.operatorOrBinary(hi);
+ }
+
+ if (arg.hasNaN()) {
+ ret = ret.operatorOrBinary(new tcuInterval.Interval(NaN));
+ }
+
+ return ret;
+};
+
+/**
+ * TODO: Check if this function works properly
+ * @param {tcuInterval.Interval} arg0
+ * @param {tcuInterval.Interval} arg1
+ * @param {function(number, number): tcuInterval.Interval} body
+ * @return {tcuInterval.Interval}
+ */
+tcuInterval.applyMonotone2 = function(arg0, arg1, body) {
+ var ret = new tcuInterval.Interval();
+
+ if (!arg0.empty() && !arg1.empty()) {
+ var lo0 = body(arg0.lo(), arg1.lo());
+ var lo1 = body(arg0.lo(), arg1.hi());
+ var hi0 = body(arg0.hi(), arg1.lo());
+ var hi1 = body(arg0.hi(), arg1.hi());
+ var a = lo0.operatorOrBinary(hi0);
+ var b = lo1.operatorOrBinary(hi1);
+ ret = a.operatorOrBinary(b);
+ }
+
+ if (arg0.hasNaN() || arg1.hasNaN()) {
+ ret = ret.operatorOrBinary(new tcuInterval.Interval(NaN));
+ }
+
+ return ret;
+};
+
+/**
+ * TODO: Check if this function works properly
+ * @param {tcuInterval.Interval} arg0
+ * @param {tcuInterval.Interval} arg1
+ * @param {tcuInterval.Interval} arg2
+ * @param {function(number, number, number): tcuInterval.Interval} body
+ * @return {tcuInterval.Interval}
+ */
+tcuInterval.applyMonotone3 = function(arg0, arg1, arg2, body) {
+ var ret = new tcuInterval.Interval();
+
+ if (!arg0.empty() && !arg1.empty() && !arg2.empty()) {
+ var i0 = body(arg0.lo(), arg1.lo(), arg2.lo());
+ var i1 = body(arg0.lo(), arg1.lo(), arg2.hi());
+ var i2 = body(arg0.lo(), arg1.hi(), arg2.lo());
+ var i3 = body(arg0.lo(), arg1.hi(), arg2.hi());
+ var i4 = body(arg0.hi(), arg1.lo(), arg2.lo());
+ var i5 = body(arg0.hi(), arg1.lo(), arg2.hi());
+ var i6 = body(arg0.hi(), arg1.hi(), arg2.lo());
+ var i7 = body(arg0.hi(), arg1.hi(), arg2.hi());
+
+ var low = Math.min(i0.lo(), i1.lo(), i2.lo(), i3.lo(), i4.lo(), i5.lo(), i6.lo(), i7.lo());
+ var high = Math.max(i0.hi(), i1.hi(), i2.hi(), i3.hi(), i4.hi(), i5.hi(), i6.hi(), i7.hi());
+ var hasNaN = i0.hasNaN() || i1.hasNaN() || i2.hasNaN() || i3.hasNaN() || i4.hasNaN() || i5.hasNaN() || i6.hasNaN() || i7.hasNaN();
+
+ ret = tcuInterval.withParams(hasNaN, low, high);
+ }
+
+ if (arg0.hasNaN() || arg1.hasNaN() || arg2.hasNaN()) {
+ ret = ret.operatorOrBinary(new tcuInterval.Interval(NaN));
+ }
+
+ return ret;
+};
+
+/** @const */ tcuInterval.POSITIVE_INFINITY = new tcuInterval.Interval(Infinity);
+/** @const */ tcuInterval.NEGATIVE_INFINITY = new tcuInterval.Interval(-Infinity);
+/** @const */ tcuInterval.ZERO = new tcuInterval.Interval(0);
+/** @const */ tcuInterval.NAN = new tcuInterval.Interval(NaN);
+});