> For the complete documentation index, see [llms.txt](https://ceres-solver-tutorial-cn.gitbook.io/ceres/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ceres-solver-tutorial-cn.gitbook.io/ceres/modeling-non-linear-least-squares/main-class-interface/evaluatationcallback.md).

# EvaluatationCallback

```cpp
class EvaluationCallback
```

用于在 Ceres 评估残差或 Jacobian 之前进行回调的接口：

```cpp
class EvaluationCallback {
 public:
  virtual ~EvaluationCallback();
  virtual void PrepareForEvaluation(bool evaluate_jacobians,
                                    bool new_evaluation_point) = 0;
};
```

```cpp
void EvaluationCallback::PrepareForEvaluation(
    bool evaluate_jacobians, 
    bool new_evaluation_point)
```

Ceres will call [`EvaluationCallback::PrepareForEvaluation()`](http://ceres-solver.org/nnls_modeling.html#_CPPv4N5ceres18EvaluationCallback20PrepareForEvaluationEbb) every time, and once before it computes the residuals and/or the Jacobians.

User parameters (the double\* values provided by the user) are fixed until the next call to [`EvaluationCallback::PrepareForEvaluation()`](http://ceres-solver.org/nnls_modeling.html#_CPPv4N5ceres18EvaluationCallback20PrepareForEvaluationEbb). If `new_evaluation_point == true`, then this is a new point that is different from the last evaluated point. Otherwise, it is the same point that was evaluated previously (either Jacobian or residual) and the user can use cached results from previous evaluations. If `evaluate_jacobians` is `true`, then Ceres will request Jacobians in the upcoming cost evaluation.

Using this callback interface, Ceres can notify you when it is about to evaluate the residuals or Jacobians. With the callback, you can share computation between residual blocks by doing the shared computation in [`EvaluationCallback::PrepareForEvaluation()`](http://ceres-solver.org/nnls_modeling.html#_CPPv4N5ceres18EvaluationCallback20PrepareForEvaluationEbb) before Ceres calls [`CostFunction::Evaluate()`](http://ceres-solver.org/nnls_modeling.html#_CPPv4NK5ceres12CostFunction8EvaluateEPPCKdPdPPd) on all the residuals. It also enables caching results between a pure residual evaluation and a residual & Jacobian evaluation, via the `new_evaluation_point` argument.

One use case for this callback is if the cost function compute is moved to the GPU. In that case, the prepare call does the actual cost function evaluation, and subsequent calls from Ceres to the actual cost functions merely copy the results from the GPU onto the corresponding blocks for Ceres to plug into the solver.

**Note**: Ceres provides no mechanism to share data other than the notification from the callback. Users must provide access to pre-computed shared data to their cost functions behind the scenes; this all happens without Ceres knowing. One approach is to put a pointer to the shared data in each cost function (recommended) or to use a global shared variable (discouraged; bug-prone). As far as Ceres is concerned, it is evaluating cost functions like any other; it just so happens that behind the scenes the cost functions reuse pre-computed data to execute faster. See [examples/evaluation\_callback\_example.cc](https://ceres-solver.googlesource.com/ceres-solver/+/master/examples/evaluation_callback_example.cc) for an example.

See `evaluation_callback_test.cc` for code that explicitly verifies the preconditions between [`EvaluationCallback::PrepareForEvaluation()`](http://ceres-solver.org/nnls_modeling.html#_CPPv4N5ceres18EvaluationCallback20PrepareForEvaluationEbb) and [`CostFunction::Evaluate()`](http://ceres-solver.org/nnls_modeling.html#_CPPv4NK5ceres12CostFunction8EvaluateEPPCKdPdPPd).
