> 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/optimization-tutorial/non-linear-least-squares/derivation/numeric-derivatives.md).

# Numeric Derivatives

在某些情况下，定义一个模板化的代价函数是不现实的，例如在计算残差时需要调用一个闭源的库函数。在这种情况下，可以使用数值微分。用户定义一个计算残差值的函数，并用它构造一个 `NumericDiffCostFunction`，例如对于 $$f(x)=10-x$$ 来说，对应的 Functor 如下：

```cpp
struct NumericDiffCostFunctor {
  bool operator()(const double* const x, double* residual) const {
    residual[0] = 10.0 - x[0];
    return true;
  }
};
```

加入到 `Problem` 中去

```cpp
CostFunction* cost_function =
  new NumericDiffCostFunction<NumericDiffCostFunctor, ceres::CENTRAL, 1, 1>();
problem.AddResidualBlock(cost_function, nullptr, &x);
```

除了一个额外的模板参数表示计算数值导数所使用的方法之外，该结构与自动微分所使用的结构几乎完全相同。更多详情，请参阅 `NumericDiffCostFunction`。**一般来说，Ceres 建议使用自动微分而不是数值微分。C++ 模板的使用使自动微分变得高效，而数值微分成本高昂，容易出现数值错误，收敛速度较慢。**

## Footnotes

* [examples/helloworld\_numeric\_diff.cc](https://ceres-solver.googlesource.com/ceres-solver/+/master/examples/helloworld_numeric_diff.cc).
