Add residuals and jacobian getters to TinySolver.

- Add methods to aceess the cached residuals and jacobian computed in
the optimization process in TinySolver. Usage of such methods will
retrieve the corresponding values associated with the converged
parameter.
- Reorder the Update() call to ensure that the jacobian/residuals
associated with the converged parameter are computed and cached.

Change-Id: If82e19d67d28b057833357f2c9a75b2d0fd139af
diff --git a/include/ceres/tiny_solver.h b/include/ceres/tiny_solver.h
index 9242cd0..f5cdfd8 100644
--- a/include/ceres/tiny_solver.h
+++ b/include/ceres/tiny_solver.h
@@ -286,14 +286,13 @@
         // model fits well.
         x = x_new_;
 
+        // TODO(sameeragarwal): Deal with failure.
+        Update(function, x);
         if (std::abs(cost_change) < options.function_tolerance) {
-          cost_ = f_x_new_.squaredNorm() / 2;
           summary.status = COST_CHANGE_TOO_SMALL;
           break;
         }
 
-        // TODO(sameeragarwal): Deal with failure.
-        Update(function, x);
         if (summary.gradient_max_norm < options.gradient_tolerance) {
           summary.status = GRADIENT_TOO_SMALL;
           break;
@@ -329,6 +328,16 @@
     return summary;
   }
 
+  Eigen::Matrix<Scalar, NUM_RESIDUALS, 1> Residuals() const {
+    // Residual updates are stored with the opposite sign.
+    return -residuals_;
+  }
+
+  Eigen::Matrix<Scalar, NUM_RESIDUALS, NUM_PARAMETERS> Jacobian() const {
+    // Undo the scaling applied to the jacobian matrix during Update().
+    return jacobian_ * jacobi_scaling_.cwiseInverse().asDiagonal();
+  }
+
   Options options;
   Summary summary;
 
diff --git a/internal/ceres/tiny_solver_test.cc b/internal/ceres/tiny_solver_test.cc
index 645ddc5..f8b9264 100644
--- a/internal/ceres/tiny_solver_test.cc
+++ b/internal/ceres/tiny_solver_test.cc
@@ -121,6 +121,14 @@
   TinySolver<Function> solver;
   solver.Solve(f, &x);
   EXPECT_NEAR(0.0, solver.summary.final_cost, 1e-10);
+
+  // Getter methods for residuals and jacobian should match the corresponding
+  // values evaluated at the converged parameter value.
+  Vec2 expected_residuals;
+  Eigen::Matrix<double, 2, 3> expected_jacobian;
+  f(x.data(), expected_residuals.data(), expected_jacobian.data());
+  EXPECT_TRUE(expected_residuals.isApprox(solver.Residuals()));
+  EXPECT_TRUE(expected_jacobian.isApprox(solver.Jacobian()));
 }
 
 // A test case for when the cost function is statically sized.