Ceres(3)---Interfacing with Automatic Differentiation
来源:互联网 发布:网络推广平均工资 编辑:程序博客网 时间:2024/06/05 00:21
转载地址:
http://ceres-solver.org/interfacing_with_autodiff.html
本篇主要介绍在一些情况下,不能直接使用 Automatic Differentiation
We begin by considering the case, where we have a templated function TemplatedComputeDistortion
that can compute the function
template <typename T> TemplatedComputeDistortion(const T r2) { const double k1 = 0.0082; const double k2 = 0.000023; return 1.0 + k1 * r2 + k2 * r2 * r2;}struct Affine2DWithDistortion { Affine2DWithDistortion(const double x_in[2], const double y_in[2]) { x[0] = x_in[0]; x[1] = x_in[1]; y[0] = y_in[0]; y[1] = y_in[1]; } template <typename T> //模板类型 bool operator()(const T* theta, const T* t, T* residuals) const { const T q_0 = cos(theta[0]) * x[0] - sin(theta[0]) * x[1] + t[0]; const T q_1 = sin(theta[0]) * x[0] + cos(theta[0]) * x[1] + t[1]; const T f = TemplatedComputeDistortion(q_0 * q_0 + q_1 * q_1); //模板类型 residuals[0] = y[0] - f * q_0; residuals[1] = y[1] - f * q_1; return true; } double x[2]; double y[2];};Automatic Differentiation 的函数对象是模板形式的
So far so good, but let us now consider three ways of defining
- A non-templated function that evaluates its value. (仿函数中要使用非模板的函数)
- A function that evaluates its value and derivative.
- A function that is defined as a table of values to be interpolated.
We will consider them in turn below.
A function that returns its value
Suppose we were given a function ComputeDistortionValue
with the following signature
double ComputeDistortionValue(double r2); //非模板类型函数
that computes the value of Affine2DWithDistortion
is a three step process:
- Wrap
ComputeDistortionValue
into a functorComputeDistortionValueFunctor
. - Numerically differentiate
ComputeDistortionValueFunctor
usingNumericDiffCostFunction
to create aCostFunction
. - Wrap the resulting
CostFunction
object usingCostFunctionToFunctor
.The resulting object is a functor with a templatedoperator()
method, which pipes the Jacobian computed byNumericDiffCostFunction
into the approproateJet
objects.
An implementation of the above three steps looks as follows:
struct ComputeDistortionValueFunctor { bool operator()(const double* r2, double* value) const { //非模板仿函数,供NumericDiffCostFunction使用 *value = ComputeDistortionValue(r2[0]); //要使用的非模板函数 return true; }};struct Affine2DWithDistortion { Affine2DWithDistortion(const double x_in[2], const double y_in[2]) { x[0] = x_in[0]; x[1] = x_in[1]; y[0] = y_in[0]; y[1] = y_in[1]; compute_distortion.reset(new ceres::CostFunctionToFunctor<1, 1>( // compute_distortion赋值 new ceres::NumericDiffCostFunction<ComputeDistortionValueFunctor, ceres::CENTRAL, 1, 1>( new ComputeDistortionValueFunctor))); } template <typename T> bool operator()(const T* theta, const T* t, T* residuals) const { const T q_0 = cos(theta[0]) * x[0] - sin(theta[0]) * x[1] + t[0]; const T q_1 = sin(theta[0]) * x[0] + cos(theta[0]) * x[1] + t[1]; const T r2 = q_0 * q_0 + q_1 * q_1; T f; (*compute_distortion)(&r2, &f); //调用指向的模板仿函数 residuals[0] = y[0] - f * q_0; residuals[1] = y[1] - f * q_1; return true; } double x[2]; double y[2]; std::unique_ptr<ceres::CostFunctionToFunctor<1, 1> > compute_distortion; //指向仿函数的指针};
猜测:这样做以后, Affine2DWithDistortion就是一个模板仿函数,这样就可以像之前使用 Automatic Derivatives 一样使用。
A function that returns its value and derivative
Now suppose we are given a function ComputeDistortionValue
that is able to compute its value and optionally its Jacobian on demand and has the following signature:
void ComputeDistortionValueAndJacobian(double r2, double* value, double* jacobian);
Again, the actual implementation of the function does not matter. Interfacing this function with Affine2DWithDistortion
is a two step process:
- Wrap
ComputeDistortionValueAndJacobian
into aCostFunction
object which we callComputeDistortionFunction
. - Wrap the resulting
ComputeDistortionFunction
object usingCostFunctionToFunctor
. The resulting object is a functor with a templatedoperator()
method, which pipes the Jacobian computed byNumericDiffCostFunction
into the approproateJet
objects.
通过下面的例子可以看出:
第一种是将 要用的函数包装在 NumericDiffCostFunction 要用的仿函数中,再用 NumericDiffCostFunction new 一个 CostFunction,供CostFunctionToFunctor使用;
第二种是通过将要用的函数包装在CostFunction中,然后供CostFunctionToFunctor使用;
class ComputeDistortionFunction : public ceres::SizedCostFunction<1, 1> { public: virtual bool Evaluate(double const* const* parameters, double* residuals, double** jacobians) const { if (!jacobians) { ComputeDistortionValueAndJacobian(parameters[0][0], residuals, NULL); } else { ComputeDistortionValueAndJacobian(parameters[0][0], residuals, jacobians[0]); } return true; }};struct Affine2DWithDistortion { Affine2DWithDistortion(const double x_in[2], const double y_in[2]) { x[0] = x_in[0]; x[1] = x_in[1]; y[0] = y_in[0]; y[1] = y_in[1]; compute_distortion.reset( new ceres::CostFunctionToFunctor<1, 1>(new ComputeDistortionFunction)); //这的<1,1>是和上面定义ComputeDistortionFunction时指定的<1,1>是一致的 } template <typename T> bool operator()(const T* theta, const T* t, T* residuals) const { const T q_0 = cos(theta[0]) * x[0] - sin(theta[0]) * x[1] + t[0]; const T q_1 = sin(theta[0]) * x[0] + cos(theta[0]) * x[1] + t[1]; const T r2 = q_0 * q_0 + q_1 * q_1; T f; (*compute_distortion)(&r2, &f); residuals[0] = y[0] - f * q_0; residuals[1] = y[1] - f * q_1; return true; } double x[2]; double y[2]; std::unique_ptr<ceres::CostFunctionToFunctor<1, 1> > compute_distortion;};
- Ceres(3)---Interfacing with Automatic Differentiation
- Interfacing with Automatic Differentiation
- Automatic differentiation
- 自动微分(Automatic Differentiation)简介
- 自动微分(Automatic Differentiation)简介
- Interfacing with I2C Devices
- Ceres(2)---Analytic,Numeric, Automatic derivatives
- C++自动微分(Automatic differentiation)原理1
- The differentiation program with abstract data
- Interfacing DJGPP with Assembly-Language Procedures
- Interfacing DJGPP with Assembly-Language Procedures
- Interfacing with Pixhawk using the NSH
- Ceres
- Ceres
- A brief introduction to C++ and Interfacing with Excel
- Lesson17 Interfacing with raw buffers: the Map class
- Ceres-Solver学习笔记(3)
- Automatic Android* Testing with UiAutomator
- B
- 【CodeForces617E】XOR and Favorite Number
- MySQL基础
- 自我实现itoa(整形转字符串)
- Linux学习之基础篇_2017.8.4
- Ceres(3)---Interfacing with Automatic Differentiation
- 数据结构顺序栈
- JavaScript--引用数据类型--objiect
- 从一个字符数组中读出相应的整数、实数
- Protobuf数据格式解析
- 2017 Multi-University Training Contest
- 手写高并发网络请求框架
- /usr/bin/ld: cannot find -lcblas
- 将字符串首字母大写