Updated NumericalDiff finite difference step so it is never smaller than epsilon

libeigen/eigen!2733

Closes #3105
diff --git a/unsupported/Eigen/src/NumericalDiff/NumericalDiff.h b/unsupported/Eigen/src/NumericalDiff/NumericalDiff.h
index a0b8c51..f07d3cc 100644
--- a/unsupported/Eigen/src/NumericalDiff/NumericalDiff.h
+++ b/unsupported/Eigen/src/NumericalDiff/NumericalDiff.h
@@ -87,10 +87,8 @@
 
     // Function Body
     for (int j = 0; j < n; ++j) {
-      h = eps * abs(x[j]);
-      if (h == 0.) {
-        h = eps;
-      }
+      const Scalar x_abs = abs(x[j]);
+      h = numext::maxi(x_abs, Scalar(1)) * eps;
       switch (mode) {
         case Forward:
           x[j] += h;
diff --git a/unsupported/test/NumericalDiff.cpp b/unsupported/test/NumericalDiff.cpp
index b46dfb2..bfde6b6 100644
--- a/unsupported/test/NumericalDiff.cpp
+++ b/unsupported/test/NumericalDiff.cpp
@@ -97,7 +97,26 @@
   VERIFY_IS_APPROX(jac, actual_jac);
 }
 
+void test_small() {
+  VectorXd x(3);
+  MatrixXd jac(15, 3);
+  MatrixXd actual_jac(15, 3);
+  my_functor functor;
+
+  x << 0.082, 1.13, 1e-8;
+
+  // real one
+  functor.actual_df(x, actual_jac);
+
+  // using NumericalDiff
+  NumericalDiff<my_functor, Central> numDiff(functor);
+  numDiff.df(x, jac);
+
+  VERIFY_IS_APPROX(jac, actual_jac);
+}
+
 EIGEN_DECLARE_TEST(NumericalDiff) {
   CALL_SUBTEST(test_forward());
   CALL_SUBTEST(test_central());
+  CALL_SUBTEST(test_small());
 }