CostFunction
对于目标函数中的每个项,都有一个CostFunction
负责计算残差向量和 Jacobian 矩阵。考虑其中一项残差 ,其取决于参数块 。给定参数 ,CostFunction
负责计算向量函数 和它对每个变量的 Jacobian 矩阵。
class CostFunction
Code Impl
class CostFunction {
public:
virtual bool Evaluate(double const* const* parameters,
double* residuals,
double** jacobians) const = 0;
const std::vector<int32>& parameter_block_sizes();
int num_residuals() const;
protected:
std::vector<int32>* mutable_parameter_block_sizes();
void set_num_residuals(int num_residuals);
};
CostFunction
输入参数块的数量和大小以及输出的数量分别存储在 CostFunction::parameter_block_sizes_
和 CostFunction::num_residuals_
中。从该类继承的用户代码应使用相应的函数方法设置这两个成员。当使用 Problem::AddResidualBlock()
添加时,Problem
将验证这些信息。
bool CostFunction::Evaluate(double const *const *parameters,
double *residuals,
double **jacobians) const
上述函数用于计算残差向量和 Jacobian 矩阵。该函数为纯虚函数,需要在子类进行重写,因为 Ceres 不知道你的残差是如何计算的。对其中的参数做出一些解释和强调。
parameters
是一个数组,其大小为CostFunction::parameter_block_sizes_.size()
。parameters[i]
也是一个数组,其大小为CostFunction::parameter_block_sizes_[i]
从上面了两条可以看出
parameters
其实是一个二维数组。parameters
永远不能为nullptr
。residuals
是一个数组,长度为num_residuals
。residuals
永远不能为nullptr
。jacobians
是一个数组,长度为CostFunction::parameter_block_sizes_.size()
。jacobians[i]
是一个 row-major 数组,长度为num_residuals x parameter_block_sizes_[i]
。如果
jacobians[i]
不为nullptr
的话,需要用户手动计算残差相对于parameters[i]
的 Jacobian 矩阵,并存储在数组中,例如jacobians[i][r * parameter_block_sizes_[i] + c]
= 。如果
jacobians[i]
为nullptr
,那么它的计算过程可以跳过,这种情况发生在当参数块被设定为常数的时候。返回值表示残差和 Jacobian 的计算是否成功。这可用于检查 jacobian 计算中是否有数值问题。
Last updated