Compute the gradient if requested in the evaluator
This extends the Evaluator interface to support evaluating the
gradient in addition to the residuals and jacobian, if requested.
bool Evaluate(const double* state,
double* cost,
double* residuals,
double* gradient, <----------- NEW
SparseMatrix* jacobian) = 0;
The ProgramEvaluator is extended to support the new gradient
evaluation. This required some gymnastics around the block
evaluate preparer, which now contains a scratch evaluate preparer
for the case that no jacobian is requested but the gradient is.
Gradient evaluation is a prerequisite for the planned suite of
first order methods, including nonlinear conjugate gradient,
CG_DESCENT, L-BFGS, trust region with line search, and more.
This also considerably refactors the evaluator_test to make it
shorter and check the results for all combinations of the optional
parameters [residuals, gradient, jacobian].
Change-Id: Ic7d0fec028dc5ffebc08ee079ad04eeaf6e02582
diff --git a/internal/ceres/trust_region_minimizer.cc b/internal/ceres/trust_region_minimizer.cc
index c475690..f990b80 100644
--- a/internal/ceres/trust_region_minimizer.cc
+++ b/internal/ceres/trust_region_minimizer.cc
@@ -161,7 +161,7 @@
// Do initial cost and Jacobian evaluation.
double cost = 0.0;
- if (!evaluator->Evaluate(x.data(), &cost, residuals.data(), jacobian)) {
+ if (!evaluator->Evaluate(x.data(), &cost, residuals.data(), NULL, jacobian)) {
LOG(WARNING) << "Terminating: Residual and Jacobian evaluation failed.";
summary->termination_type = NUMERICAL_FAILURE;
return;
@@ -362,7 +362,9 @@
// Try this step.
double new_cost;
- if (!evaluator->Evaluate(x_plus_delta.data(), &new_cost, NULL, NULL)) {
+ if (!evaluator->Evaluate(x_plus_delta.data(),
+ &new_cost,
+ NULL, NULL, NULL)) {
summary->termination_type = NUMERICAL_FAILURE;
LOG(WARNING) << "Terminating: Cost evaluation failed.";
return;
@@ -394,7 +396,11 @@
x_norm = x.norm();
// Step looks good, evaluate the residuals and Jacobian at this
// point.
- if (!evaluator->Evaluate(x.data(), &cost, residuals.data(), jacobian)) {
+ if (!evaluator->Evaluate(x.data(),
+ &cost,
+ residuals.data(),
+ NULL,
+ jacobian)) {
summary->termination_type = NUMERICAL_FAILURE;
LOG(WARNING) << "Terminating: Residual and Jacobian evaluation failed.";
return;