23 #ifndef O2SCL_GSL_MMIN_BFGS2_H 24 #define O2SCL_GSL_MMIN_BFGS2_H 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> 35 #ifndef DOXYGEN_NO_O2NS 50 virtual double wrap_f(
double alpha)=0;
52 virtual double wrap_df(
double alpha)=0;
54 virtual void wrap_fdf(
double alpha,
double *f,
double *df)=0;
69 #ifndef DOXYGEN_INTERNAL 112 if (alpha == x_cache_key) {
119 for(
size_t i=0;i<dim;i++) {
120 av_x_alpha[i]=(*x)[i];
134 if (alpha==f_cache_key) {
138 f_alpha=(*func)(dim,av_x_alpha);
148 if (alpha==df_cache_key)
return df_alpha;
151 if (alpha!=g_cache_key) {
153 (*dfunc)(dim,av_x_alpha,av_g_alpha);
155 (*agrad)(dim,av_x_alpha,av_g_alpha);
166 virtual void wrap_fdf(
double alpha,
double *f,
double *df) {
169 if (alpha == f_cache_key && alpha == df_cache_key) {
174 if (alpha == f_cache_key || alpha == df_cache_key) {
181 f_alpha=(*func)(dim,av_x_alpha);
183 (*dfunc)(dim,av_x_alpha,av_g_alpha);
185 (*agrad)(dim,av_x_alpha,av_g_alpha);
214 double f, vec_t &t_g, vec_t &t_p, auto_grad_t *ag) {
218 if (dfunc!=0) grad_given=
true;
219 else grad_given=
false;
231 for(
size_t i=0;i<dim;i++) {
232 av_x_alpha[i]=(*x)[i];
233 av_g_alpha[i]=(*g)[i];
247 double t_f_alpha, t_df_alpha;
248 wrap_fdf(alpha,&t_f_alpha,&t_df_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];
269 for(
size_t i=0;i<dim;i++) {
270 av_x_alpha[i]=(*x)[i];
271 av_g_alpha[i]=(*g)[i];
292 #ifndef DOXYGEN_INTERNAL 302 double interp_quad(
double f0,
double fp0,
double f1,
double zl,
316 double cubic(
double c0,
double c1,
double c2,
double c3,
double z);
319 void check_extremum(
double c0,
double c1,
double c2,
double c3,
double z,
320 double *zmin,
double *fmin);
323 double interp_cubic(
double f0,
double fp0,
double f1,
324 double fp1,
double zl,
double zh);
327 double interpolate(
double a,
double fa,
double fpa,
double b,
328 double fb,
double fpb,
double xmin,
double xmax,
341 double tau1,
double tau2,
double tau3,
342 int order,
double alpha1,
double *alpha_new);
385 class def_auto_grad_t=
389 #ifndef DOXYGEN_INTERNAL 453 double alpha=0.0, alpha1;
460 if (pnorm == 0.0 || g0norm == 0.0 || fp0 == 0) {
461 for(
size_t i=0;i<this->dim;i++) st_dx[i]=0.0;
462 O2SCL_CONV2(
"Either pnorm, g0norm, or fp0 vanished in ",
463 "mmin_bfgs2::iterate().",
471 double dbl_eps=std::numeric_limits<double>::epsilon();
475 if (-delta_f>10.0*dbl_eps*fabs(f0)) del=-delta_f;
476 else del=10.0*dbl_eps*fabs(f0);
477 if (2.0*del/(-fp0)<1.0) alpha1=2.0*del/(-fp0);
485 status=lm.
minimize(wrap,rho,sigma,tau1,tau2,tau3,order,
490 "mmin_bfgs2::iterate().",
511 double dxg, dgg, dxdg, dgnorm, A, B;
514 for(
size_t i=0;i<dim;i++) dx0[i]=(*st_x)[i];
518 for(
size_t i=0;i<dim;i++) st_dx[i]=dx0[i];
521 for(
size_t i=0;i<dim;i++) dg0[i]=st_grad[i];
532 A=-(1.0 + dgnorm * dgnorm / dxdg) * B + dgg / dxdg;
538 for(
size_t i=0;i<dim;i++) p[i]=st_grad[i];
543 for(
size_t i=0;i<dim;i++) {
554 dir=(pg >= 0.0) ? -1.0 : +1.0;
565 virtual const char *
type() {
return "mmin_bfgs2";}
576 for(
size_t i=0;i<n;i++) {
618 virtual int set(vec_t &x,
double u_step_size,
double tol_u,
628 agrad->set_function(ufunc);
629 (*agrad)(dim,x,st_grad);
633 for(
size_t i=0;i<dim;i++) {
638 for(
size_t i=0;i<dim;i++) {
666 virtual int set_de(vec_t &x,
double u_step_size,
double tol_u,
667 func_t &ufunc, dfunc_t &udfunc) {
676 udfunc(dim,x,st_grad);
680 for(
size_t i=0;i<dim;i++) {
685 for(
size_t i=0;i<dim;i++) {
724 virtual int mmin(
size_t nn, vec_t &xx,
double &fmin,
728 O2SCL_ERR2(
"Tried to min over zero variables ",
736 set(xx,step_size,lmin_tol,ufunc);
753 if(this->verbose>0) {
754 this->print_iter(nn,*st_x,st_f,xiter,
755 norm,this->tol_rel,
"mmin_bfgs2");
758 if (norm<this->tol_rel) {
764 }
while (status ==
gsl_continue && xiter < this->ntrial);
766 std::cout <<
"H: " << (*st_x)[0] << std::endl;
767 for(
size_t i=0;i<nn;i++) xx[i]=(*st_x)[i];
771 this->last_ntrial=xiter;
783 virtual int mmin_de(
size_t nn, vec_t &xx,
double &fmin,
784 func_t &ufunc, dfunc_t &udfunc) {
787 O2SCL_ERR2(
"Tried to min over zero variables ",
795 set_de(xx,step_size,lmin_tol,ufunc,udfunc);
811 if(this->verbose>0) {
812 this->print_iter(nn,*st_x,st_f,xiter,
813 norm,this->tol_rel,
"mmin_bfgs2");
816 if (norm<this->tol_rel) status=
success;
819 }
while (status ==
gsl_continue && xiter < this->ntrial);
821 for(
size_t i=0;i<nn;i++) xx[i]=(*st_x)[i];
825 this->last_ntrial=xiter;
835 #ifndef DOXYGEN_INTERNAL 842 (
const mmin_bfgs2<func_t,vec_t,dfunc_t,auto_grad_t,def_auto_grad_t>&);
848 #ifndef DOXYGEN_NO_O2NS Class for automatically computing gradients [abstract base].
void update_position(double alpha, vec_t &t_x, double *t_f, vec_t &t_g)
Update position.
double step_size
The size of the first trial step (default 0.01)
The main O<span style='position: relative; top: 0.3em; font-size: 0.8em'>2</span>scl O$_2$scl names...
dfunc_t * dfunc
Derivative.
double lmin_tol
The tolerance for the 1-dimensional minimizer.
#define O2SCL_CONV_RET(d, n, b)
Set a "convergence" error and return the error value.
void moveto(double alpha)
Move to a new point, using the cached value if possible.
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.
The line minimizer for mmin_bfgs2.
vec_t av_x_alpha
Temporary storage.
invalid argument supplied by user
virtual void wrap_fdf(double alpha, double *f, double *df)=0
Function and derivative.
virtual int iterate()
Perform an iteration.
bool grad_given
True if the gradient was given by the user.
exceeded max number of iterations
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
void change_direction()
Convert cache values to the new minimizer direction.
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.
virtual int allocate(size_t n)
Allocate the memory.
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.
virtual int free()
Free the allocated memory.
double dnrm2(const size_t N, const vec_t &X)
Compute the norm of the vector X.
iteration is not making progress toward solution
virtual double wrap_df(double alpha)
Evaluate the derivative.
Multidimensional minimization [abstract base].
vec_t av_g_alpha
Temporary storage.
#define O2SCL_ERR2(d, d2, n)
Set an error, two-string version.
def_auto_grad_t def_grad
Default automatic gradient object.
double ddot(const size_t N, const vec_t &X, const vec2_t &Y)
Compute .
int restart()
Reset the minimizer to use the current point as a new starting point.
Simple automatic computation of gradient by finite differencing.
virtual double wrap_df(double alpha)=0
Derivative.
virtual double wrap_f(double alpha)
Evaluate the function.
#define O2SCL_CONV2(d, d2, n, b)
Set a "convergence" error, two-string version.
virtual void wrap_fdf(double alpha, double *f, double *df)
Evaluate the function and the derivative.
void dscal(const double alpha, const size_t N, vec_t &X)
Compute .
auto_grad_t * agrad
Automatic gradient object.
std::function< int(size_t, boost::numeric::ublas::vector< double > &, boost::numeric::ublas::vector< double > &)> grad_funct11
Array of multi-dimensional functions typedef.
double slope()
Compute the slope.
void daxpy(const double alpha, const size_t N, const vec_t &X, vec2_t &Y)
Compute .
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.
Virtual base for the mmin_bfgs2 wrapper.
Wrapper class for the mmin_bfgs2 minimizer.
Multidimensional minimization by the BFGS algorithm (GSL)
std::function< double(size_t, const boost::numeric::ublas::vector< double > &)> multi_funct11
Multi-dimensional function typedef.
virtual const char * type()
Return string denoting type("mmin_bfgs2")
mmin_linmin_gsl lm
The line minimizer.
auto_grad_t * agrad
The automatic gradient object.
virtual double wrap_f(double alpha)=0
Function.
size_t dim
Number of minimization dimensions.