Ceres学习笔记1——helloworld.cc

1.残差块构造的问题

1.使用模板定义的()运算符,可以让Ceres使用自动求导,这里的关键是使用模板。其次这种函数应该是有专门的名字叫做函数对象,也就是tutorial中的functor。对于函数对象返回bool值的又称为谓词,所以这里可能是函数对象或者谓词的使用吗?具体需要好好学学这方面
2.下面的定义可以看出,由于要优化的变量是x,但是这里却把x定义成了最严格的const类型,为什么?
3.

struct CostFunctor {
  template <typename T>
  // 这里是一个函数对象,返回值为bool的特殊函数对象称为谓词
  bool operator()(const T* const x, T* residual) const {
    residual[0] = 10.0 - x[0];
    return true;
  }
};

2.数值求导和自动求导

当残差的定义无法使用模板的时候,比如残差的计算使用到了库函数,此时只能使用数值求导。
数值求导对象的定义相对自动求导,只是多了一个指定数值求导方式的变量,如下所示。

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

一般来说,我们推荐自动微分而不是数字微分。使用 C++ 模板使自动微分高效,而数值微分代价高昂,容易出现数值错误,并导致收敛速度较慢。

3.解析导数

也就是自己推导雅克比,然后提供给ceres使用。

// A CostFunction implementing analytically derivatives for the
// function f(x) = 10 - x.
class QuadraticCostFunction  // 二次的代价函数
    : public SizedCostFunction<1 /* number of residuals */,
                               1 /* size of first parameter */> {
 public:
  virtual ~QuadraticCostFunction() {}

  // parameters是二维的:x是n维向量,有m个数据点,所以最后是mxn,二维
  // residuals是一维的:对于每个数据点x都有一个残差,m个数据点,所以是mx1,一维
  // 雅克比是二维的:对于每个残差,他的梯度都是nx1的向量。对于m个残差,所以总的J是mxn维的
  virtual bool Evaluate(double const* const* parameters,
                        double* residuals,
                        double** jacobians) const {
    double x = parameters[0][0];

    // f(x) = 10 - x.
    residuals[0] = 10 - x;

    // f'(x) = -1. Since there's only 1 parameter and that parameter
    // has 1 dimension, there is only 1 element to fill in the
    // jacobians.
    //
    // Since the Evaluate function can be called with the jacobians
    // pointer equal to NULL, the Evaluate function must check to see
    // if jacobians need to be computed.
    //
    // For this simple problem it is overkill to check if jacobians[0]
    // is NULL, but in general when writing more complex
    // CostFunctions, it is possible that Ceres may only demand the
    // derivatives w.r.t. a subset of the parameter blocks.
    if (jacobians != NULL && jacobians[0] != NULL) {
      jacobians[0][0] = -1;
    }

    return true;
  }
};
上一篇:RK WITH_DEXPREOPT 预编译


下一篇:codeforces 753-div3 D(现在只会做水题了呜呜呜)