Я прохожу учебник по Ceres Solver .
Функция Пауэлла
Карты функций Пауэлла из R^4 -> R^4
, поэтому определение кажется интуитивно понятнымодин остаточный блок, который принимает массив из 4 элементов x
и заполняет массив из 4 элементов residual
.
Вместо этого, пример в руководстве определяет 4 различных остаточных блока, которые отображаются R^2 -> R^1
.
Конечно, если мы пытаемся минимизировать 1/2 || F(x) ||^2
, то минимизация каждого элемента F
неявно приведет к тому же решению, что и минимизация 1/2 || F(x) ||^2
напрямую (т.е. я предлагаю вернутьодиночный остаточный вектор F
вместо F1
... F4
отдельно). (Я проверил это с помощью приведенного ниже функтора стоимости).
struct F {
template<typename T>
bool operator() (const T* const x, T* residual) const {
residual[0] = x[0] + 10.0 * x[1];
residual[1] = sqrt(5.0) * (x[2] - x[3]);
residual[2] = (x[1] - 2.0*x[2]) * (x[1] - 2.0*x[2]);
residual[3] = T(sqrt(10.0)) * (x[0] - x[3]) * (x[0] - x[3]);
return true;
}
};
В чем преимущество определения отдельных остаточных блоков (и неявно блоков параметров) для каждого элемента остаточного вектора F
?
Если остаток F1
зависит от параметров x1
и x2
, а остаток F2
зависит от x3
и x4
, будет ли стоимость F
относительно x1
влияет на значение x3
?
Кривая Фиттинг
Другой пример пытается найти параметры m
и c
длякривая y=e^(mx + c)
.
Определяет некоторую ExponentialResidual
, которая просто выводит T(y_) - exp(m[0] * T(x_) + c[0])
, где (x_, y_)
- точка данных.
Затем они добавляют один остаточный блок длякаждое наблюдение
double m = 0.0;
double c = 0.0;
Problem problem;
for (int i = 0; i < kNumObservations; ++i) {
CostFunction* cost_function =
new AutoDiffCostFunction<ExponentialResidual, 1, 1, 1>(
new ExponentialResidual(data[2 * i], data[2 * i + 1]));
problem.AddResidualBlock(cost_function, NULL, &m, &c);
}
- Хотя мне было лень воспроизводить этот пример сам, я подозреваю, что это также может быть достигнуто только с одним остаточным блоком, который отображает
R^2 -> R^1
, где 1DОстаток - это просто сумма всех T(y_) - exp(m[0] * T(x_) + c[0])
для всех (x_, y_)
? Было ли необходимо определять остаточный блок для каждого наблюдения?
Спасибо за чтение этого длинного поста!