DoglegOptimizerImpl.h
Go to the documentation of this file.
1 /* ----------------------------------------------------------------------------
2 
3  * GTSAM Copyright 2010, Georgia Tech Research Corporation,
4  * Atlanta, Georgia 30332-0415
5  * All Rights Reserved
6  * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
7 
8  * See LICENSE for the license information
9 
10  * -------------------------------------------------------------------------- */
11 
17 #pragma once
18 
19 #include <iomanip>
20 #include <cassert>
21 
24 
25 namespace gtsam {
26 
33 struct GTSAM_EXPORT DoglegOptimizerImpl {
34 
35  struct GTSAM_EXPORT IterationResult {
36  double delta;
38  double f_error;
39  };
40 
57  ONE_STEP_PER_ITERATION
58  };
59 
95  template<class M, class F, class VALUES>
96  static IterationResult Iterate(
97  double delta, TrustRegionAdaptationMode mode, const VectorValues& dx_u, const VectorValues& dx_n,
98  const M& Rd, const F& f, const VALUES& x0, const double f_error, const bool verbose=false);
99 
122  static VectorValues ComputeDoglegPoint(double delta, const VectorValues& dx_u, const VectorValues& dx_n, const bool verbose=false);
123 
133  static VectorValues ComputeBlend(double delta, const VectorValues& x_u, const VectorValues& x_n, const bool verbose=false);
134 };
135 
136 
137 /* ************************************************************************* */
138 template<class M, class F, class VALUES>
140  double delta, TrustRegionAdaptationMode mode, const VectorValues& dx_u, const VectorValues& dx_n,
141  const M& Rd, const F& f, const VALUES& x0, const double f_error, const bool verbose)
142 {
143  gttic(M_error);
144  const double M_error = Rd.error(VectorValues::Zero(dx_u));
145  gttoc(M_error);
146 
147  // Result to return
149 
150  bool stay = true;
151  enum { NONE, INCREASED_DELTA, DECREASED_DELTA } lastAction = NONE; // Used to prevent alternating between increasing and decreasing in one iteration
152  while(stay) {
153  gttic(Dog_leg_point);
154  // Compute dog leg point
155  result.dx_d = ComputeDoglegPoint(delta, dx_u, dx_n, verbose);
156  gttoc(Dog_leg_point);
157 
158  if(verbose) std::cout << "delta = " << delta << ", dx_d_norm = " << result.dx_d.norm() << std::endl;
159 
160  gttic(retract);
161  // Compute expmapped solution
162  const VALUES x_d(x0.retract(result.dx_d));
163  gttoc(retract);
164 
165  gttic(decrease_in_f);
166  // Compute decrease in f
167  result.f_error = f.error(x_d);
168  gttoc(decrease_in_f);
169 
170  gttic(new_M_error);
171  // Compute decrease in M
172  const double new_M_error = Rd.error(result.dx_d);
173  gttoc(new_M_error);
174 
175  if(verbose) std::cout << std::setprecision(15) << "f error: " << f_error << " -> " << result.f_error << std::endl;
176  if(verbose) std::cout << std::setprecision(15) << "M error: " << M_error << " -> " << new_M_error << std::endl;
177 
178  gttic(adjust_delta);
179  // Compute gain ratio. Here we take advantage of the invariant that the
180  // Bayes' net error at zero is equal to the nonlinear error
181  const double rho = std::abs(f_error - result.f_error) < 1e-15 || std::abs(M_error - new_M_error) < 1e-15 ?
182  0.5 :
183  (f_error - result.f_error) / (M_error - new_M_error);
184 
185  if(verbose) std::cout << std::setprecision(15) << "rho = " << rho << std::endl;
186 
187  if(rho >= 0.75) {
188  // M agrees very well with f, so try to increase lambda
189  const double dx_d_norm = result.dx_d.norm();
190  const double newDelta = std::max(delta, 3.0 * dx_d_norm); // Compute new delta
191 
193  stay = false; // If not searching, just return with the new delta
194  else if(mode == SEARCH_EACH_ITERATION) {
195  if(std::abs(newDelta - delta) < 1e-15 || lastAction == DECREASED_DELTA)
196  stay = false; // Searching, but Newton's solution is within trust region so keep the same trust region
197  else {
198  stay = true; // Searching and increased delta, so try again to increase delta
199  lastAction = INCREASED_DELTA;
200  }
201  } else {
202  assert(false); }
203 
204  delta = newDelta; // Update delta from new delta
205 
206  } else if(0.75 > rho && rho >= 0.25) {
207  // M agrees so-so with f, keep the same delta
208  stay = false;
209 
210  } else if(0.25 > rho && rho >= 0.0) {
211  // M does not agree well with f, decrease delta until it does
212  double newDelta;
213  bool hitMinimumDelta;
214  if(delta > 1e-5) {
215  newDelta = 0.5 * delta;
216  hitMinimumDelta = false;
217  } else {
218  newDelta = delta;
219  hitMinimumDelta = true;
220  }
221  if(mode == ONE_STEP_PER_ITERATION || /* mode == SEARCH_EACH_ITERATION && */ lastAction == INCREASED_DELTA || hitMinimumDelta)
222  stay = false; // If not searching, just return with the new smaller delta
224  stay = true;
225  lastAction = DECREASED_DELTA;
226  } else {
227  assert(false); }
228 
229  delta = newDelta; // Update delta from new delta
230 
231  } else {
232  // f actually increased, so keep decreasing delta until f does not decrease.
233  // NOTE: NaN and Inf solutions also will fall into this case, so that we
234  // decrease delta if the solution becomes undetermined.
235  assert(0.0 > rho);
236  if(delta > 1e-5) {
237  delta *= 0.5;
238  stay = true;
239  lastAction = DECREASED_DELTA;
240  } else {
241  if(verbose) std::cout << "Warning: Dog leg stopping because cannot decrease error with minimum delta" << std::endl;
242  result.dx_d.setZero(); // Set delta to zero - don't allow error to increase
243  result.f_error = f_error;
244  stay = false;
245  }
246  }
247  gttoc(adjust_delta);
248  }
249 
250  // dx_d and f_error have already been filled in during the loop
251  result.delta = delta;
252  return result;
253 }
254 
255 }
gttoc
#define gttoc(label)
Definition: timing.h:296
e
Array< double, 1, 3 > e(1./3., 0.5, 2.)
gtsam::DoglegOptimizerImpl::Iterate
static IterationResult Iterate(double delta, TrustRegionAdaptationMode mode, const VectorValues &dx_u, const VectorValues &dx_n, const M &Rd, const F &f, const VALUES &x0, const double f_error, const bool verbose=false)
Definition: DoglegOptimizerImpl.h:139
gtsam::DoglegOptimizerImpl::ONE_STEP_PER_ITERATION
@ ONE_STEP_PER_ITERATION
Definition: DoglegOptimizerImpl.h:57
gtsam::DoglegOptimizerImpl
Definition: DoglegOptimizerImpl.h:33
gtsam::utils.numerical_derivative.retract
def retract(a, np.ndarray xi)
Definition: numerical_derivative.py:44
Ordering.h
Variable ordering for the elimination algorithm.
result
Values result
Definition: OdometryOptimize.cpp:8
gtsam::DoglegOptimizerImpl::IterationResult::delta
double delta
Definition: DoglegOptimizerImpl.h:36
gtsam::DoglegOptimizerImpl::IterationResult::dx_d
VectorValues dx_d
Definition: DoglegOptimizerImpl.h:37
gtsam::DoglegOptimizerImpl::ComputeDoglegPoint
static VectorValues ComputeDoglegPoint(double delta, const VectorValues &dx_u, const VectorValues &dx_n, const bool verbose=false)
Definition: DoglegOptimizerImpl.cpp:26
gtsam.examples.PlanarManipulatorExample.delta
def delta(g0, g1)
Definition: PlanarManipulatorExample.py:45
gtsam::VectorValues
Definition: VectorValues.h:74
mode
static const DiscreteKey mode(modeKey, 2)
gtsam::DoglegOptimizerImpl::TrustRegionAdaptationMode
TrustRegionAdaptationMode
Definition: DoglegOptimizerImpl.h:54
x0
static Symbol x0('x', 0)
gtsam::VectorValues::Zero
static VectorValues Zero(const VectorValues &other)
Definition: VectorValues.cpp:77
VectorValues.h
Factor Graph Values.
gtsam::symbol_shorthand::F
Key F(std::uint64_t j)
Definition: inference/Symbol.h:153
tree::f
Point2(* f)(const Point3 &, OptionalJacobian< 2, 3 >)
Definition: testExpression.cpp:218
gtsam
traits
Definition: SFMdata.h:40
gtsam::DoglegOptimizerImpl::SEARCH_REDUCE_ONLY
@ SEARCH_REDUCE_ONLY
Definition: DoglegOptimizerImpl.h:56
gtsam::DoglegOptimizerImpl::IterationResult
Definition: DoglegOptimizerImpl.h:35
exampleQR::Rd
Matrix Rd
Definition: testNoiseModel.cpp:215
gtsam::DoglegOptimizerImpl::SEARCH_EACH_ITERATION
@ SEARCH_EACH_ITERATION
Definition: DoglegOptimizerImpl.h:55
abs
#define abs(x)
Definition: datatypes.h:17
max
#define max(a, b)
Definition: datatypes.h:20
gttic
#define gttic(label)
Definition: timing.h:295
gtsam::DoglegOptimizerImpl::IterationResult::f_error
double f_error
Definition: DoglegOptimizerImpl.h:38
M
Matrix< RealScalar, Dynamic, Dynamic > M
Definition: bench_gemm.cpp:51


gtsam
Author(s):
autogenerated on Sun Dec 22 2024 04:11:29