101 LevenbergMarquardtOptions<T, S> *options) {
104 auto start = std::chrono::steady_clock::now();
106 if (!options->validate()) {
107 if (options->verbose) {
108 std::cerr <<
"Levenberg-Marquardt options invalid" << std::endl;
113 T mu =
static_cast<T
>(options->initial_damping);
116 auto solver = options->solver;
117 auto streams = options->streams;
119 if (!graph->initialize_optimization(options->optimization_level)) {
123 if (!graph->build_structure()) {
127 solver->update_structure(graph, *streams);
129 graph->linearize(*streams);
132 solver->update_values(graph, *streams);
133 T chi2 = graph->chi2();
135 thrust::device_vector<T> delta_x(graph->get_hessian_dimension());
140 std::chrono::duration<double>(std::chrono::steady_clock::now() - start)
143 if (options->verbose) {
144 std::cout << std::setprecision(12) << std::setw(18) <<
"Iteration"
145 << std::setw(24) <<
"Initial Chi2" << std::setw(24)
146 <<
"Current Chi2" << std::setw(24) <<
"Lambda" << std::setw(24)
147 <<
"Time" << std::setw(24) <<
"Total Time" << std::endl;
149 <<
"---------------------------------------------------------------"
150 "---------------------------------------------------------------"
155 const auto num_iterations = options->iterations;
156 for (
size_t i = 0; i < num_iterations && run; i++) {
158 start = std::chrono::steady_clock::now();
160 solver->set_damping_factor(graph,
static_cast<T
>(mu), *streams);
161 bool solve_ok = solver->solve(graph, delta_x.data().get(), *streams);
163 graph->backup_parameters();
164 graph->apply_update(delta_x.data().get(), *streams);
167 graph->compute_error();
168 T new_chi2 = graph->chi2();
171 new_chi2 = std::numeric_limits<T>::max();
174 T rho = compute_rho(graph, delta_x, chi2, new_chi2, mu, solve_ok);
176 if (solve_ok && std::isfinite(new_chi2) && rho > 0) {
178 double alpha = 1.0 - pow(2.0 * rho - 1.0, 3);
179 alpha = std::max(std::min(alpha, 2.0 / 3.0), 1.0 / 3.0);
180 mu *=
static_cast<T
>(alpha);
183 graph->linearize(*streams);
184 solver->update_values(graph, *streams);
188 graph->revert_parameters();
189 graph->compute_error();
201 double iteration_time =
202 std::chrono::duration<double>(std::chrono::steady_clock::now() - start)
204 time += iteration_time;
205 if (options->verbose) {
206 std::cout << std::setprecision(12) << std::setw(18) << i << std::setw(24)
207 << chi2 << std::setw(24) << new_chi2 << std::setw(24) << mu
208 << std::setw(24) << iteration_time << std::setw(24) << time
213 if (!std::isfinite(mu)) {
214 std::cout <<
"Damping factor is infinite, terminating optimization"
220 std::cout <<
"Rho is zero, terminating optimization" << std::endl;
224 if (options->stop_flag && *(options->stop_flag)) {
225 std::cout <<
"Stopping optimization due to stop flag" << std::endl;
246 LevenbergMarquardtOptions<T, S> *options) {
249 auto start = std::chrono::steady_clock::now();
251 if (!options->validate()) {
252 if (options->verbose) {
253 std::cerr <<
"Levenberg-Marquardt options invalid" << std::endl;
258 T mu =
static_cast<T
>(options->initial_damping);
262 auto solver = options->solver;
263 auto streams = options->streams;
265 if (!graph->initialize_optimization(options->optimization_level)) {
269 if (!graph->build_structure()) {
272 solver->update_structure(graph, *streams);
274 graph->linearize(*streams);
275 solver->update_values(graph, *streams);
276 T chi2 = graph->chi2();
278 thrust::device_vector<T> delta_x(graph->get_hessian_dimension());
283 std::chrono::duration<double>(std::chrono::steady_clock::now() - start)
286 if (options->verbose) {
287 std::cout << std::setprecision(12) << std::setw(18) <<
"Iteration"
288 << std::setw(24) <<
"Initial Chi2" << std::setw(24)
289 <<
"Current Chi2" << std::setw(24) <<
"Lambda" << std::setw(24)
290 <<
"Time" << std::setw(24) <<
"Total Time" << std::endl;
292 <<
"---------------------------------------------------------------"
293 "---------------------------------------------------------------"
298 const auto num_iterations = options->iterations;
299 for (
size_t i = 0; i < num_iterations && run; i++) {
301 start = std::chrono::steady_clock::now();
302 T initial_chi2 = chi2;
303 T end_chi2 = initial_chi2;
305 solver->set_damping_factor(graph,
static_cast<T
>(mu), *streams);
307 bool solve_ok = solver->solve(graph, delta_x.data().get(), *streams);
309 graph->backup_parameters();
311 graph->apply_update(delta_x.data().get(), *streams);
314 graph->compute_error();
316 T new_chi2 = graph->chi2();
319 new_chi2 = std::numeric_limits<T>::max();
322 T rho = compute_rho(graph, delta_x, chi2, new_chi2, mu, solve_ok);
324 bool step_accepted =
false;
325 if (solve_ok && std::isfinite(new_chi2) && rho > 0) {
327 double alpha = 1.0 - pow(2.0 * rho - 1.0, 3);
328 alpha = std::max(std::min(alpha, 2.0 / 3.0), 1.0 / 3.0);
329 mu *=
static_cast<T
>(alpha);
332 graph->linearize(*streams);
334 solver->update_values(graph, *streams);
341 step_accepted =
true;
345 graph->revert_parameters();
354 graph->compute_error();
360 new_chi2 = initial_chi2;
363 double iteration_time =
364 std::chrono::duration<double>(std::chrono::steady_clock::now() - start)
366 time += iteration_time;
367 if (options->verbose) {
368 std::cout << std::setprecision(4) << std::setw(10) << i << std::setw(16)
369 << chi2 << std::setw(16) << new_chi2 << std::setw(16) << mu
370 << std::setw(16) << iteration_time << std::setw(16) << time
375 if (!std::isfinite(mu)) {
376 std::cout <<
"Damping factor is infinite, terminating optimization"
382 std::cout <<
"Rho is zero, terminating optimization" << std::endl;
386 if (options->stop_flag && *(options->stop_flag)) {
387 std::cout <<
"Stopping optimization due to stop flag" << std::endl;
392 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 optimizer.hpp:100
bool levenberg_marquardt2(Graph< T, S > *graph, LevenbergMarquardtOptions< T, S > *options)
Levenberg-Marquardt with similar early termination stopping criteria to ORB-SLAM.
Definition optimizer.hpp:245