111 LevenbergMarquardtOptions<T, S> *options) {
114 auto start = std::chrono::steady_clock::now();
116 if (!options->validate()) {
117 if (options->verbose) {
118 std::cerr <<
"Levenberg-Marquardt options invalid" << std::endl;
123 T mu =
static_cast<T
>(options->initial_damping);
126 auto solver = options->solver;
127 auto streams = options->streams;
129 if (!graph->initialize_optimization(options->optimization_level)) {
133 if (!graph->build_structure()) {
137 solver->update_structure(graph, *streams);
139 graph->linearize(*streams);
142 solver->update_values(graph, *streams);
143 T chi2 = graph->chi2();
145 thrust::device_vector<T> delta_x(graph->get_hessian_dimension());
150 std::chrono::duration<double>(std::chrono::steady_clock::now() - start)
153 if (options->verbose) {
154 std::cout << std::setprecision(12) << std::setw(18) <<
"Iteration"
155 << std::setw(24) <<
"Initial Chi2" << std::setw(24)
156 <<
"Current Chi2" << std::setw(24) <<
"Lambda" << std::setw(24)
157 <<
"Time" << std::setw(24) <<
"Total Time" << std::endl;
159 <<
"---------------------------------------------------------------"
160 "---------------------------------------------------------------"
165 const auto num_iterations = options->iterations;
166 for (
size_t i = 0; i < num_iterations && run; i++) {
168 start = std::chrono::steady_clock::now();
170 solver->set_damping_factor(graph,
static_cast<T
>(mu), options->use_identity,
172 bool solve_ok = solver->solve(graph, delta_x.data().get(), *streams);
174 graph->backup_parameters();
175 graph->apply_update(delta_x.data().get(), *streams);
178 graph->compute_error();
179 T new_chi2 = graph->chi2();
182 new_chi2 = std::numeric_limits<T>::max();
185 T rho = compute_rho(graph, delta_x, chi2, new_chi2, mu, solve_ok);
187 if (solve_ok && std::isfinite(new_chi2) && rho > 0) {
189 double alpha = 1.0 - pow(2.0 * rho - 1.0, 3);
190 alpha = std::max(std::min(alpha, 2.0 / 3.0), 1.0 / 3.0);
191 mu *=
static_cast<T
>(alpha);
194 graph->linearize(*streams);
195 solver->update_values(graph, *streams);
199 graph->revert_parameters();
200 graph->compute_error();
212 double iteration_time =
213 std::chrono::duration<double>(std::chrono::steady_clock::now() - start)
215 time += iteration_time;
216 if (options->verbose) {
217 std::cout << std::setprecision(12) << std::setw(18) << i << std::setw(24)
218 << chi2 << std::setw(24) << new_chi2 << std::setw(24) << mu
219 << std::setw(24) << iteration_time << std::setw(24) << time
224 if (!std::isfinite(mu)) {
225 std::cout <<
"Damping factor is infinite, terminating optimization"
231 std::cout <<
"Rho is zero, terminating optimization" << std::endl;
235 if (options->stop_flag && *(options->stop_flag)) {
236 std::cout <<
"Stopping optimization due to stop flag" << std::endl;
257 LevenbergMarquardtOptions<T, S> *options) {
260 auto start = std::chrono::steady_clock::now();
262 if (!options->validate()) {
263 if (options->verbose) {
264 std::cerr <<
"Levenberg-Marquardt options invalid" << std::endl;
269 T mu =
static_cast<T
>(options->initial_damping);
273 auto solver = options->solver;
274 auto streams = options->streams;
276 if (!graph->initialize_optimization(options->optimization_level)) {
280 if (!graph->build_structure()) {
283 solver->update_structure(graph, *streams);
285 graph->linearize(*streams);
286 solver->update_values(graph, *streams);
287 T chi2 = graph->chi2();
289 thrust::device_vector<T> delta_x(graph->get_hessian_dimension());
294 std::chrono::duration<double>(std::chrono::steady_clock::now() - start)
297 if (options->verbose) {
298 std::cout << std::setprecision(12) << std::setw(18) <<
"Iteration"
299 << std::setw(24) <<
"Initial Chi2" << std::setw(24)
300 <<
"Current Chi2" << std::setw(24) <<
"Lambda" << std::setw(24)
301 <<
"Time" << std::setw(24) <<
"Total Time" << std::endl;
303 <<
"---------------------------------------------------------------"
304 "---------------------------------------------------------------"
309 const auto num_iterations = options->iterations;
310 for (
size_t i = 0; i < num_iterations && run; i++) {
312 start = std::chrono::steady_clock::now();
313 T initial_chi2 = chi2;
314 T end_chi2 = initial_chi2;
316 solver->set_damping_factor(graph,
static_cast<T
>(mu), options->use_identity,
319 bool solve_ok = solver->solve(graph, delta_x.data().get(), *streams);
321 graph->backup_parameters();
323 graph->apply_update(delta_x.data().get(), *streams);
326 graph->compute_error();
328 T new_chi2 = graph->chi2();
331 new_chi2 = std::numeric_limits<T>::max();
334 T rho = compute_rho(graph, delta_x, chi2, new_chi2, mu, solve_ok);
336 bool step_accepted =
false;
337 if (solve_ok && std::isfinite(new_chi2) && rho > 0) {
339 double alpha = 1.0 - pow(2.0 * rho - 1.0, 3);
340 alpha = std::max(std::min(alpha, 2.0 / 3.0), 1.0 / 3.0);
341 mu *=
static_cast<T
>(alpha);
344 graph->linearize(*streams);
346 solver->update_values(graph, *streams);
353 step_accepted =
true;
357 graph->revert_parameters();
366 graph->compute_error();
372 new_chi2 = initial_chi2;
375 double iteration_time =
376 std::chrono::duration<double>(std::chrono::steady_clock::now() - start)
378 time += iteration_time;
379 if (options->verbose) {
380 std::cout << std::setprecision(4) << std::setw(10) << i << std::setw(16)
381 << chi2 << std::setw(16) << new_chi2 << std::setw(16) << mu
382 << std::setw(16) << iteration_time << std::setw(16) << time
387 if (!std::isfinite(mu)) {
388 std::cout <<
"Damping factor is infinite, terminating optimization"
394 std::cout <<
"Rho is zero, terminating optimization" << std::endl;
398 if (options->stop_flag && *(options->stop_flag)) {
399 std::cout <<
"Stopping optimization due to stop flag" << std::endl;
404 if (((initial_chi2 - end_chi2) * 1.0e3) < initial_chi2) {
bool levenberg_marquardt(Graph< T, S > *graph, LevenbergMarquardtOptions< T, S > *options)
Levenberg-Marquardt optimization algorithm.
Definition levenberg_marquardt.hpp:110
bool levenberg_marquardt2(Graph< T, S > *graph, LevenbergMarquardtOptions< T, S > *options)
Levenberg-Marquardt with similar early termination stopping criteria to ORB-SLAM.
Definition levenberg_marquardt.hpp:256