Support midpoint Jet

Provide autodiff support for C++20 std::midpoint if the standard is
active.

Change-Id: I1308a1e514bef4c74f08f655cbf803fa43503ce5
This commit is contained in:
Sergiu Deitsch
2021-11-25 20:30:03 +01:00
parent 8426526dff
commit b1391e0625
2 changed files with 40 additions and 0 deletions
+16
View File
@@ -418,6 +418,7 @@ using std::tanh;
#ifdef CERES_HAS_CPP20
using std::lerp;
using std::midpoint;
#endif // defined(CERES_HAS_CPP20)
// Legacy names from pre-C++11 days.
@@ -867,6 +868,21 @@ inline Jet<T, N> lerp(const Jet<T, N>& a,
return Jet<T, N>{lerp(a.a, b.a, t.a),
(T(1) - t.a) * a.v + t.a * b.v + (b.a - a.a) * t.v};
}
// Computes the midpoint a + (b - a) / 2.
//
// Differentiating midpoint(a, b) with respect to a and b gives:
//
// d/da midpoint(a, b) = 1/2
// d/db midpoint(a, b) = 1/2
//
// with the dual representation given by
//
// midpoint(a + da, b + db) ~= midpoint(a, b) + (da + db) / 2 .
template <typename T, int N>
inline Jet<T, N> midpoint(const Jet<T, N>& a, const Jet<T, N>& b) {
return Jet<T, N>{midpoint(a.a, b.a), T(0.5) * (a.v + b.v)};
}
#endif // defined(CERES_HAS_CPP20)
// atan2(b + db, a + da) ~= atan2(b, a) + (- b da + a db) / (a^2 + b^2)
+24
View File
@@ -943,6 +943,30 @@ TEST(Jet, Jet) {
VL << "v = " << v;
ExpectJetsClose(z, v);
}
{ // Check that midpoint(x, y) = (x + y) / 2
J z = midpoint(x, y);
J v = (x + y) / J{2};
VL << "z = " << z;
VL << "v = " << v;
ExpectJetsClose(z, v);
}
{ // Check that midpoint(x, x) = x
J z = midpoint(x, x);
VL << "z = " << z;
ExpectJetsClose(z, x);
}
{ // Check that midpoint(x, x) = x while avoiding overflow
J x = MakeJet(std::numeric_limits<double>::min(), 1, 2);
J y = MakeJet(std::numeric_limits<double>::max(), 3, 4);
J z = midpoint(x, y);
J v = x + (y - x) / J{2};
VL << "z = " << z;
VL << "v = " << v;
ExpectJetsClose(z, v);
}
#endif // defined(CERES_HAS_CPP20)
{