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