修改平方和[ceres solver]

modify the squared sum [ceres-solver]

本文关键字:ceres solver 修改      更新时间:2023-10-16

我正在尝试修改ceres的默认行为,即将残差的平方和计算为成本函数。我希望它只计算一个和(残差已经以只能为正的方式计算)

根据文档,我应该使用ConditionedCostFunction

这就是我所做的:我定义了取1个残差和1个参数的调节器

struct Conditioners : ceres::CostFunction
{
public:
    Conditioners()
    {
        set_num_residuals(1);
        mutable_parameter_block_sizes()->push_back(1);
    }
    ~Conditioners()
    {}
    template<typename T>
    T operator() (T x)
    {
        return T(x * x);
    }
    bool Evaluate(double const* const* parameters, double* residuals, double** jacobians) const
    {
        return true;
    }
};

我把调理剂放在矢量里

std::vector<ceres::CostFunction*> conditioners;
for(int i = 0; i < 1; i++)
    conditioners.push_back(new Conditioners());
ceres::ConditionedCostFunction* ccf =
              new ceres::ConditionedCostFunction(cost_function, conditioners, ceres::TAKE_OWNERSHIP);
problem.AddResidualBlock(ccf, NULL, &x);

它编译一切。但这并不能解决问题。它甚至还没有启动。上面写着:

Ceres Solver Report: Iterations: 0, Initial cost: 4.512500e+01, Final cost: 4.512500e+01, Termination: CONVERGENCE
x : 0.5 -> 0.5

而不是:

iter      cost      cost_change  |gradient|   |step|    tr_ratio  tr_radius  ls_iter  iter_time  total_time
   0  4.512500e+01    0.00e+00    9.50e+00   0.00e+00   0.00e+00  1.00e+04       0    2.99e-04    1.04e-03
   1  4.511598e-07    4.51e+01    9.50e-04   9.50e+00   1.00e+00  3.00e+04       1    3.84e-04    9.72e-03
   2  5.012552e-16    4.51e-07    3.17e-08   9.50e-04   1.00e+00  9.00e+04       1    2.98e-05    9.92e-03
Ceres Solver Report: Iterations: 2, Initial cost: 4.512500e+01, Final cost: 5.012552e-16, Termination: CONVERGENCE
x : 0.5 -> 10

(如果你想自己尝试,这个例子会修改hellowword的例子)你知道哪里出了问题吗??(ceres报告没有更具体)

我找到了解决方案,它是:

struct Conditioners : ceres::CostFunction
{
public:
Conditioners()
{
    set_num_residuals(1);
    mutable_parameter_block_sizes()->push_back(1);
}
~Conditioners()
{}
template<typename T>
T operator() (T x)
{
    return T(x * x);
}
bool Evaluate(double const* const* parameters, double* residuals, double** jacobians) const
{
    residuals[0] = parameters[0][0] * parameters[0][0]
    if (jacobians)
         jacobians[0][0] = 2.0 * parameters[0][0]
    return true;
}
};

我的错误是认为我只需要重新实现()运算符,ceres就会自动找到jacobian。事实并非如此。