изменить сумму в квадрате [ceres-solver]

Я пытаюсь изменить стандартное поведение 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

(если вы хотите попробовать сами, этот пример изменяет пример helloword)
Есть ли у вас указания на то, что пошло не так? (отчет Ceres не был более конкретным)

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
{
residuals[0] = parameters[0][0] * parameters[0][0]

if (jacobians)
jacobians[0][0] = 2.0 * parameters[0][0]

return true;
}
};

Моя ошибка состояла в том, что я подумал, что мне нужно было только реализовать оператор (), и это автоматически обнаружит якобиана. Это не.

2

Другие решения