DenseAD: access the value and derivatives of Evaluations via accessor functions

this allows some flexibility of how an Evaluation object is
represented internally. the main motivation for this is to allow using
SIMD instruction which expect special data types as their operants.
This commit is contained in:
Andreas Lauser
2016-10-20 17:11:12 +02:00
parent e047e85f54
commit 66ec787438
5 changed files with 221 additions and 204 deletions

View File

@@ -97,57 +97,57 @@ void testOperators(const Scalar tolerance)
// test the non-inplace operators
{
Eval a = xEval + yEval;
if (std::abs(a.value - (x + y)) > tolerance)
if (std::abs(a.value() - (x + y)) > tolerance)
throw std::logic_error("oops: operator+");
Eval b = xEval + c;
if (std::abs(b.value - (x + c)) > tolerance)
if (std::abs(b.value() - (x + c)) > tolerance)
throw std::logic_error("oops: operator+");
Eval d = xEval + cEval;
if (std::abs(d.value - (x + c)) > tolerance)
if (std::abs(d.value() - (x + c)) > tolerance)
throw std::logic_error("oops: operator+");
}
{
Eval a = xEval - yEval;
if (std::abs(a.value - (x - y)) > tolerance)
if (std::abs(a.value() - (x - y)) > tolerance)
throw std::logic_error("oops: operator-");
Eval b = xEval - c;
if (std::abs(b.value - (x - c)) > tolerance)
if (std::abs(b.value() - (x - c)) > tolerance)
throw std::logic_error("oops: operator-");
Eval d = xEval - cEval;
if (std::abs(d.value - (x - c)) > tolerance)
if (std::abs(d.value() - (x - c)) > tolerance)
throw std::logic_error("oops: operator-");
}
{
Eval a = xEval*yEval;
if (std::abs(a.value - (x*y)) > tolerance)
if (std::abs(a.value() - (x*y)) > tolerance)
throw std::logic_error("oops: operator*");
Eval b = xEval*c;
if (std::abs(b.value - (x*c)) > tolerance)
if (std::abs(b.value() - (x*c)) > tolerance)
throw std::logic_error("oops: operator*");
Eval d = xEval*cEval;
if (std::abs(d.value - (x*c)) > tolerance)
if (std::abs(d.value() - (x*c)) > tolerance)
throw std::logic_error("oops: operator*");
}
{
Eval a = xEval/yEval;
if (std::abs(a.value - (x/y)) > tolerance)
if (std::abs(a.value() - (x/y)) > tolerance)
throw std::logic_error("oops: operator/");
Eval b = xEval/c;
if (std::abs(b.value - (x/c)) > tolerance)
if (std::abs(b.value() - (x/c)) > tolerance)
throw std::logic_error("oops: operator/");
Eval d = xEval/cEval;
if (std::abs(d.value - (x/c)) > tolerance)
if (std::abs(d.value() - (x/c)) > tolerance)
throw std::logic_error("oops: operator/");
}
@@ -155,68 +155,68 @@ void testOperators(const Scalar tolerance)
{
Eval a = xEval;
a += yEval;
if (std::abs(a.value - (x + y)) > tolerance)
if (std::abs(a.value() - (x + y)) > tolerance)
throw std::logic_error("oops: operator+");
Eval b = xEval;
b += c;
if (std::abs(b.value - (x + c)) > tolerance)
if (std::abs(b.value() - (x + c)) > tolerance)
throw std::logic_error("oops: operator+");
Eval d = xEval;
d += cEval;
if (std::abs(d.value - (x + c)) > tolerance)
if (std::abs(d.value() - (x + c)) > tolerance)
throw std::logic_error("oops: operator+");
}
{
Eval a = xEval;
a -= yEval;
if (std::abs(a.value - (x - y)) > tolerance)
if (std::abs(a.value() - (x - y)) > tolerance)
throw std::logic_error("oops: operator-");
Eval b = xEval;
b -= c;
if (std::abs(b.value - (x - c)) > tolerance)
if (std::abs(b.value() - (x - c)) > tolerance)
throw std::logic_error("oops: operator-");
Eval d = xEval;
d -= cEval;
if (std::abs(d.value - (x - c)) > tolerance)
if (std::abs(d.value() - (x - c)) > tolerance)
throw std::logic_error("oops: operator-");
}
{
Eval a = xEval;
a *= yEval;
if (std::abs(a.value - (x*y)) > tolerance)
if (std::abs(a.value() - (x*y)) > tolerance)
throw std::logic_error("oops: operator*");
Eval b = xEval;
b *= c;
if (std::abs(b.value - (x*c)) > tolerance)
if (std::abs(b.value() - (x*c)) > tolerance)
throw std::logic_error("oops: operator*");
Eval d = xEval;
d *= cEval;
if (std::abs(d.value - (x*c)) > tolerance)
if (std::abs(d.value() - (x*c)) > tolerance)
throw std::logic_error("oops: operator*");
}
{
Eval a = xEval;
a /= yEval;
if (std::abs(a.value - (x/y)) > tolerance)
if (std::abs(a.value() - (x/y)) > tolerance)
throw std::logic_error("oops: operator/");
Eval b = xEval;
b /= c;
if (std::abs(b.value - (x/c)) > tolerance)
if (std::abs(b.value() - (x/c)) > tolerance)
throw std::logic_error("oops: operator/");
Eval d = xEval;
d /= cEval;
if (std::abs(d.value - (x/c)) > tolerance)
if (std::abs(d.value() - (x/c)) > tolerance)
throw std::logic_error("oops: operator/");
}
@@ -276,16 +276,16 @@ void test1DFunction(AdFn* adFn, ClassicFn* classicFn, Scalar xMin = 1e-6, Scalar
Scalar yStar2 = classicFn(x + eps);
Scalar yPrime = (yStar2 - yStar1)/(2*eps);
if (std::abs(y-yEval.value) > 5e-14)
if (std::abs(y-yEval.value()) > 5e-14)
throw std::logic_error("oops: value");
Scalar deltaAbs = std::abs(yPrime - yEval.derivatives[0]);
Scalar deltaAbs = std::abs(yPrime - yEval.derivative(0));
Scalar deltaRel = std::abs(deltaAbs/yPrime);
if (deltaAbs > 1000*eps && deltaRel > 1000*eps)
throw std::logic_error("oops: derivative @"+std::to_string((long double) x)+": "
+ std::to_string((long double) yPrime) + " vs "
+ std::to_string((long double) yEval.derivatives[0])
+ " delta: " + std::to_string((long double) std::abs(yPrime - yEval.derivatives[0])));
+ std::to_string((long double) yEval.derivative(0))
+ " delta: " + std::to_string((long double) std::abs(yPrime - yEval.derivative(0))));
}
}
@@ -312,17 +312,17 @@ void test2DFunction1(AdFn* adFn, ClassicFn* classicFn, Scalar xMin, Scalar xMax,
Scalar zStar2 = classicFn(x + eps, y);
Scalar zPrime = (zStar2 - zStar1)/(2.*eps);
if (std::abs(z - zEval.value)/std::abs(z + zEval.value)
if (std::abs(z - zEval.value())/std::abs(z + zEval.value())
> std::numeric_limits<Scalar>::epsilon()*1e2)
throw std::logic_error("oops: value");
Scalar deltaAbs = std::abs(zPrime - zEval.derivatives[0]);
Scalar deltaAbs = std::abs(zPrime - zEval.derivative(0));
Scalar deltaRel = std::abs(deltaAbs/zPrime);
if (deltaAbs > 1000*eps && deltaRel > 1000*eps)
throw std::logic_error("oops: derivative @"+std::to_string((long double) x)+": "
+ std::to_string((long double) zPrime) + " vs "
+ std::to_string((long double) zEval.derivatives[0])
+ " delta: " + std::to_string((long double) std::abs(zPrime - zEval.derivatives[0])));
+ std::to_string((long double) zEval.derivative(0))
+ " delta: " + std::to_string((long double) std::abs(zPrime - zEval.derivative(0))));
}
}
@@ -349,17 +349,17 @@ void test2DFunction2(AdFn* adFn, ClassicFn* classicFn, Scalar x, Scalar yMin, Sc
Scalar zStar2 = classicFn(x, y + eps);
Scalar zPrime = (zStar2 - zStar1)/(2*eps);
if (std::abs(z - zEval.value)/std::abs(z + zEval.value)
if (std::abs(z - zEval.value())/std::abs(z + zEval.value())
> std::numeric_limits<Scalar>::epsilon()*1e2)
throw std::logic_error("oops: value");
Scalar deltaAbs = std::abs(zPrime - zEval.derivatives[1]);
Scalar deltaAbs = std::abs(zPrime - zEval.derivative(1));
Scalar deltaRel = std::abs(deltaAbs/zPrime);
if (deltaAbs > 1000*eps && deltaRel > 1000*eps)
throw std::logic_error("oops: derivative @"+std::to_string((long double) x)+": "
+ std::to_string((long double) zPrime) + " vs "
+ std::to_string((long double) zEval.derivatives[1])
+ " delta: " + std::to_string((long double) std::abs(zPrime - zEval.derivatives[1])));
+ std::to_string((long double) zEval.derivative(1))
+ " delta: " + std::to_string((long double) std::abs(zPrime - zEval.derivative(1))));
}
}
@@ -388,19 +388,19 @@ void testPowBase(Scalar baseMin = 1e-2, Scalar baseMax = 100)
Scalar zStar2 = pow(base + eps, exp);
Scalar zPrime = (zStar2 - zStar1)/(2*eps);
if (std::abs(z - zEval2.value)/std::abs(z + zEval2.value)
if (std::abs(z - zEval2.value())/std::abs(z + zEval2.value())
> std::numeric_limits<Scalar>::epsilon()*1e2)
throw std::logic_error("oops: value");
Scalar deltaAbs = std::abs(zPrime - zEval1.derivatives[0]);
Scalar deltaAbs = std::abs(zPrime - zEval1.derivative(0));
Scalar deltaRel = std::abs(deltaAbs/zPrime);
if (deltaAbs > 1000*eps && deltaRel > 1000*eps)
throw std::logic_error("oops: derivative @"+std::to_string((long double) base)+": "
+ std::to_string((long double) zPrime) + " vs "
+ std::to_string((long double) zEval1.derivatives[0])
+ " delta: " + std::to_string((long double) std::abs(zPrime - zEval1.derivatives[0])));
+ std::to_string((long double) zEval1.derivative(0))
+ " delta: " + std::to_string((long double) std::abs(zPrime - zEval1.derivative(0))));
if (!EvalToolbox::isSame(zEval1, zEval2, /*tolerance=*/std::numeric_limits<Scalar>::epsilon()*1e3*zEval1.value))
if (!EvalToolbox::isSame(zEval1, zEval2, /*tolerance=*/std::numeric_limits<Scalar>::epsilon()*1e3*zEval1.value()))
throw std::logic_error("oops: pow(Eval, Scalar) != pow(Eval, Eval)");
}
}
@@ -430,19 +430,19 @@ void testPowExp(Scalar expMin = -100, Scalar expMax = 100)
Scalar zStar2 = pow(base, exp + eps);
Scalar zPrime = (zStar2 - zStar1)/(2*eps);
if (std::abs(z - zEval2.value)/std::abs(z + zEval2.value)
if (std::abs(z - zEval2.value())/std::abs(z + zEval2.value())
> std::numeric_limits<Scalar>::epsilon()*1e2)
throw std::logic_error("oops: value");
Scalar deltaAbs = std::abs(zPrime - zEval1.derivatives[1]);
Scalar deltaAbs = std::abs(zPrime - zEval1.derivative(1));
Scalar deltaRel = std::abs(deltaAbs/zPrime);
if (deltaAbs > 1000*eps && deltaRel > 1000*eps)
throw std::logic_error("oops: derivative @"+std::to_string((long double) base)+": "
+ std::to_string((long double) zPrime) + " vs "
+ std::to_string((long double) zEval1.derivatives[1])
+ " delta: " + std::to_string((long double) std::abs(zPrime - zEval1.derivatives[1])));
+ std::to_string((long double) zEval1.derivative(1))
+ " delta: " + std::to_string((long double) std::abs(zPrime - zEval1.derivative(1))));
if (!EvalToolbox::isSame(zEval1, zEval2, /*tolerance=*/std::numeric_limits<Scalar>::epsilon()*1e3*zEval1.value))
if (!EvalToolbox::isSame(zEval1, zEval2, /*tolerance=*/std::numeric_limits<Scalar>::epsilon()*1e3*zEval1.value()))
throw std::logic_error("oops: pow(Eval, Scalar) != pow(Eval, Eval)");
}
}
@@ -480,17 +480,17 @@ void testAtan2()
Scalar zStar2 = atan2(x + eps, y + eps);
Scalar zPrime = (zStar2 - zStar1)/(2*eps);
if (std::abs(z - zEval.value)/std::abs(z + zEval.value)
if (std::abs(z - zEval.value())/std::abs(z + zEval.value())
> std::numeric_limits<Scalar>::epsilon()*1e2)
throw std::logic_error("oops: value");
Scalar deltaAbs = std::abs(zPrime - zEval.derivatives[0]);
Scalar deltaAbs = std::abs(zPrime - zEval.derivative(0));
Scalar deltaRel = std::abs(deltaAbs/zPrime);
if (deltaAbs > 1000*eps && deltaRel > 1000*eps)
throw std::logic_error("oops: derivative @("+std::to_string((long double) x)+","+std::to_string((long double) y)+"): "
+ std::to_string((long double) zPrime) + " vs "
+ std::to_string((long double) zEval.derivatives[0])
+ " delta: " + std::to_string((long double) std::abs(zPrime - zEval.derivatives[0])));
+ std::to_string((long double) zEval.derivative(0))
+ " delta: " + std::to_string((long double) std::abs(zPrime - zEval.derivative(0))));
}
}