All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
mmin_bfgs2.h
Go to the documentation of this file.
1 /*
2  -------------------------------------------------------------------
3 
4  Copyright (C) 2006-2014, Andrew W. Steiner
5 
6  This file is part of O2scl.
7 
8  O2scl is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 3 of the License, or
11  (at your option) any later version.
12 
13  O2scl is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with O2scl. If not, see <http://www.gnu.org/licenses/>.
20 
21  -------------------------------------------------------------------
22 */
23 #ifndef O2SCL_GSL_MMIN_BFGS2_H
24 #define O2SCL_GSL_MMIN_BFGS2_H
25 
26 /** \file mmin_bfgs2.h
27  \brief File defining \ref o2scl::mmin_bfgs2
28 */
29 #include <gsl/gsl_blas.h>
30 #include <gsl/gsl_poly.h>
31 #include <gsl/gsl_multimin.h>
32 #include <o2scl/mmin.h>
33 #include <o2scl/cblas.h>
34 
35 #ifndef DOXYGEN_NO_O2NS
36 namespace o2scl {
37 #endif
38 
39  /** \brief Virtual base for the mmin_bfgs2 wrapper
40 
41  This class is useful so that the gsl_mmin_linmin class doesn't
42  need to depend on any template parameters, even though it will
43  need a wrapping object as an argument for the
44  gsl_mmin_linmin::min() function.
45  */
46  class mmin_wrap_gsl {
47  public:
48  virtual ~mmin_wrap_gsl() {}
49  /// Function
50  virtual double wrap_f(double alpha)=0;
51  /// Derivative
52  virtual double wrap_df(double alpha)=0;
53  /// Function and derivative
54  virtual void wrap_fdf(double alpha, double *f, double *df)=0;
55  };
56 
57  /** \brief Wrapper class for the mmin_bfgs2 minimizer
58 
59  This is a reimplmentation of the internal GSL wrapper for
60  function calls in the BFGS minimizer
61  */
62  template<class func_t=multi_funct11,
64  class dfunc_t=grad_funct11,
65  class auto_grad_t=
68 
69 #ifndef DOXYGEN_INTERNAL
70 
71  protected:
72 
73  /// Function
74  func_t *func;
75 
76  /// Derivative
77  dfunc_t *dfunc;
78 
79  /// The automatic gradient object
80  auto_grad_t *agrad;
81 
82  /// True if the gradient was given by the user
83  bool grad_given;
84 
85  /** \name fixed values
86  */
87  //@{
88  vec_t *x;
89  vec_t *g;
90  vec_t *p;
91  //@}
92 
93  /** \name cached values, for x(alpha)=x + alpha * p
94  */
95  //@{
96  double f_alpha;
97  double df_alpha;
98  //@}
99 
100  /** \name cache keys
101  */
102  //@{
103  double f_cache_key;
104  double df_cache_key;
105  double x_cache_key;
106  double g_cache_key;
107  //@}
108 
109  /// Move to a new point, using the cached value if possible
110  void moveto(double alpha) {
111 
112  if (alpha == x_cache_key) {
113  /* using previously cached position */
114  return;
115  }
116 
117  /* set x_alpha=x + alpha * p */
118 
119  for(size_t i=0;i<dim;i++) {
120  av_x_alpha[i]=(*x)[i];
121  }
122  o2scl_cblas::daxpy(alpha,dim,*p,av_x_alpha);
123 
124  x_cache_key=alpha;
125  }
126 
127  /// Compute the slope
128  double slope() {
129  return o2scl_cblas::ddot(dim,av_g_alpha,*p);
130  }
131 
132  /// Evaluate the function
133  virtual double wrap_f(double alpha) {
134  if (alpha==f_cache_key) {
135  return f_alpha;
136  }
137  moveto(alpha);
138  f_alpha=(*func)(dim,av_x_alpha);
139 
140  f_cache_key=alpha;
141  return f_alpha;
142  }
143 
144  /// Evaluate the derivative
145  virtual double wrap_df(double alpha) {
146 
147  /* using previously cached df(alpha) */
148  if (alpha==df_cache_key) return df_alpha;
149 
150  moveto(alpha);
151  if (alpha!=g_cache_key) {
152  if (grad_given) {
153  (*dfunc)(dim,av_x_alpha,av_g_alpha);
154  } else {
155  (*agrad)(dim,av_x_alpha,av_g_alpha);
156  }
157  g_cache_key=alpha;
158  }
159  df_alpha=slope();
160  df_cache_key=alpha;
161 
162  return df_alpha;
163  }
164 
165  /// Evaluate the function and the derivative
166  virtual void wrap_fdf(double alpha, double *f, double *df) {
167 
168  /* Check for previously cached values */
169  if (alpha == f_cache_key && alpha == df_cache_key) {
170  *f=f_alpha;
171  *df=df_alpha;
172  return;
173  }
174  if (alpha == f_cache_key || alpha == df_cache_key) {
175  *f=wrap_f(alpha);
176  *df=wrap_df(alpha);
177  return;
178  }
179 
180  moveto(alpha);
181  f_alpha=(*func)(dim,av_x_alpha);
182  if (grad_given) {
183  (*dfunc)(dim,av_x_alpha,av_g_alpha);
184  } else {
185  (*agrad)(dim,av_x_alpha,av_g_alpha);
186  }
187  f_cache_key=alpha;
188  g_cache_key=alpha;
189 
190  df_alpha=slope();
191  df_cache_key=alpha;
192 
193  *f=f_alpha;
194  *df=df_alpha;
195 
196  return;
197  }
198 
199 #endif
200 
201  public:
202 
203  /// Temporary storage
204  vec_t av_x_alpha;
205 
206  /// Temporary storage
207  vec_t av_g_alpha;
208 
209  /// Number of minimization dimensions
210  size_t dim;
211 
212  /// Initialize wrapper
213  void prepare_wrapper(func_t &ufunc, dfunc_t *udfunc, vec_t &t_x,
214  double f, vec_t &t_g, vec_t &t_p, auto_grad_t *ag) {
215 
216  func=&ufunc;
217  dfunc=udfunc;
218  if (dfunc!=0) grad_given=true;
219  else grad_given=false;
220  agrad=ag;
221 
222  x=&t_x;
223  g=&t_g;
224  p=&t_p;
225 
226  x_cache_key=0.0;
227  f_cache_key=0.0;
228  g_cache_key=0.0;
229  df_cache_key=0.0;
230 
231  for(size_t i=0;i<dim;i++) {
232  av_x_alpha[i]=(*x)[i];
233  av_g_alpha[i]=(*g)[i];
234  }
235 
236  f_alpha=f;
237  df_alpha=slope();
238 
239  return;
240  }
241 
242  /// Update position
243  void update_position(double alpha, vec_t &t_x, double *t_f, vec_t &t_g) {
244 
245  /* ensure that everything is fully cached */
246  {
247  double t_f_alpha, t_df_alpha;
248  wrap_fdf(alpha,&t_f_alpha,&t_df_alpha);
249  }
250 
251  *t_f=f_alpha;
252  for(size_t i=0;i<dim;i++) {
253  t_x[i]=av_x_alpha[i];
254  t_g[i]=av_g_alpha[i];
255  }
256  }
257 
258  /** \brief Convert cache values to the new minimizer direction
259 
260  Convert the cache values from the end of the current minimisation
261  to those needed for the start of the next minimisation, alpha=0
262  */
264 
265  /* The new x_alpha for alpha=0 is the current position and the
266  new g_alpha for alpha=0 is the current gradient at the
267  endpoint
268  */
269  for(size_t i=0;i<dim;i++) {
270  av_x_alpha[i]=(*x)[i];
271  av_g_alpha[i]=(*g)[i];
272  }
273  x_cache_key=0.0;
274  g_cache_key=0.0;
275 
276  /* The function value does not change */
277  f_cache_key=0.0;
278 
279  /* Calculate the slope along the new direction vector, p */
280  df_alpha=slope();
281  df_cache_key=0.0;
282 
283  return;
284  }
285 
286  };
287 
288  /** \brief The line minimizer for mmin_bfgs2
289  */
291 
292 #ifndef DOXYGEN_INTERNAL
293 
294  protected:
295 
296  /** \brief Minimize the interpolating quadratic
297 
298  Find a minimum in x=[0,1] of the interpolating quadratic through
299  (0,f0) (1,f1) with derivative fp0 at x=0. The interpolating
300  polynomial is q(x)=f0 + fp0 * z + (f1-f0-fp0) * z^2
301  */
302  double interp_quad(double f0, double fp0, double f1, double zl,
303  double zh);
304 
305  /** \brief Minimize the interpolating cubic
306 
307  Find a minimum in x=[0,1] of the interpolating cubic through
308  (0,f0) (1,f1) with derivatives fp0 at x=0 and fp1 at x=1.
309 
310  The interpolating polynomial is:
311 
312  c(x)=f0 + fp0 * z + eta * z^2 + xi * z^3
313 
314  where eta=3*(f1-f0)-2*fp0-fp1, xi=fp0+fp1-2*(f1-f0).
315  */
316  double cubic(double c0, double c1, double c2, double c3, double z);
317 
318  /// Test to see curvature is positive
319  void check_extremum(double c0, double c1, double c2, double c3, double z,
320  double *zmin, double *fmin);
321 
322  /// Interpolate using a cubic
323  double interp_cubic(double f0, double fp0, double f1,
324  double fp1, double zl, double zh);
325 
326  /// Perform the interpolation
327  double interpolate(double a, double fa, double fpa, double b,
328  double fb, double fpb, double xmin, double xmax,
329  int order);
330 #endif
331 
332  public:
333 
334  /** \brief The line minimization
335 
336  Recommended values from \ref Fletcher87 are
337  <tt>rho=0.01, sigma=0.1, tau1=9, tau2=0.05,
338  tau3=0.5 </tt>
339  */
340  int minimize(mmin_wrap_gsl &wrap, double rho, double sigma,
341  double tau1, double tau2, double tau3,
342  int order, double alpha1, double *alpha_new);
343  };
344 
345  /** \brief Multidimensional minimization by the BFGS
346  algorithm (GSL)
347 
348  The functions mmin() and mmin_de() min a given function
349  until the gradient is smaller than the value of mmin::tol_rel
350  (which defaults to \f$ 10^{-4} \f$ ).
351 
352  See an example for the usage of this class in
353  \ref ex_mmin_sect .
354 
355  This class includes the optimizations from the GSL minimizer \c
356  vector_bfgs2.
357 
358  Default template arguments
359  - \c func_t - \ref multi_funct11
360  - \c vec_t - \ref boost::numeric::ublas::vector <double >
361  - \c dfunc_t - \ref mm_funct11
362  - \c auto_grad_t - \ref gradient<func_t,
363  \ref boost::numeric::ublas::vector <double > >
364  - \c def_auto_grad_t - \ref gradient_gsl<func_t,
365  \ref boost::numeric::ublas::vector < double > >
366 
367  \todo While BFGS does well in the \c ex_mmin example with the
368  initial guess of \f$ (1,0,7\pi) \f$ it seems to converge more
369  poorly for the spring function than the other minimizers with
370  other initial guesses, and I think this will happen in the GSL
371  versions too. I need to examine this more closely with some code
372  designed to clearly show this.
373  */
374  template<class func_t=multi_funct11,
376  class dfunc_t=grad_funct11,
377  class auto_grad_t=
379  class def_auto_grad_t=
381  class mmin_bfgs2 : public mmin_base<func_t,func_t,vec_t> {
382 
383 #ifndef DOXYGEN_INTERNAL
384 
385  protected:
386 
387  /// \name The original variables from the GSL state structure
388  //@{
389  int iter;
390  double step;
391  double g0norm;
392  double pnorm;
393  double delta_f;
394  /* f'(0) for f(x-alpha*p) */
395  double fp0;
396  vec_t x0;
397  vec_t g0;
398  vec_t p;
399  /* work space */
400  vec_t dx0;
401  vec_t dg0;
402  /* wrapper function */
404  /* minimization parameters */
405  double rho;
406  double sigma;
407  double tau1;
408  double tau2;
409  double tau3;
410  int order;
411  //@}
412 
413  /// The line minimizer
415 
416  /// \name Store the arguments to set() so we can use them for iterate()
417  //@{
418  vec_t *st_x;
419  vec_t st_dx;
420  vec_t st_grad;
421  double st_f;
422  //@}
423 
424  /// Memory size
425  size_t dim;
426 
427  /// Automatic gradient object
428  auto_grad_t *agrad;
429 
430 #endif
431 
432  public:
433 
434  mmin_bfgs2() {
435  // The default values of lmin_tol and step_size from the
436  // example in the GSL documentation
437  lmin_tol=1.0e-4;
438  step_size=0.01;
439  agrad=&def_grad;
440  }
441 
442  virtual ~mmin_bfgs2() {}
443 
444  /// Perform an iteration
445  virtual int iterate() {
446 
447  double alpha=0.0, alpha1;
448 
449  double pg, dir;
450  int status;
451 
452  double f0=st_f;
453 
454  if (pnorm == 0.0 || g0norm == 0.0 || fp0 == 0) {
455  for(size_t i=0;i<this->dim;i++) st_dx[i]=0.0;
456  O2SCL_CONV2("Either pnorm, g0norm, or fp0 vanished in ",
457  "mmin_bfgs2::iterate().",
458  exc_enoprog,this->err_nonconv);
459  // The functions mmin() and mmin_de() use this return value, so
460  // when err_nonconv is false, we still want to return a non-zero
461  // value.
462  return exc_enoprog;
463  }
464 
465  double dbl_eps=std::numeric_limits<double>::epsilon();
466 
467  if (delta_f < 0) {
468  double del;
469  if (-delta_f>10.0*dbl_eps*fabs(f0)) del=-delta_f;
470  else del=10.0*dbl_eps*fabs(f0);
471  if (2.0*del/(-fp0)<1.0) alpha1=2.0*del/(-fp0);
472  else alpha1=1.0;
473  } else {
474  alpha1=fabs(step);
475  }
476 
477  /* line minimisation, with cubic interpolation (order=3) */
478 
479  status=lm.minimize(wrap,rho,sigma,tau1,tau2,tau3,order,
480  alpha1,&alpha);
481 
482  if (status != success) {
483  O2SCL_CONV2("Variable stepb vanished in ",
484  "mmin_bfgs2::iterate().",
485  exc_enoprog,this->err_nonconv);
486  // The functions mmin() and mmin_de() use this return value, so
487  // when err_nonconv is false, we still want to return a non-zero
488  // value.
489  return exc_enoprog;
490  }
491 
492  wrap.update_position(alpha,*st_x,&st_f,st_grad);
493 
494  delta_f=st_f - f0;
495 
496  /* Choose a new direction for the next step */
497 
498  {
499  /* This is the BFGS update: */
500  /* p'=g1 - A dx - B dg */
501  /* A=- (1+ dg.dg/dx.dg) B + dg.g/dx.dg */
502  /* B=dx.g/dx.dg */
503 
504  double dxg, dgg, dxdg, dgnorm, A, B;
505 
506  /* dx0=x - x0 */
507  for(size_t i=0;i<dim;i++) dx0[i]=(*st_x)[i];
508  o2scl_cblas::daxpy(-1.0,dim,x0,dx0);
509 
510  /* keep a copy */
511  for(size_t i=0;i<dim;i++) st_dx[i]=dx0[i];
512 
513  /* dg0=g - g0 */
514  for(size_t i=0;i<dim;i++) dg0[i]=st_grad[i];
515  o2scl_cblas::daxpy(-1.0,dim,g0,dg0);
516 
517  dxg=o2scl_cblas::ddot(dim,dx0,st_grad);
518  dgg=o2scl_cblas::ddot(dim,dg0,st_grad);
519  dxdg=o2scl_cblas::ddot(dim,dx0,dg0);
520 
521  dgnorm=o2scl_cblas::dnrm2(dim,dg0);
522 
523  if (dxdg != 0) {
524  B=dxg / dxdg;
525  A=-(1.0 + dgnorm * dgnorm / dxdg) * B + dgg / dxdg;
526  } else {
527  B=0;
528  A=0;
529  }
530 
531  for(size_t i=0;i<dim;i++) p[i]=st_grad[i];
532  o2scl_cblas::daxpy(-A,dim,dx0,p);
533  o2scl_cblas::daxpy(-B,dim,dg0,p);
534  }
535 
536  for(size_t i=0;i<dim;i++) {
537  g0[i]=st_grad[i];
538  x0[i]=(*st_x)[i];
539  }
540 
541  g0norm=o2scl_cblas::dnrm2(dim,g0);
542  pnorm=o2scl_cblas::dnrm2(dim,p);
543 
544  /* update direction and fp0 */
545 
546  pg=o2scl_cblas::ddot(dim,st_grad,p);
547  dir=(pg >= 0.0) ? -1.0 : +1.0;
548  o2scl_cblas::dscal(dir/pnorm,dim,p);
549  pnorm=o2scl_cblas::dnrm2(dim,p);
550  fp0=o2scl_cblas::ddot(dim,p,g0);
551 
552  wrap.change_direction();
553 
554  return success;
555  }
556 
557  /// Return string denoting type("mmin_bfgs2")
558  virtual const char *type() { return "mmin_bfgs2";}
559 
560  /// Allocate the memory
561  virtual int allocate(size_t n) {
562 
563  p.resize(n);
564  x0.resize(n);
565  g0.resize(n);
566  dx0.resize(n);
567  dg0.resize(n);
568 
569  for(size_t i=0;i<n;i++) {
570  p[i]=0.0;
571  x0[i]=0.0;
572  g0[i]=0.0;
573  dx0[i]=0.0;
574  dg0[i]=0.0;
575  }
576 
577  st_dx.resize(n);
578  st_grad.resize(n);
579 
580  wrap.av_x_alpha.resize(n);
581  wrap.av_g_alpha.resize(n);
582  wrap.dim=n;
583  dim=n;
584 
585  return success;
586  }
587 
588  /// Free the allocated memory
589  virtual int free() {
590  wrap.av_x_alpha.clear();
591  wrap.av_g_alpha.clear();
592  st_grad.clear();
593  dg0.clear();
594  dx0.clear();
595  g0.clear();
596  x0.clear();
597  p.clear();
598  st_dx.clear();
599  wrap.dim=0;
600  dim=0;
601  return 0;
602  }
603 
604  /// Reset the minimizer to use the current point as a new starting point
605  int restart() {
606  iter=0;
607  return success;
608  }
609 
610  /// Set the function and initial guess
611  virtual int set(vec_t &x, double u_step_size, double tol_u,
612  func_t &ufunc) {
613 
614  iter=0;
615  step=u_step_size;
616  delta_f=0;
617 
618  st_x=&x;
619 
620  st_f=ufunc(dim,x);
621  agrad->set_function(ufunc);
622  (*agrad)(dim,x,st_grad);
623 
624  /* Use the gradient as the initial direction */
625 
626  for(size_t i=0;i<dim;i++) {
627  x0[i]=x[i];
628  g0[i]=st_grad[i];
629  }
630  g0norm=o2scl_cblas::dnrm2(dim,g0);
631  for(size_t i=0;i<dim;i++) {
632  p[i]=st_grad[i];
633  }
634  o2scl_cblas::dscal(-1.0/g0norm,dim,p);
635 
636  // pnorm should be 1
637  pnorm=o2scl_cblas::dnrm2(dim,p);
638  fp0=-g0norm;
639 
640  /* Prepare the wrapper */
641 
642  wrap.prepare_wrapper(ufunc,0,x0,st_f,g0,p,agrad);
643 
644  /* Prepare 1d minimisation parameters */
645 
646  rho=0.01;
647  sigma=tol_u;
648  tau1=9;
649  tau2=0.05;
650  tau3=0.5;
651  // use cubic interpolation where possible
652  order=3;
653 
654  return success;
655 
656  }
657 
658  /// Set the function, the gradient, and the initial guess
659  virtual int set_de(vec_t &x, double u_step_size, double tol_u,
660  func_t &ufunc, dfunc_t &udfunc) {
661 
662  iter=0;
663  step=u_step_size;
664  delta_f=0;
665 
666  st_x=&x;
667 
668  st_f=ufunc(dim,x);
669  udfunc(dim,x,st_grad);
670 
671  /* Use the gradient as the initial direction */
672 
673  for(size_t i=0;i<dim;i++) {
674  x0[i]=x[i];
675  g0[i]=st_grad[i];
676  }
677  g0norm=o2scl_cblas::dnrm2(dim,g0);
678  for(size_t i=0;i<dim;i++) {
679  p[i]=st_grad[i];
680  }
681  o2scl_cblas::dscal(-1.0/g0norm,dim,p);
682 
683  // pnorm should be 1
684  pnorm=o2scl_cblas::dnrm2(dim,p);
685  fp0=-g0norm;
686 
687  /* Prepare the wrapper */
688 
689  wrap.prepare_wrapper(ufunc,&udfunc,x0,st_f,g0,p,agrad);
690 
691  /* Prepare 1d minimisation parameters */
692 
693  rho=0.01;
694  sigma=tol_u;
695  tau1=9;
696  tau2=0.05;
697  tau3=0.5;
698  // use cubic interpolation where possible
699  order=3;
700 
701  return success;
702 
703  }
704 
705  /// The size of the first trial step (default 0.01)
706  double step_size;
707 
708  /// The tolerance for the 1-dimensional minimizer
709  double lmin_tol;
710 
711  /// Default automatic gradient object
712  def_auto_grad_t def_grad;
713 
714  /** \brief Calculate the minimum \c min of \c func w.r.t the
715  array \c x of size \c nn.
716  */
717  virtual int mmin(size_t nn, vec_t &xx, double &fmin,
718  func_t &ufunc) {
719 
720  if (nn==0) {
721  O2SCL_ERR2("Tried to min over zero variables ",
722  " in mmin_bfgs2::mmin().",exc_einval);
723  }
724 
725  int xiter=0, status;
726 
727  allocate(nn);
728 
729  set(xx,step_size,lmin_tol,ufunc);
730 
731  do {
732 
733  xiter++;
734 
735  status=iterate();
736 
737  if (status) {
738  break;
739  }
740 
741  // Equivalent to gsl_multimin_test_gradient with
742  // additional code to print out present iteration
743 
744  double norm=o2scl_cblas::dnrm2(nn,st_grad);
745 
746  if(this->verbose>0) {
747  this->print_iter(nn,*st_x,st_f,xiter,
748  norm,this->tol_rel,"mmin_bfgs2");
749  }
750 
751  if (norm<this->tol_rel) {
752  status=success;
753  } else {
754  status=gsl_continue;
755  }
756 
757  } while (status == gsl_continue && xiter < this->ntrial);
758 
759  for(size_t i=0;i<nn;i++) xx[i]=(*st_x)[i];
760  fmin=st_f;
761 
762  free();
763  this->last_ntrial=xiter;
764 
765  if (status==gsl_continue && xiter==this->ntrial) {
766  O2SCL_CONV_RET("Too many iterations in mmin_bfgs2::mmin().",
767  exc_emaxiter,this->err_nonconv);
768  }
769  return status;
770  }
771 
772  /** \brief Calculate the minimum \c min of \c func w.r.t the
773  array \c x of size \c nn.
774  */
775  virtual int mmin_de(size_t nn, vec_t &xx, double &fmin,
776  func_t &ufunc, dfunc_t &udfunc) {
777 
778  if (nn==0) {
779  O2SCL_ERR2("Tried to min over zero variables ",
780  "in mmin_bfgs2::mmin().",exc_einval);
781  }
782 
783  int xiter=0, status;
784 
785  allocate(nn);
786 
787  set_de(xx,step_size,lmin_tol,ufunc,udfunc);
788 
789  do {
790  xiter++;
791 
792  status=iterate();
793 
794  if (status) {
795  break;
796  }
797 
798  // Equivalent to gsl_multimin_test_gradient with
799  // additional code to print out present iteration
800 
801  double norm=o2scl_cblas::dnrm2(nn,st_grad);
802 
803  if(this->verbose>0) {
804  this->print_iter(nn,*st_x,st_f,xiter,
805  norm,this->tol_rel,"mmin_bfgs2");
806  }
807 
808  if (norm<this->tol_rel) status=success;
809  else status=gsl_continue;
810 
811  } while (status == gsl_continue && xiter < this->ntrial);
812 
813  for(size_t i=0;i<nn;i++) xx[i]=(*st_x)[i];
814  fmin=st_f;
815 
816  free();
817  this->last_ntrial=xiter;
818 
819  if (status==gsl_continue && xiter==this->ntrial) {
820  O2SCL_CONV_RET("Too many iterations in mmin_bfgs2::mmin_de().",
821  exc_emaxiter,this->err_nonconv);
822  }
823 
824  return status;
825  }
826 
827 #ifndef DOXYGEN_INTERNAL
828 
829  private:
830 
835 
836 #endif
837 
838  };
839 
840 #ifndef DOXYGEN_NO_O2NS
841 }
842 #endif
843 
844 #endif
Class for automatically computing gradients [abstract base].
Definition: mmin.h:53
void update_position(double alpha, vec_t &t_x, double *t_f, vec_t &t_g)
Update position.
Definition: mmin_bfgs2.h:243
double step_size
The size of the first trial step (default 0.01)
Definition: mmin_bfgs2.h:706
dfunc_t * dfunc
Derivative.
Definition: mmin_bfgs2.h:77
double lmin_tol
The tolerance for the 1-dimensional minimizer.
Definition: mmin_bfgs2.h:709
#define O2SCL_CONV_RET(d, n, b)
Set a "convergence" error and return the error value.
Definition: err_hnd.h:292
void moveto(double alpha)
Move to a new point, using the cached value if possible.
Definition: mmin_bfgs2.h:110
virtual int mmin_de(size_t nn, vec_t &xx, double &fmin, func_t &ufunc, dfunc_t &udfunc)
Calculate the minimum min of func w.r.t the array x of size nn.
Definition: mmin_bfgs2.h:775
The line minimizer for mmin_bfgs2.
Definition: mmin_bfgs2.h:290
double interp_quad(double f0, double fp0, double f1, double zl, double zh)
Minimize the interpolating quadratic.
vec_t av_x_alpha
Temporary storage.
Definition: mmin_bfgs2.h:204
double interp_cubic(double f0, double fp0, double f1, double fp1, double zl, double zh)
Interpolate using a cubic.
invalid argument supplied by user
Definition: err_hnd.h:59
virtual void wrap_fdf(double alpha, double *f, double *df)=0
Function and derivative.
virtual int iterate()
Perform an iteration.
Definition: mmin_bfgs2.h:445
bool grad_given
True if the gradient was given by the user.
Definition: mmin_bfgs2.h:83
virtual int set(vec_t &x, double u_step_size, double tol_u, func_t &ufunc)
Set the function and initial guess.
Definition: mmin_bfgs2.h:611
exceeded max number of iterations
Definition: err_hnd.h:73
int minimize(mmin_wrap_gsl &wrap, double rho, double sigma, double tau1, double tau2, double tau3, int order, double alpha1, double *alpha_new)
The line minimization.
iteration has not converged
Definition: err_hnd.h:51
void change_direction()
Convert cache values to the new minimizer direction.
Definition: mmin_bfgs2.h:263
virtual int mmin(size_t nn, vec_t &xx, double &fmin, func_t &ufunc)
Calculate the minimum min of func w.r.t the array x of size nn.
Definition: mmin_bfgs2.h:717
void check_extremum(double c0, double c1, double c2, double c3, double z, double *zmin, double *fmin)
Test to see curvature is positive.
virtual int allocate(size_t n)
Allocate the memory.
Definition: mmin_bfgs2.h:561
virtual int set_de(vec_t &x, double u_step_size, double tol_u, func_t &ufunc, dfunc_t &udfunc)
Set the function, the gradient, and the initial guess.
Definition: mmin_bfgs2.h:659
virtual int free()
Free the allocated memory.
Definition: mmin_bfgs2.h:589
double dnrm2(const size_t N, const vec_t &X)
Compute the norm of the vector X.
Definition: cblas_base.h:156
func_t * func
Function.
Definition: mmin_bfgs2.h:74
bool err_nonconv
If true, call the error handler if the routine does not "converge".
Definition: mmin.h:208
double cubic(double c0, double c1, double c2, double c3, double z)
Minimize the interpolating cubic.
iteration is not making progress toward solution
Definition: err_hnd.h:105
virtual double wrap_df(double alpha)
Evaluate the derivative.
Definition: mmin_bfgs2.h:145
Multidimensional minimization [abstract base].
Definition: mmin.h:163
int print_iter(size_t nv, vec2_t &x, double y, int iter, double value, double limit, std::string comment)
Print out iteration information.
Definition: mmin.h:248
vec_t av_g_alpha
Temporary storage.
Definition: mmin_bfgs2.h:207
#define O2SCL_ERR2(d, d2, n)
Set an error, two-string version.
Definition: err_hnd.h:281
def_auto_grad_t def_grad
Default automatic gradient object.
Definition: mmin_bfgs2.h:712
double interpolate(double a, double fa, double fpa, double b, double fb, double fpb, double xmin, double xmax, int order)
Perform the interpolation.
double ddot(const size_t N, const vec_t &X, const vec2_t &Y)
Compute .
Definition: cblas_base.h:123
int restart()
Reset the minimizer to use the current point as a new starting point.
Definition: mmin_bfgs2.h:605
Simple automatic computation of gradient by finite differencing.
Definition: mmin.h:95
virtual double wrap_df(double alpha)=0
Derivative.
virtual double wrap_f(double alpha)
Evaluate the function.
Definition: mmin_bfgs2.h:133
size_t dim
Memory size.
Definition: mmin_bfgs2.h:425
#define O2SCL_CONV2(d, d2, n, b)
Set a "convergence" error, two-string version.
Definition: err_hnd.h:286
int last_ntrial
The number of iterations for in the most recent minimization.
Definition: mmin.h:205
virtual void wrap_fdf(double alpha, double *f, double *df)
Evaluate the function and the derivative.
Definition: mmin_bfgs2.h:166
void dscal(const double alpha, const size_t N, vec_t &X)
Compute .
Definition: cblas_base.h:190
auto_grad_t * agrad
Automatic gradient object.
Definition: mmin_bfgs2.h:428
std::function< int(size_t, boost::numeric::ublas::vector< double > &, boost::numeric::ublas::vector< double > &)> grad_funct11
Array of multi-dimensional functions typedef.
Definition: mmin.h:41
double slope()
Compute the slope.
Definition: mmin_bfgs2.h:128
void daxpy(const double alpha, const size_t N, const vec_t &X, vec2_t &Y)
Compute .
Definition: cblas_base.h:98
double tol_rel
Function value tolerance.
Definition: mmin.h:199
void prepare_wrapper(func_t &ufunc, dfunc_t *udfunc, vec_t &t_x, double f, vec_t &t_g, vec_t &t_p, auto_grad_t *ag)
Initialize wrapper.
Definition: mmin_bfgs2.h:213
Virtual base for the mmin_bfgs2 wrapper.
Definition: mmin_bfgs2.h:46
Wrapper class for the mmin_bfgs2 minimizer.
Definition: mmin_bfgs2.h:67
Multidimensional minimization by the BFGS algorithm (GSL)
Definition: mmin_bfgs2.h:381
std::function< double(size_t, const boost::numeric::ublas::vector< double > &)> multi_funct11
Multi-dimensional function typedef.
Definition: multi_funct.h:45
Success.
Definition: err_hnd.h:47
virtual const char * type()
Return string denoting type("mmin_bfgs2")
Definition: mmin_bfgs2.h:558
mmin_linmin_gsl lm
The line minimizer.
Definition: mmin_bfgs2.h:414
auto_grad_t * agrad
The automatic gradient object.
Definition: mmin_bfgs2.h:80
virtual double wrap_f(double alpha)=0
Function.
size_t dim
Number of minimization dimensions.
Definition: mmin_bfgs2.h:210
int ntrial
Maximum number of iterations.
Definition: mmin.h:196

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).
Hosted at Get Object-oriented Scientific Computing
Lib at SourceForge.net. Fast, secure and Free Open Source software
downloads..