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