aboutsummaryrefslogtreecommitdiff
path: root/internal/ceres/program_evaluator.h
diff options
context:
space:
mode:
Diffstat (limited to 'internal/ceres/program_evaluator.h')
-rw-r--r--internal/ceres/program_evaluator.h23
1 files changed, 21 insertions, 2 deletions
diff --git a/internal/ceres/program_evaluator.h b/internal/ceres/program_evaluator.h
index 8aa2a39..672c233 100644
--- a/internal/ceres/program_evaluator.h
+++ b/internal/ceres/program_evaluator.h
@@ -79,6 +79,9 @@
#ifndef CERES_INTERNAL_PROGRAM_EVALUATOR_H_
#define CERES_INTERNAL_PROGRAM_EVALUATOR_H_
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
#ifdef CERES_USE_OPENMP
#include <omp.h>
#endif
@@ -97,7 +100,13 @@
namespace ceres {
namespace internal {
-template<typename EvaluatePreparer, typename JacobianWriter>
+struct NullJacobianFinalizer {
+ void operator()(SparseMatrix* jacobian, int num_parameters) {}
+};
+
+template<typename EvaluatePreparer,
+ typename JacobianWriter,
+ typename JacobianFinalizer = NullJacobianFinalizer>
class ProgramEvaluator : public Evaluator {
public:
ProgramEvaluator(const Evaluator::Options &options, Program* program)
@@ -244,9 +253,10 @@ class ProgramEvaluator : public Evaluator {
}
if (!abort) {
+ const int num_parameters = program_->NumEffectiveParameters();
+
// Sum the cost and gradient (if requested) from each thread.
(*cost) = 0.0;
- int num_parameters = program_->NumEffectiveParameters();
if (gradient != NULL) {
VectorRef(gradient, num_parameters).setZero();
}
@@ -257,6 +267,15 @@ class ProgramEvaluator : public Evaluator {
VectorRef(evaluate_scratch_[i].gradient.get(), num_parameters);
}
}
+
+ // Finalize the Jacobian if it is available.
+ // `num_parameters` is passed to the finalizer so that additional
+ // storage can be reserved for additional diagonal elements if
+ // necessary.
+ if (jacobian != NULL) {
+ JacobianFinalizer f;
+ f(jacobian, num_parameters);
+ }
}
return !abort;
}