support log10 jet Change-Id: I1425f7c8fc891cf941a162b8e5b427b5ab4e71da
diff --git a/include/ceres/jet.h b/include/ceres/jet.h index 62e9828..e45caf2 100644 --- a/include/ceres/jet.h +++ b/include/ceres/jet.h
@@ -404,6 +404,7 @@ using std::isnan; using std::isnormal; using std::log; +using std::log10; using std::log1p; using std::log2; using std::norm; @@ -473,6 +474,14 @@ return Jet<T, N>(log(f.a), f.v * a_inverse); } +// log10(a + h) ~= log10(a) + h / (a log(10)) +template <typename T, int N> +inline Jet<T, N> log10(const Jet<T, N>& f) { + // Most compilers will expand log(10) to a constant. + const T a_inverse = T(1.0) / (f.a * log(T(10.0))); + return Jet<T, N>(log10(f.a), f.v * a_inverse); +} + // log1p(a + h) ~= log1p(a) + h / (1 + a) template <typename T, int N> inline Jet<T, N> log1p(const Jet<T, N>& f) {
diff --git a/internal/ceres/jet_test.cc b/internal/ceres/jet_test.cc index 6a7011d..bceb9e4 100644 --- a/internal/ceres/jet_test.cc +++ b/internal/ceres/jet_test.cc
@@ -702,6 +702,17 @@ NumericalTest("exp2", exp2<double, 2>, 1e-5); NumericalTest("exp2", exp2<double, 2>, 1.0); + { // Check that log10(x) == log(x) / log(10) + J z = log10(x); + J w = log(x) / log(10.0); + VL << "z = " << z; + VL << "w = " << w; + ExpectJetsClose(z, w); + } + NumericalTest("log10", log10<double, 2>, 1e-5); + NumericalTest("log10", log10<double, 2>, 1.0); + NumericalTest("log10", log10<double, 2>, 98.76); + { // Check that log2(x) == log(x) / log(2) J z = log2(x); J w = log(x) / log(2.0);