void MAST::NPSOLOptimizationInterface::optimize() { #if MAST_ENABLE_NPSOL == 1 // make sure that functions have been provided libmesh_assert(_funobj); libmesh_assert(_funcon); int N = _feval->n_vars(), NCLIN = 0, NCNLN = _feval->n_eq()+_feval->n_ineq(), NCTOTL = N+NCLIN+NCNLN, LDA = std::max(NCLIN, 1), LDJ = std::max(NCNLN, 1), LDR = N, INFORM = 0, // on exit: Reports result of call to NPSOL // < 0 either funobj or funcon has set this to -ve // 0 => converged to point x // 1 => x satisfies optimality conditions, but sequence of iterates has not converged // 2 => Linear constraints and bounds cannot be satisfied. No feasible solution // 3 => Nonlinear constraints and bounds cannot be satisfied. No feasible solution // 4 => Major iter limit was reached // 6 => x does not satisfy first-order optimality to required accuracy // 7 => function derivatives seem to be incorrect // 9 => input parameter invalid ITER = 0, // iter count LENIW = 3*N + NCLIN + 2*NCNLN, LENW = 2*N*N + N*NCLIN + 2*N*NCNLN + 20*N + 11*NCLIN + 21*NCNLN; Real F = 0.; // on exit: final objective std::vector<int> IW (LENIW, 0), ISTATE (NCTOTL, 0); // status of constraints l <= r(x) <= u, // -2 => lower bound is violated by more than delta // -1 => upper bound is violated by more than delta // 0 => both bounds are satisfied by more than delta // 1 => lower bound is active (to within delta) // 2 => upper bound is active (to within delta) // 3 => boundars are equal and equality constraint is satisfied std::vector<Real> A (LDA, 0.), // this is used for liear constraints, not currently handled BL (NCTOTL, 0.), BU (NCTOTL, 0.), C (NCNLN, 0.), // on exit: nonlinear constraints CJAC (LDJ* N, 0.), // // on exit: CJAC(i,j) is the partial derivative of ith nonlinear constraint CLAMBDA (NCTOTL, 0.), // on entry: need not be initialized for cold start // on exit: QP multiplier from the QP subproblem, >=0 if istate(j)=1, <0 if istate(j)=2 G (N, 0.), // on exit: objective gradient R (LDR*N, 0.), // on entry: need not be initialized if called with Cold Statrt // on exit: information about Hessian, if Hessian=Yes, R is upper Cholesky factor of approx H X (N, 0.), // on entry: initial point // on exit: final estimate of solution W (LENW, 0.), // workspace xmin (N, 0.), xmax (N, 0.); // now setup the lower and upper limits for the variables and constraints _feval->init_dvar(X, xmin, xmax); for (unsigned int i=0; i<N; i++) { BL[i] = xmin[i]; BU[i] = xmax[i]; } // all constraints are assumed to be g_i(x) <= 0, so that the upper // bound is 0 and lower bound is -infinity for (unsigned int i=0; i<NCNLN; i++) { BL[i+N] = -1.e20; BU[i+N] = 0.; } std::string nm; // nm = "List"; // npoptn_(nm.c_str(), (int)nm.length()); // nm = "Verify level 3"; // npoptn_(nm.c_str(), (int)nm.length()); npsol_(&N, &NCLIN, &NCNLN, &LDA, &LDJ, &LDR, &A[0], &BL[0], &BU[0], _funcon, _funobj, &INFORM, &ITER, &ISTATE[0], &C[0], &CJAC[0], &CLAMBDA[0], &F, &G[0], &R[0], &X[0], &IW[0], &LENIW, &W[0], &LENW); #endif // MAST_ENABLE_NPSOL 1 }
// HillClimb is always one on the original model. Therefore, if_bounded will be set as false temperoraly // so that all calculation can be perfomed on the original model. After HillClimb is finished, if_bounded // will be set as its original value. // Samples generated during HillClimb will be saved into storage but always at the level of number_energy_level // (the extra level) double CEquiEnergy_TState::HillClimb_NPSOL(size_t nSolution ) { energy_level = parameter->number_energy_level; bool if_bounded_old = if_bounded; if_bounded = false; // temperarily set if_bounded as false so all calculation is done on original model const string COLD_START = string("Cold Start"); const string NO_PRINT_OUT = string("Major print level = 0"); const string DERIVATIVE_LEVEL = string("Derivative level = 0"); // npsol MinusLogPosterior_NPSOL::model = this; int n = current_sample.data.dim; // sample dimension // linear constraints int nclin = 0; // number of linear constraints int ldA = nclin > 1 ? nclin : 1; // number of rows of A double *A = new double[ldA*n]; // nonlinear constraints int ncnln = 0; // number of nonlinear constraints int ldJ = ncnln > 1 ? ncnln : 1; // number of rows of cJac; double *cJac = new double[ldJ*n]; // R provides the upper-triangular Cholesky factor of the initial approximation // of the Hessian of the Lagrangian int ldR = n; // number of rows of R; double *R = new double[ldR*n]; // int nctotal = n + nclin + ncnln; int *istate = new int[nctotal]; // array indicating whether the constaits are effective double *bl = new double[nctotal]; // lower bounds for samples, A and cJac double *bu = new double[nctotal]; // upper bounds for samples, A and cJac for (int i=0; i<n; i++) { bl[i] = 0.0; bu[i] = 100.0; } double *clambda = new double [nctotal]; // lagragin parameters of the constraints for (int i=0; i<nctotal; i++) clambda[i] = 0; // work space int leniw = 3*n + nclin + 2*ncnln; int *iw = new int [leniw]; // integer work space int lenw; if (nclin == 0 && ncnln == 0) lenw = 20*n; else if (ncnln == 0) lenw = 2*n*n + 20*n + 11*nclin; else lenw = 2*n*n + n*nclin + 2*n*ncnln + 20*n + 11*nclin + 21*ncnln; double *w = new double[lenw]; // floating work space // initial estimate of the solution double *x = new double[n]; // returning value of npsol int inform, iter; double *c = new double[1]; // because ncnln = 0 double f; // value of objective f(x) at the final iterate double *g = new double[n]; // objective gradient double max_log_posterior = -1.0e300; npoptn_((char*)DERIVATIVE_LEVEL.c_str(), DERIVATIVE_LEVEL.length()); // npoptn_((char*)NO_PRINT_OUT.c_str(), NO_PRINT_OUT.length()); // test if LogPosterior_StatesIntegratedOut works for (int i=0; i<nSolution; i++) { InitializeParameter(x, n); npoptn_((char*)COLD_START.c_str(), COLD_START.length()); npsol_(&n, &nclin, &ncnln, &ldA, &ldJ, &ldR, A, bl, bu, NULL, MinusLogPosterior_NPSOL::function, &inform, &iter, istate, c, cJac, clambda, &f, g, R, x, iw, &leniw, w, &lenw); if (f < 1.0e300) { CSampleIDWeight sample; sample.data.Resize(n); for (int j=0; j<n; j++) sample.data[j] = x[j]; sample.DataChanged(); sample.id = (int)(time(NULL)-timer_when_started); log_posterior_function(sample); SaveSampleToStorage(sample); max_log_posterior = sample.weight > max_log_posterior ? sample.weight : max_log_posterior; } } delete [] g; delete [] c; delete [] w; delete [] iw; delete [] istate; delete [] clambda; delete [] bu; delete [] bl; delete [] R; delete [] cJac; delete [] A; storage->finalize(energy_level); storage->ClearDepositDrawHistory(energy_level); if_bounded = if_bounded_old; return max_log_posterior; }