Remove extraneous initial and final evals.

Change-Id: I80ed87435f399cbf452c68be7ea1e7139696aa4a
diff --git a/internal/ceres/line_search_minimizer.cc b/internal/ceres/line_search_minimizer.cc
index 636289f..ca7d639 100644
--- a/internal/ceres/line_search_minimizer.cc
+++ b/internal/ceres/line_search_minimizer.cc
@@ -124,7 +124,9 @@
     return;
   }
 
+  summary->initial_cost = current_state.cost + summary->fixed_cost;
   iteration_summary.cost = current_state.cost + summary->fixed_cost;
+
   iteration_summary.gradient_max_norm = current_state.gradient_max_norm;
 
   // The initial gradient max_norm is bounded from below so that we do
diff --git a/internal/ceres/solver_impl.cc b/internal/ceres/solver_impl.cc
index 3dfbb67..9b56f28 100644
--- a/internal/ceres/solver_impl.cc
+++ b/internal/ceres/solver_impl.cc
@@ -77,6 +77,30 @@
   double* parameters_;
 };
 
+// Macro used to evaluate initial and final residuals, gradient and
+// jacobian if requested by the user.
+//
+// We need a macro here, instead of a simple function call, since the
+// multiplexing happens on variable names.
+#define CERES_EVALUATE(which)                                           \
+  Evaluator::Evaluate(                                                  \
+      original_program,                                                 \
+      options.num_threads,                                              \
+      &summary->final_cost,                                             \
+      options.return_ ## which ## _residuals ? &summary->which ## _residuals : NULL, \
+      options.return_ ## which ## _gradient ? &summary->which ## _gradient : NULL, \
+      options.return_ ## which ## _jacobian ? &summary->which ## _jacobian : NULL)
+
+void SetSummaryFinalCost(Solver::Summary* summary) {
+  summary->final_cost = summary->initial_cost;
+  // We need the loop here, instead of just looking at the last
+  // iteration because the minimizer maybe making non-monotonic steps.
+  for (int i = 0; i < summary->iterations.size(); ++i) {
+    const IterationSummary& iteration_summary = summary->iterations[i];
+    summary->final_cost = min(iteration_summary.cost, summary->final_cost);
+  }
+}
+
 // Callback for logging the state of the minimizer to STDERR or STDOUT
 // depending on the user's preferences and logging level.
 class TrustRegionLoggingCallback : public IterationCallback {
@@ -373,27 +397,18 @@
   }
 
   event_logger.AddEvent("Init");
+
   // Evaluate the initial cost, residual vector and the jacobian
-  // matrix if requested by the user. The initial cost needs to be
-  // computed on the original unpreprocessed problem, as it is used to
-  // determine the value of the "fixed" part of the objective function
-  // after the problem has undergone reduction.
-  if (!Evaluator::Evaluate(original_program,
-                           options.num_threads,
-                           &(summary->initial_cost),
-                           options.return_initial_residuals
-                           ? &summary->initial_residuals
-                           : NULL,
-                           options.return_initial_gradient
-                           ? &summary->initial_gradient
-                           : NULL,
-                           options.return_initial_jacobian
-                           ? &summary->initial_jacobian
-                           : NULL)) {
-    summary->termination_type = NUMERICAL_FAILURE;
-    summary->error = "Unable to evaluate the initial cost.";
-    LOG(ERROR) << summary->error;
-    return;
+  // matrix if requested by the user.
+  if (options.return_initial_residuals ||
+      options.return_initial_gradient ||
+      options.return_initial_jacobian) {
+    if (!CERES_EVALUATE(initial)) {
+      summary->termination_type = NUMERICAL_FAILURE;
+      summary->error = "Unable to evaluate the initial cost.";
+      LOG(ERROR) << summary->error;
+      return;
+    }
   }
 
   event_logger.AddEvent("InitialEvaluate");
@@ -470,24 +485,21 @@
     summary->termination_type = FUNCTION_TOLERANCE;
 
     double post_process_start_time = WallTimeInSeconds();
+
+
+
+
     // Evaluate the final cost, residual vector and the jacobian
     // matrix if requested by the user.
-    if (!Evaluator::Evaluate(original_program,
-                             options.num_threads,
-                             &summary->final_cost,
-                             options.return_final_residuals
-                             ? &summary->final_residuals
-                             : NULL,
-                             options.return_final_gradient
-                             ? &summary->final_gradient
-                             : NULL,
-                             options.return_final_jacobian
-                             ? &summary->final_jacobian
-                             : NULL)) {
-      summary->termination_type = NUMERICAL_FAILURE;
-      summary->error = "Unable to evaluate the final cost.";
-      LOG(ERROR) << summary->error;
-      return;
+    if (options.return_final_residuals ||
+        options.return_final_gradient ||
+        options.return_final_jacobian) {
+      if (!CERES_EVALUATE(final)) {
+        summary->termination_type = NUMERICAL_FAILURE;
+        summary->error = "Unable to evaluate the final cost.";
+        LOG(ERROR) << summary->error;
+        return;
+      }
     }
 
     // Ensure the program state is set to the user parameters on the way out.
@@ -588,6 +600,8 @@
                       summary);
   event_logger.AddEvent("Minimize");
 
+  SetSummaryFinalCost(summary);
+
   // If the user aborted mid-optimization or the optimization
   // terminated because of a numerical failure, then return without
   // updating user state.
@@ -604,35 +618,27 @@
 
   // Evaluate the final cost, residual vector and the jacobian
   // matrix if requested by the user.
-  if (!Evaluator::Evaluate(original_program,
-                           options.num_threads,
-                           &summary->final_cost,
-                           options.return_final_residuals
-                           ? &summary->final_residuals
-                           : NULL,
-                           options.return_final_gradient
-                           ? &summary->final_gradient
-                           : NULL,
-                           options.return_final_jacobian
-                           ? &summary->final_jacobian
-                           : NULL)) {
-    // This failure requires careful handling.
-    //
-    // At this point, we have modified the user's state, but the
-    // evaluation failed and we inform him of NUMERICAL_FAILURE. Ceres
-    // guarantees that user's state is not modified if the solver
-    // returns with NUMERICAL_FAILURE. Thus, we need to restore the
-    // user's state to their original values.
+  if (options.return_final_residuals ||
+      options.return_final_gradient ||
+      options.return_final_jacobian) {
+    if (!CERES_EVALUATE(final)) {
+      // This failure requires careful handling.
+      //
+      // At this point, we have modified the user's state, but the
+      // evaluation failed and we inform him of NUMERICAL_FAILURE. Ceres
+      // guarantees that user's state is not modified if the solver
+      // returns with NUMERICAL_FAILURE. Thus, we need to restore the
+      // user's state to their original values.
+      reduced_program->StateVectorToParameterBlocks(original_parameters.data());
+      reduced_program->CopyParameterBlockStateToUserState();
 
-    reduced_program->StateVectorToParameterBlocks(original_parameters.data());
-    reduced_program->CopyParameterBlockStateToUserState();
+      summary->termination_type = NUMERICAL_FAILURE;
+      summary->error = "Unable to evaluate the final cost.";
+      LOG(ERROR) << summary->error;
 
-    summary->termination_type = NUMERICAL_FAILURE;
-    summary->error = "Unable to evaluate the final cost.";
-    LOG(ERROR) << summary->error;
-
-    event_logger.AddEvent("PostProcess");
-    return;
+      event_logger.AddEvent("PostProcess");
+      return;
+    }
   }
 
   // Ensure the program state is set to the user parameters on the way out.
@@ -729,26 +735,16 @@
   }
 
   // Evaluate the initial cost, residual vector and the jacobian
-  // matrix if requested by the user. The initial cost needs to be
-  // computed on the original unpreprocessed problem, as it is used to
-  // determine the value of the "fixed" part of the objective function
-  // after the problem has undergone reduction.
-  if (!Evaluator::Evaluate(original_program,
-                           options.num_threads,
-                           &(summary->initial_cost),
-                           options.return_initial_residuals
-                           ? &summary->initial_residuals
-                           : NULL,
-                           options.return_initial_gradient
-                           ? &summary->initial_gradient
-                           : NULL,
-                           options.return_initial_jacobian
-                           ? &summary->initial_jacobian
-                           : NULL)) {
-    summary->termination_type = NUMERICAL_FAILURE;
-    summary->error = "Unable to evaluate the initial cost.";
-    LOG(ERROR) << summary->error;
-    return;
+  // matrix if requested by the user.
+  if (options.return_initial_residuals ||
+      options.return_initial_gradient ||
+      options.return_initial_jacobian) {
+    if (!CERES_EVALUATE(initial)) {
+      summary->termination_type = NUMERICAL_FAILURE;
+      summary->error = "Unable to evaluate the initial cost.";
+      LOG(ERROR) << summary->error;
+      return;
+    }
   }
 
   original_program->SetParameterBlockStatePtrsToUserStatePtrs();
@@ -799,24 +795,20 @@
     summary->termination_type = FUNCTION_TOLERANCE;
 
     const double post_process_start_time = WallTimeInSeconds();
+
+    SetSummaryFinalCost(summary);
+
     // Evaluate the final cost, residual vector and the jacobian
     // matrix if requested by the user.
-    if (!Evaluator::Evaluate(original_program,
-                             options.num_threads,
-                             &summary->final_cost,
-                             options.return_final_residuals
-                             ? &summary->final_residuals
-                             : NULL,
-                             options.return_final_gradient
-                             ? &summary->final_gradient
-                             : NULL,
-                             options.return_final_jacobian
-                             ? &summary->final_jacobian
-                             : NULL)) {
-      summary->termination_type = NUMERICAL_FAILURE;
-      summary->error = "Unable to evaluate the final cost.";
-      LOG(ERROR) << summary->error;
-      return;
+    if (options.return_final_residuals ||
+        options.return_final_gradient ||
+        options.return_final_jacobian) {
+      if (!CERES_EVALUATE(final)) {
+        summary->termination_type = NUMERICAL_FAILURE;
+        summary->error = "Unable to evaluate the final cost.";
+        LOG(ERROR) << summary->error;
+        return;
+      }
     }
 
     // Ensure the program state is set to the user parameters on the way out.
@@ -868,35 +860,30 @@
   reduced_program->StateVectorToParameterBlocks(parameters.data());
   reduced_program->CopyParameterBlockStateToUserState();
 
+  SetSummaryFinalCost(summary);
+
   // Evaluate the final cost, residual vector and the jacobian
   // matrix if requested by the user.
-  if (!Evaluator::Evaluate(original_program,
-                           options.num_threads,
-                           &summary->final_cost,
-                           options.return_final_residuals
-                           ? &summary->final_residuals
-                           : NULL,
-                           options.return_final_gradient
-                           ? &summary->final_gradient
-                           : NULL,
-                           options.return_final_jacobian
-                           ? &summary->final_jacobian
-                           : NULL)) {
-    // This failure requires careful handling.
-    //
-    // At this point, we have modified the user's state, but the
-    // evaluation failed and we inform him of NUMERICAL_FAILURE. Ceres
-    // guarantees that user's state is not modified if the solver
-    // returns with NUMERICAL_FAILURE. Thus, we need to restore the
-    // user's state to their original values.
+  if (options.return_final_residuals ||
+      options.return_final_gradient ||
+      options.return_final_jacobian) {
+    if (!CERES_EVALUATE(final)) {
+      // This failure requires careful handling.
+      //
+      // At this point, we have modified the user's state, but the
+      // evaluation failed and we inform him of NUMERICAL_FAILURE. Ceres
+      // guarantees that user's state is not modified if the solver
+      // returns with NUMERICAL_FAILURE. Thus, we need to restore the
+      // user's state to their original values.
 
-    reduced_program->StateVectorToParameterBlocks(original_parameters.data());
-    reduced_program->CopyParameterBlockStateToUserState();
+      reduced_program->StateVectorToParameterBlocks(original_parameters.data());
+      reduced_program->CopyParameterBlockStateToUserState();
 
-    summary->termination_type = NUMERICAL_FAILURE;
-    summary->error = "Unable to evaluate the final cost.";
-    LOG(ERROR) << summary->error;
-    return;
+      summary->termination_type = NUMERICAL_FAILURE;
+      summary->error = "Unable to evaluate the final cost.";
+      LOG(ERROR) << summary->error;
+      return;
+    }
   }
 
   // Ensure the program state is set to the user parameters on the way out.
diff --git a/internal/ceres/trust_region_minimizer.cc b/internal/ceres/trust_region_minimizer.cc
index 5ea9374..fc405f5 100644
--- a/internal/ceres/trust_region_minimizer.cc
+++ b/internal/ceres/trust_region_minimizer.cc
@@ -145,6 +145,7 @@
     return;
   }
 
+  summary->initial_cost = cost + summary->fixed_cost;
   iteration_summary.cost = cost + summary->fixed_cost;
 
   int num_consecutive_nonmonotonic_steps = 0;
diff --git a/internal/ceres/wall_time.cc b/internal/ceres/wall_time.cc
index 8dc4e1f..7de7e06 100644
--- a/internal/ceres/wall_time.cc
+++ b/internal/ceres/wall_time.cc
@@ -86,10 +86,10 @@
   last_event_time_ = current_time;
 
   StringAppendF(&events_,
-                "  %25s : %5.3e   %5.3e\n",
+                "  %25s : %8.3f   %8.3f\n",
                 event_name.c_str(),
-                relative_time_delta,
-                absolute_time_delta);
+                1000 * relative_time_delta,
+                1000 * absolute_time_delta);
 }
 
 }  // namespace internal