@@ -258,14 +258,22 @@ typename DoglegOptimizerImpl::IterationResult DoglegOptimizerImpl::Iterate(
258258 * trust region is not correlated between algorithm iterations.
259259 */
260260struct GTSAM_EXPORT DoglegLineSearchImpl {
261+ struct Params {
262+ double minDelta; // /< Minimum allowed small delta
263+ double maxDelta; // /< Maximum allowed delta
264+ double stepSize; // /< Increase of trust region for outward steps
265+ double sufficientDecreaseCoeff; // /< Coefficient for suff. decrease check
266+ bool verbose; // /< Whether to print debug information
267+ };
268+
261269 /* *
262270 * Compute the update point for one iteration of the Dogleg Line Search
263- * algorithm, starting with a trust region of |N| * min_delta the algorithm
264- * searches trust regions from |N| * min_delta to max_delta where |N| is the
271+ * algorithm, starting with a trust region of |N| * minDelta the algorithm
272+ * searches trust regions from |N| * minDelta to maxDelta where |N| is the
265273 * number of variables in the system. The algorithm returns the search point
266274 * with minimum cost that meets the Wolfe Conditions. Evaluation points for
267275 * the line search are computed according to a geometric series step_{k+1} =
268- * step_size * step_k.
276+ * stepSize * step_k.
269277 *
270278 *
271279 * @tparam M The type of the Bayes' net or tree, currently
@@ -274,12 +282,7 @@ struct GTSAM_EXPORT DoglegLineSearchImpl {
274282 * @tparam F For normal usage this will be NonlinearFactorGraph<VALUES>.
275283 * @tparam VALUES The Values or TupleValues to pass to F::error() to evaluate
276284 * the error function.
277- * @param min_delta The minimum trust region size (scaled by size of system)
278- * @param max_delta The maximum trust region size (scaled by size of system)
279- * @param step_size The multiplicative factor for the geometric series that
280- * defines the evaluation points for the line search
281- * @param sufficient_decrease_coeff The coefficient for sufficient decrease to
282- * ensure that the linesearch meets the Wolfe conditions
285+ * @param params The parameters for dogleg line search
283286 * @param Rd The Bayes' net or tree as described above.
284287 * @param f The original nonlinear factor graph with which to evaluate the
285288 * accuracy of \f$ M(\delta x) \f$ to adjust \f$ \delta \f$.
@@ -289,83 +292,81 @@ struct GTSAM_EXPORT DoglegLineSearchImpl {
289292 * update \c dx_d, and the resulting nonlinear error \c f_error.
290293 */
291294 template <class M , class F , class VALUES >
292- static DoglegOptimizerImpl::IterationResult Iterate (
293- const double min_delta, const double max_delta, const double step_size ,
294- const double sufficient_decrease_coeff, const VectorValues& dx_u ,
295- const VectorValues& dx_n, const M& Rd, const F& f, const VALUES& x0 ,
296- const bool verbose = false );
295+ static DoglegOptimizerImpl::IterationResult Iterate (const Params& params,
296+ const VectorValues& dx_u ,
297+ const VectorValues& dx_n ,
298+ const M& Rd, const F& f,
299+ const VALUES& x0 );
297300};
298301
299302/* ************************************************************************* */
300303template <class M , class F , class VALUES >
301304typename DoglegOptimizerImpl::IterationResult DoglegLineSearchImpl::Iterate (
302- const double min_delta, const double max_delta, const double step_size,
303- const double sufficient_decrease_coeff, const VectorValues& dx_u,
304- const VectorValues& dx_n, const M& Rd, const F& f, const VALUES& x0,
305- const bool verbose) {
306- if (verbose)
307- std::cout << " DoglegLineSearch | minDelta: " << min_delta
308- << " maxDelta: " << max_delta << " stepSize: " << step_size
309- << std::endl;
310- const double F_init_error = f.error (x0);
311- const double gn_step = dx_n.norm ();
312- const size_t num_vars = dx_n.size ();
313-
314- double max_step, step;
305+ const Params& params, const VectorValues& dx_u, const VectorValues& dx_n,
306+ const M& Rd, const F& f, const VALUES& x0) {
307+ if (params.verbose )
308+ std::cout << " DoglegLineSearch | minDelta: " << params.minDelta
309+ << " maxDelta: " << params.maxDelta
310+ << " stepSize: " << params.stepSize << std::endl;
311+ const double fInitError = f.error (x0);
312+ const double gnStep = dx_n.norm ();
313+ const size_t numVars = dx_n.size ();
314+
315+ double maxStep, step;
315316 // / The search bounds are scaled by the number of variables in the system
316- max_step = std::min (max_delta * num_vars, gn_step );
317- step = std::min (min_delta * num_vars, gn_step );
318- step = std::min (step, max_step ); // Edge case min_step > max_step
317+ maxStep = std::min (params. maxDelta * numVars, gnStep );
318+ step = std::min (params. minDelta * numVars, gnStep );
319+ step = std::min (step, maxStep ); // Edge case min_step > maxStep
319320
320- if (verbose)
321- std::cout << " Search Region: [ " << step << " -> " << max_step << " ]"
321+ if (params. verbose )
322+ std::cout << " Search Region: [ " << step << " -> " << maxStep << " ]"
322323 << std::endl;
323324
324325 DoglegOptimizerImpl::IterationResult result;
325326 result.dx_d =
326- DoglegOptimizerImpl::ComputeDoglegPoint (step, dx_u, dx_n, verbose);
327+ DoglegOptimizerImpl::ComputeDoglegPoint (step, dx_u, dx_n, params. verbose );
327328 result.f_error = f.error (x0.retract (result.dx_d ));
328329 result.delta = step;
329- if (verbose)
330+ if (params. verbose )
330331 std::cout << " Initial Step Error: " << result.f_error << std::endl;
331332
332333 // Validate Step size will terminate search
333- if (step < 1e-12 || step_size < 1.0 )
334+ if (step < 1e-12 || params. stepSize < 1.0 )
334335 throw std::runtime_error (
335336 " Invalid DoglegLineSearch configuration. Would cause infinite search." );
336337
337338 // Search Increase delta
338339 double eps = std::numeric_limits<double >::epsilon ();
339- while (step < max_step - eps) {
340+ while (step < maxStep - eps) {
340341 // Compute the trust region for the evaluation point according to the
341342 // Geometric Series
342- step = std::min (max_step , step * step_size );
343+ step = std::min (maxStep , step * params. stepSize );
343344
344345 // Compute the Evaluation Point and evaluate the error
345- VectorValues dx_d =
346- DoglegOptimizerImpl::ComputeDoglegPoint ( step, dx_u, dx_n, verbose);
346+ VectorValues dx_d = DoglegOptimizerImpl::ComputeDoglegPoint (
347+ step, dx_u, dx_n, params. verbose );
347348 VALUES x_d (x0.retract (dx_d));
348- double new_F_error = f.error (x_d);
349+ double fNewError = f.error (x_d);
349350
350- if (verbose)
351- std::cout << " Step: " << step << " | Error: " << new_F_error << std::endl;
351+ if (params. verbose )
352+ std::cout << " Step: " << step << " | Error: " << fNewError << std::endl;
352353
353354 // Check step acceptance conditions
354- bool update_decreased_error = new_F_error < result.f_error ;
355- bool update_has_sufficient_decrease =
356- new_F_error < (F_init_error - sufficient_decrease_coeff * step);
355+ bool updateDecreasedError = fNewError < result.f_error ;
356+ bool updateHasSufficientDecrease =
357+ fNewError < (fInitError - params. sufficientDecreaseCoeff * step);
357358
358- if (verbose)
359- std::cout << " Decrease Error: " << update_decreased_error
360- << " | Suff. Dec.: " << update_has_sufficient_decrease
359+ if (params. verbose )
360+ std::cout << " Decrease Error: " << updateDecreasedError
361+ << " | Suff. Dec.: " << updateHasSufficientDecrease
361362 << std::endl;
362363
363- if (update_decreased_error && update_has_sufficient_decrease ) {
364- result.f_error = new_F_error ;
364+ if (updateDecreasedError && updateHasSufficientDecrease ) {
365+ result.f_error = fNewError ;
365366 result.dx_d = dx_d;
366367 result.delta = step;
367368
368- if (verbose) std::cout << " Step Accepted" << std::endl;
369+ if (params. verbose ) std::cout << " Step Accepted" << std::endl;
369370 }
370371 }
371372
0 commit comments