Add floor and ceil functions to the Jet implementation. Change-Id: I72ebfb0e9ade2964dbf3a014225ead345d5ae352
diff --git a/include/ceres/jet.h b/include/ceres/jet.h index 77c99f4..b89f807 100644 --- a/include/ceres/jet.h +++ b/include/ceres/jet.h
@@ -391,6 +391,8 @@ inline double sinh (double x) { return std::sinh(x); } inline double cosh (double x) { return std::cosh(x); } inline double tanh (double x) { return std::tanh(x); } +inline double floor (double x) { return std::floor(x); } +inline double ceil (double x) { return std::ceil(x); } inline double pow (double x, double y) { return std::pow(x, y); } inline double atan2(double y, double x) { return std::atan2(y, x); } @@ -485,6 +487,24 @@ return Jet<T, N>(tanh_a, tmp * f.v); } +// The floor function should be used with extreme care as this operation will +// result in a zero derivative which provides no information to the solver. +// +// floor(a + h) ~= floor(a) + 0 +template <typename T, int N> inline +Jet<T, N> floor(const Jet<T, N>& f) { + return Jet<T, N>(floor(f.a)); +} + +// The ceil function should be used with extreme care as this operation will +// result in a zero derivative which provides no information to the solver. +// +// ceil(a + h) ~= ceil(a) + 0 +template <typename T, int N> inline +Jet<T, N> ceil(const Jet<T, N>& f) { + return Jet<T, N>(ceil(f.a)); +} + // Bessel functions of the first kind with integer order equal to 0, 1, n. inline double BesselJ0(double x) { return j0(x); } inline double BesselJ1(double x) { return j1(x); }
diff --git a/internal/ceres/jet_test.cc b/internal/ceres/jet_test.cc index 636018a..97f9366 100644 --- a/internal/ceres/jet_test.cc +++ b/internal/ceres/jet_test.cc
@@ -469,6 +469,48 @@ // See formula http://dlmf.nist.gov/10.6.E1 ExpectJetsClose(BesselJ0(z) + BesselJn(2, z), (2.0 / z) * BesselJ1(z)); } + + { // Check that floor of a positive number works. + J a = MakeJet(0.1, -2.7, 1e-3); + J b = floor(a); + J expected = MakeJet(floor(a.a), 0.0, 0.0); + ExpectJetsClose(expected, b); + } + + { // Check that floor of a negative number works. + J a = MakeJet(-1.1, -2.7, 1e-3); + J b = floor(a); + J expected = MakeJet(floor(a.a), 0.0, 0.0); + ExpectJetsClose(expected, b); + } + + { // Check that floor of a positive number works. + J a = MakeJet(10.123, -2.7, 1e-3); + J b = floor(a); + J expected = MakeJet(floor(a.a), 0.0, 0.0); + ExpectJetsClose(expected, b); + } + + { // Check that ceil of a positive number works. + J a = MakeJet(0.1, -2.7, 1e-3); + J b = ceil(a); + J expected = MakeJet(ceil(a.a), 0.0, 0.0); + ExpectJetsClose(expected, b); + } + + { // Check that ceil of a negative number works. + J a = MakeJet(-1.1, -2.7, 1e-3); + J b = ceil(a); + J expected = MakeJet(ceil(a.a), 0.0, 0.0); + ExpectJetsClose(expected, b); + } + + { // Check that ceil of a positive number works. + J a = MakeJet(10.123, -2.7, 1e-3); + J b = ceil(a); + J expected = MakeJet(ceil(a.a), 0.0, 0.0); + ExpectJetsClose(expected, b); + } } TEST(Jet, JetsInEigenMatrices) {