数值微分和解析微分
数值微分
在某些情况下,很难定义一个模板类cost functor
,这种情况下可以用数值微分。例如f(x)=10−x
struct CostFunctor {
bool operator()(const double* const x, double* residual) const {
residual[0] = 10.0 - x[0];
return true;
}
};
CostFunction* cost_function =
new NumericDiffCostFunction<NumericDiffCostFunctor, ceres::CENTRAL, 1, 1, 1>(
new NumericDiffCostFunctor)
problem.AddResidualBlock(cost_function, NULL, &x);
通常更推荐使用automatic differentiation
,因为它更高效,而数值微分存在数值误差,可能导致收敛速度变慢。
解析微分
在某些情况下,使用自动微分是不太可能的。自动微分依赖于链式求导法则,使用解析微分可以更高效。这种情况下,自己定义函数计算残差和雅可比矩阵更加合适。
同样以f(x)=10−x为例
class QuadraticCostFunction : public ceres::SizedCostFunction<1, 1> {
public:
virtual ~QuadraticCostFunction() {}
virtual bool Evaluate(double const* const* parameters,
double* residuals,
double** jacobians) const {
const double x = parameters[0][0];
residuals[0] = 10 - x;
// Compute the Jacobian if asked for.
if (jacobians != NULL && jacobians[0] != NULL) {
jacobians[0][0] = -1;
}
return true;
}
};
More About Derivatives
除了以上方法外,ceres solver还有其他函数,参考DynamicAutoDiffCostFunction
, CostFunctionToFunctor
, NumericDiffFunctor
和 ConditionedCostFunction
。