Numeric Derivatives

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

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

加入到 Problem 中去

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

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

Footnotes

Last updated