ceres 拾遗

Ceres的Options详解

https://blog.csdn.net/DumpDoctorWang/article/details/84890792?utm_medium=distribute.pc_relevant.none-task-blog-OPENSEARCH-1.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-OPENSEARCH-1.control

 

 

AutoDiffCostFunction  

http://www.ceres-solver.org/nnls_modeling.html?highlight=autodiffcostfunction#autodiffcostfunction

classAutoDiffCostFunction

Defining a CostFunction or a SizedCostFunction can be a tedious and error prone especially when computing derivatives. To this end Ceres provides automatic differentiation.

template <typename CostFunctor,
       int kNumResiduals,  // Number of residuals, or ceres::DYNAMIC.
       int... Ns>          // Size of each parameter block
class AutoDiffCostFunction : public
SizedCostFunction<kNumResiduals, Ns> {
 public:
  AutoDiffCostFunction(CostFunctor* functor, ownership = TAKE_OWNERSHIP);
  // Ignore the template parameter kNumResiduals and use
  // num_residuals instead.
  AutoDiffCostFunction(CostFunctor* functor,
                       int num_residuals,
                       ownership = TAKE_OWNERSHIP);
};

To get an auto differentiated cost function, you must define a class with a templated operator() (a functor) that computes the cost function in terms of the template parameter T. The autodiff framework substitutes appropriate Jet objects for T in order to compute the derivative when necessary, but this is hidden, and you should write the function as if T were a scalar type (e.g. a double-precision floating point number).

The function must write the computed value in the last argument (the only non-const one) and return true to indicate success.

For example, consider a scalar error e=k−x⊤ye=k−x⊤y, where both xx and yy are two-dimensional vector parameters and kk is a constant. The form of this error, which is the difference between a constant and an expression, is a common pattern in least squares problems. For example, the value x⊤yx⊤y might be the model expectation for a series of measurements, where there is an instance of the cost function for each measurement kk.

The actual cost added to the total problem is e2e2, or (k−x⊤y)2(k−x⊤y)2; however, the squaring is implicitly done by the optimization framework.

To write an auto-differentiable cost function for the above model, first define the object

class MyScalarCostFunctor {
  MyScalarCostFunctor(double k): k_(k) {}

  template <typename T>
  bool operator()(const T* const x , const T* const y, T* e) const {
    e[0] = k_ - x[0] * y[0] - x[1] * y[1];
    return true;
  }

 private:
  double k_;
};

Note that in the declaration of operator() the input parameters x and y come first, and are passed as const pointers to arrays of T. If there were three input parameters, then the third input parameter would come after y. The output is always the last parameter, and is also a pointer to an array. In the example above, e is a scalar, so only e[0] is set.

Then given this class definition, the auto differentiated cost function for it can be constructed as follows.

CostFunction* cost_function
    = new AutoDiffCostFunction<MyScalarCostFunctor, 1, 2, 2>(
        new MyScalarCostFunctor(1.0));              ^  ^  ^
                                                    |  |  |
                        Dimension of residual ------+  |  |
                        Dimension of x ----------------+  |
                        Dimension of y -------------------+

In this example, there is usually an instance for each measurement of k.

In the instantiation above, the template parameters following MyScalarCostFunction<1, 2, 2> describe the functor as computing a 1-dimensional output from two arguments, both 2-dimensional.

By default AutoDiffCostFunction will take ownership of the cost functor pointer passed to it, ie. will call delete on the cost functor when the AutoDiffCostFunction itself is deleted. However, this may be undesirable in certain cases, therefore it is also possible to specify DO_NOT_TAKE_OWNERSHIP as a second argument in the constructor, while passing a pointer to a cost functor which does not need to be deleted by the AutoDiffCostFunction. For example:

MyScalarCostFunctor functor(1.0)
CostFunction* cost_function
    = new AutoDiffCostFunction<MyScalarCostFunctor, 1, 2, 2>(
        &functor, DO_NOT_TAKE_OWNERSHIP);

AutoDiffCostFunction also supports cost functions with a runtime-determined number of residuals. For example:

CostFunction* cost_function
    = new AutoDiffCostFunction<MyScalarCostFunctor, DYNAMIC, 2, 2>(
        new CostFunctorWithDynamicNumResiduals(1.0),   ^     ^  ^
        runtime_number_of_residuals); <----+           |     |  |
                                           |           |     |  |
                                           |           |     |  |
          Actual number of residuals ------+           |     |  |
          Indicate dynamic number of residuals --------+     |  |
          Dimension of x ------------------------------------+  |
          Dimension of y ---------------------------------------+

WARNING 1 A common beginner’s error when first using AutoDiffCostFunction is to get the sizing wrong. In particular, there is a tendency to set the template parameters to (dimension of residual, number of parameters) instead of passing a dimension parameter for every parameter block. In the example above, that would be <MyScalarCostFunction, 1, 2>, which is missing the 2 as the last template argument.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值