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) {