int main(int argc, char **argv) { int n; int m; minlbfgsstate state; minlbfgsreport rep; ap::real_1d_array s; double x; double y; // // Function minimized: // F = exp(x-1) + exp(1-x) + (y-x)^2 // N = 2 - task dimension // M = 1 - build tank-1 model // n = 2; m = 1; s.setlength(2); s(0) = 10; s(1) = ap::randomreal()-0.5; minlbfgscreate(n, m, s, state); minlbfgssetcond(state, 0.0, 0.0, 0.0001, 0); minlbfgssetxrep(state, true); printf("\n\nF = exp(x-1) + exp(1-x) + (y-x)^2\n"); printf("OPTIMIZATION STARTED\n"); while(minlbfgsiteration(state)) { if( state.needfg ) { x = state.x(0); y = state.x(1); state.f = exp(x-1)+exp(1-x)+ap::sqr(y-x); state.g(0) = exp(x-1)-exp(1-x)+2*(x-y); state.g(1) = 2*(y-x); } if( state.xupdated ) { printf(" F(%8.5lf,%8.5lf)=%0.5lf\n", double(state.x(0)), double(state.x(1)), double(state.f)); } } printf("OPTIMIZATION STOPPED\n"); minlbfgsresults(state, s, rep); // // output results // printf("X = %4.2lf (should be 1.00)\n", double(s(0))); printf("Y = %4.2lf (should be 1.00)\n\n\n", double(s(1))); return 0; }
/************************************************************************* Extended subroutine for internal use only. Accepts additional parameters: Flags - additional settings: * Flags = 0 means no additional settings * Flags = 1 "do not allocate memory". used when solving a many subsequent tasks with same N/M values. First call MUST be without this flag bit set, subsequent calls of MinLBFGS with same MinLBFGSState structure can set Flags to 1. -- ALGLIB -- Copyright 02.04.2010 by Bochkanov Sergey *************************************************************************/ void minlbfgscreatex(int n, int m, const ap::real_1d_array& x, int flags, minlbfgsstate& state) { bool allocatemem; ap::ap_error::make_assertion(n>=1, "MinLBFGS: N too small!"); ap::ap_error::make_assertion(m>=1, "MinLBFGS: M too small!"); ap::ap_error::make_assertion(m<=n, "MinLBFGS: M too large!"); // // Initialize // state.n = n; state.m = m; state.flags = flags; allocatemem = flags%2==0; flags = flags/2; if( allocatemem ) { state.rho.setbounds(0, m-1); state.theta.setbounds(0, m-1); state.y.setbounds(0, m-1, 0, n-1); state.s.setbounds(0, m-1, 0, n-1); state.d.setbounds(0, n-1); state.x.setbounds(0, n-1); state.g.setbounds(0, n-1); state.work.setbounds(0, n-1); } minlbfgssetcond(state, double(0), double(0), double(0), 0); minlbfgssetxrep(state, false); minlbfgssetstpmax(state, double(0)); // // Prepare first run // state.k = 0; ap::vmove(&state.x(0), 1, &x(0), 1, ap::vlen(0,n-1)); state.rstate.ia.setbounds(0, 6); state.rstate.ra.setbounds(0, 4); state.rstate.stage = -1; }
void OptHOM::OptimPass(alglib::real_1d_array &x, int itMax) { static const double EPSG = 0.; static const double EPSF = 0.; static const double EPSX = 0.; static int OPTMETHOD = 1; Msg::Info("--- Optimization pass with initial jac. range (%g, %g), jacBar = %g", minJac, maxJac, jacBar); iter = 0; alglib::real_1d_array scale; calcScale(scale); int iterationscount = 0, nfev = 0, terminationtype = -1; if (OPTMETHOD == 1) { alglib::mincgstate state; alglib::mincgreport rep; try{ mincgcreate(x, state); mincgsetscale(state,scale); mincgsetprecscale(state); mincgsetcond(state, EPSG, EPSF, EPSX, itMax); mincgsetxrep(state, true); alglib::mincgoptimize(state, evalObjGradFunc, printProgressFunc, this); mincgresults(state, x, rep); } catch(alglib::ap_error e){ Msg::Error("%s", e.msg.c_str()); } iterationscount = rep.iterationscount; nfev = rep.nfev; terminationtype = rep.terminationtype; } else { alglib::minlbfgsstate state; alglib::minlbfgsreport rep; try{ minlbfgscreate(3, x, state); minlbfgssetscale(state,scale); minlbfgssetprecscale(state); minlbfgssetcond(state, EPSG, EPSF, EPSX, itMax); minlbfgssetxrep(state, true); alglib::minlbfgsoptimize(state, evalObjGradFunc, printProgressFunc, this); minlbfgsresults(state, x, rep); } catch(alglib::ap_error e){ Msg::Error("%s", e.msg.c_str()); } iterationscount = rep.iterationscount; nfev = rep.nfev; terminationtype = rep.terminationtype; } Msg::Info("Optimization finalized after %d iterations (%d function evaluations),", iterationscount, nfev); switch(int(terminationtype)) { case 1: Msg::Info("because relative function improvement is no more than EpsF"); break; case 2: Msg::Info("because relative step is no more than EpsX"); break; case 4: Msg::Info("because gradient norm is no more than EpsG"); break; case 5: Msg::Info("because the maximum number of steps was taken"); break; default: Msg::Info("with code %d", int(terminationtype)); break; } }