00001
00002
00003
00004
00005
00006
00007 #include <admodel.h>
00008
00009 #ifdef __cplusplus
00010 extern "C" {
00011 #endif
00012 int lbfgs_(long int *, long int *, double *,
00013 double *, double *, long int *, double *, long int *,
00014 double *, double *, double *, long int *,long int *,
00015 long int *);
00016 #ifdef __cplusplus
00017 }
00018 #endif
00019
00020 void function_minimizer::limited_memory_quasi_newton(const independent_variables& _x, int m)
00021 {
00022 independent_variables& x = (independent_variables&) _x;
00023 if (m<=0)
00024 {
00025 cerr << "illegal value for number of steps in limited memory"
00026 " quasi-newton method -- set equal to 10" << endl;
00027 }
00028 int noprintx=0;
00029 int on;
00030 int maxfn_option=0;
00031 if ( (on=option_match(ad_comm::argc,ad_comm::argv,"-maxfn"))>-1)
00032 {
00033 maxfn_option=1;
00034 }
00035 if ( (on=option_match(ad_comm::argc,ad_comm::argv,"-nox"))>-1)
00036 {
00037 noprintx=1;
00038 }
00039 int nvar=initial_params::nvarcalc();
00040 double _crit=0;
00041 int itn=0;
00042 int ifn=0;
00043 int nopt;
00044
00045 if ( (on=option_match(ad_comm::argc,ad_comm::argv,"-crit",nopt))>-1)
00046 {
00047 if (!nopt)
00048 {
00049 cerr << "Usage -crit option needs number -- ignored" << endl;
00050 }
00051 else
00052 {
00053 char * end;
00054 _crit=strtod(ad_comm::argv[on+1],&end);
00055 if (_crit<=0)
00056 {
00057 cerr << "Usage -crit option needs positive number -- ignored" << endl;
00058 _crit=0.0;
00059 }
00060 }
00061 }
00062
00063 gradient_structure::set_YES_DERIVATIVES();
00064
00065 if (!(!convergence_criteria))
00066 {
00067 int ind=min(convergence_criteria.indexmax(),
00068 initial_params::current_phase);
00069 crit=convergence_criteria(ind);
00070 }
00071 if (_crit)
00072 {
00073 crit = _crit;
00074 }
00075 if (!(!maximum_function_evaluations) && !maxfn_option)
00076 {
00077 int ind=min(maximum_function_evaluations.indexmax(),
00078 initial_params::current_phase);
00079 maxfn= (int) maximum_function_evaluations(ind);
00080 }
00081 dvariable vf=0.0;
00082
00083 double xtol, f;
00084 dvector diag(1,nvar);
00085
00086 int iflag, icall;
00087 double fbest=1.e+100;
00088 dvector g(1,nvar);
00089 g.initialize();
00090 dvector xbest(1,nvar);
00091 dvector gbest(1,nvar);
00092
00093 long int diagco=0.0;
00094 int iprintx[2];
00095
00096
00097 dvector w(1,nvar+2*m+2*nvar*m);
00098 nopt=0;
00099 int on1;
00100 if ( (on1=option_match(ad_comm::argc,ad_comm::argv,"-iprint",nopt))>-1)
00101 {
00102 if (!nopt)
00103 {
00104 cerr << "Usage -iprint option needs integer -- ignored" << endl;
00105 }
00106 else
00107 {
00108 int jj=atoi(ad_comm::argv[on1+1]);
00109 iprint=jj;
00110 }
00111 }
00112 iprintx[0] = iprint;
00113 iprintx[1] = 0;
00114 crit = 1e-5;
00115 xtol = 1e-16;
00116 icall = 0;
00117 iflag = 0;
00118 long int linfo=0;
00119
00120 L20:
00121 f = 0.;
00122 vf=initial_params::reset(dvar_vector(x));
00123 *objective_function_value::pobjfun=0.0;
00124 userfunction();
00125 vf+=*objective_function_value::pobjfun;
00126 f=value(vf);
00127 ifn++;
00128 if (f<fbest)
00129 {
00130 fbest=f;
00131 xbest=x;
00132 gbest=g;
00133 }
00134
00135 gradcalc(nvar,g);
00136 if(fmod(double(itn),double(iprint)) == 0)
00137 {
00138 if (iprint>0)
00139 {
00140 if (!itn)
00141 {
00142 if (ad_printf) (*ad_printf)("\nInitial statistics: ");
00143 }
00144 else
00145 {
00146 if (ad_printf) (*ad_printf)("\nIntermediate statistics: ");
00147 }
00148
00149 if (ad_printf) (*ad_printf)("%d variables; iteration %ld; function evaluation %ld\n",
00150 nvar, itn, ifn);
00151
00152 if (!itn)
00153 {
00154 if (ad_printf) (*ad_printf)("Function value %12.4le; maximum gradient component mag %12.4le\n",
00155 f, max(fabs(g)));
00156 }
00157 else
00158 {
00159
00160 if (ad_printf) (*ad_printf)("Function value %12.4le; maximum gradient component mag %12.4le\n",
00161 fbest, max(gbest));
00162 }
00163 if (!noprintx)
00164 {
00165 if (!itn)
00166 fmmdisp(x, g, nvar, 0,noprintx);
00167 else
00168 fmmdisp(xbest, gbest, nvar, 0,noprintx);
00169 }
00170 }
00171 }
00172
00173 long int lnvar=nvar;
00174 long int litn=itn;
00175 long int liprintx= *iprintx;
00176 long int liflag=iflag;
00177 long int lm=m;
00178 lbfgs_(&lnvar, &lm, &(x[1]) , &f, &(g[1]), &diagco, &(diag[1]),
00179 &liprintx, &crit, &xtol, &(w[1]), &liflag,&litn,&linfo);
00180 itn=int(litn);
00181 iflag=int(liflag);
00182
00183 if (iflag <= 0)
00184 {
00185 goto L50;
00186 }
00187 ++icall;
00188 if (icall > maxfn)
00189 {
00190 goto L50;
00191 }
00192 goto L20;
00193 L50:
00194 if (iprint>0)
00195 {
00196 if (ad_printf) (*ad_printf)("\nfinal statistics: ");
00197
00198 if (ad_printf) (*ad_printf)("%d variables; iteration %ld; function evaluation %ld\n",
00199 nvar, itn, ifn);
00200 if (ad_printf) (*ad_printf)("Function value %12.4le; maximum gradient component mag %12.4le\n",
00201 f, max(g));
00202 fmmdisp(x, g, nvar, 0,noprintx);
00203 }
00204 gradient_structure::set_NO_DERIVATIVES();
00205 x=xbest;
00206 objective_function_value::gmax=fabs(max(gbest));
00207 }
00208
00209 void function_minimizer::limited_memory_quasi_newton
00210 (double& f, const independent_variables& _x, int m, int noprintx,
00211 int maxfn, double crit)
00212 {
00213 independent_variables& x = (independent_variables&) _x;
00214 if (m<=0)
00215 {
00216 cerr << "illegal value for number of steps in limited memory"
00217 " quasi-newton method -- set equal to 10" << endl;
00218 }
00219 int on;
00220
00221 int nvar=initial_params::nvarcalc();
00222 double _crit=0;
00223 int itn=0;
00224 int ifn=0;
00225 int nopt;
00226
00227 if ( (on=option_match(ad_comm::argc,ad_comm::argv,"-crit",nopt))>-1)
00228 {
00229 if (!nopt)
00230 {
00231 cerr << "Usage -crit option needs number -- ignored" << endl;
00232 }
00233 else
00234 {
00235 char * end;
00236 _crit=strtod(ad_comm::argv[on+1],&end);
00237 if (_crit<=0)
00238 {
00239 cerr << "Usage -crit option needs positive number -- ignored" << endl;
00240 _crit=0.0;
00241 }
00242 }
00243 }
00244 gradient_structure::set_YES_DERIVATIVES();
00245 dvariable vf=0.0;
00246
00247 double xtol;
00248 dvector diag(1,nvar);
00249
00250 int iflag, icall;
00251 double fbest=1.e+100;
00252 dvector g(1,nvar);
00253 g.initialize();
00254 dvector xbest(1,nvar);
00255 dvector gbest(1,nvar);
00256
00257 long int diagco=0;
00258 int iprintx[2];
00259
00260
00261 dvector w(1,nvar+2*m+2*nvar*m);
00262 iprintx[0] = iprint;
00263 iprintx[1] = 0;
00264 crit = 1e-5;
00265 xtol = 1e-16;
00266 icall = 0;
00267 iflag = 0;
00268 long int linfo=0;
00269
00270 L20:
00271 f = 0.;
00272 vf=initial_params::reset(dvar_vector(x));
00273 *objective_function_value::pobjfun=0.0;
00274 userfunction();
00275 vf+=*objective_function_value::pobjfun;
00276 f=value(vf);
00277 ifn++;
00278 if (f<fbest)
00279 {
00280 fbest=f;
00281 xbest=x;
00282 gbest=g;
00283 }
00284
00285 gradcalc(nvar,g);
00286 if(fmod(double(itn),double(iprint)) == 0)
00287 {
00288 if (iprint>0)
00289 {
00290 if (!itn)
00291 {
00292 if (ad_printf) (*ad_printf)("\nInitial statistics: ");
00293 }
00294 else
00295 {
00296 if (ad_printf) (*ad_printf)("\nIntermediate statistics: ");
00297 }
00298
00299 if (ad_printf) (*ad_printf)("%d variables; iteration %ld; function evaluation %ld\n",
00300 nvar, itn, ifn);
00301
00302 if (!itn)
00303 {
00304 if (ad_printf) (*ad_printf)("Function value %12.4le; maximum gradient component mag %12.4le\n",
00305 f, max(g));
00306 }
00307 else
00308 {
00309 if (ad_printf) (*ad_printf)("Function value %12.4le; maximum gradient component mag %12.4le\n",
00310 fbest, max(gbest));
00311 }
00312 if (!noprintx)
00313 {
00314 if (!itn)
00315 fmmdisp(x, g, nvar, 0,noprintx);
00316 else
00317 fmmdisp(xbest, gbest, nvar, 0,noprintx);
00318 }
00319 }
00320 }
00321 long int lnvar=nvar;
00322 long int litn=itn;
00323 long int liprintx= *iprintx;
00324 long int liflag=iflag;
00325 long int lm=m;
00326 lbfgs_(&lnvar, &lm, &(x[1]) , &f, &(g[1]), &diagco, &(diag[1]),
00327 &liprintx, &crit, &xtol, &(w[1]), &liflag,&litn,&linfo);
00328 itn=int(litn);
00329 iflag=int(liflag);
00330
00331 if (iflag <= 0)
00332 {
00333 goto L50;
00334 }
00335 ++icall;
00336 if (icall > maxfn)
00337 {
00338 goto L50;
00339 }
00340 goto L20;
00341 L50:
00342 if (iprint>0)
00343 {
00344 if (ad_printf) (*ad_printf)("\nfinal statistics: ");
00345
00346 if (ad_printf) (*ad_printf)("%d variables; iteration %ld; function evaluation %ld\n",
00347 nvar, itn, ifn);
00348 if (ad_printf) (*ad_printf)("Function value %12.4le; maximum gradient component mag %12.4le\n",
00349 f, max(g));
00350 fmmdisp(x, g, nvar, 0,noprintx);
00351 }
00352
00353 x=xbest;
00354 f=fbest;
00355 objective_function_value::gmax=fabs(max(gbest));
00356 }
00357