fptr F77_FUNC(ipcreate,IPCREATE) (fint* N, fdouble* X_L, fdouble* X_U, fint* M, fdouble* G_L, fdouble* G_U, fint* NELE_JAC, fint* NELE_HESS, fint* IDX_STY, FEval_F_CB EVAL_F, FEval_G_CB EVAL_G, FEval_Grad_F_CB EVAL_GRAD_F, FEval_Jac_G_CB EVAL_JAC_G, FEval_Hess_CB EVAL_HESS) { Index n = *N; Index m = *M; Index nele_jac = *NELE_JAC; Index nele_hess = *NELE_HESS; Index index_style = *IDX_STY; FUserData* fuser_data; fuser_data = (FUserData*) malloc(sizeof(FUserData)); /* First create a new IpoptProblem object; if that fails return 0 */ fuser_data->Problem = CreateIpoptProblem(n, X_L, X_U, m, G_L, G_U, nele_jac, nele_hess, index_style, eval_f, eval_g, eval_grad_f, eval_jac_g, eval_h); if (fuser_data->Problem == NULL) { free(fuser_data); return (fptr)NULL; } /* Store the information for the callback function */ fuser_data->EVAL_F = EVAL_F; fuser_data->EVAL_G = EVAL_G; fuser_data->EVAL_GRAD_F = EVAL_GRAD_F; fuser_data->EVAL_JAC_G = EVAL_JAC_G; fuser_data->EVAL_HESS = EVAL_HESS; fuser_data->INTERMEDIATE_CB = NULL; return (fptr)fuser_data; }
/*! * run optimization with ipopt * author: Vitalij Ruge **/ static inline void optimizationWithIpopt(OptData*optData) { IpoptProblem nlp = NULL; const int NV = optData->dim.NV; const int NRes = optData->dim.NRes; const int nsi = optData->dim.nsi; const int np = optData->dim.np; const int nx = optData->dim.nx; const int NJ = optData->dim.nJderx; const int NJf = optData->dim.nJfderx; const int nH0 = optData->dim.nH0_; const int nH1 = optData->dim.nH1_; const int njac = np*(NJ*nsi + nx*(np*nsi - 1)) + NJf; const int nhess = (nsi*np-1)*nH0+nH1; Number * Vmin = optData->bounds.Vmin; Number * Vmax = optData->bounds.Vmax; Number * gmin = optData->ipop.gmin; Number * gmax = optData->ipop.gmax; Number * vopt = optData->ipop.vopt; Number * mult_g = optData->ipop.mult_g; Number * mult_x_L = optData->ipop.mult_x_L; Number * mult_x_U = optData->ipop.mult_x_U; Number obj; char *cflags; int max_iter = 5000; int res = 0; nlp = CreateIpoptProblem(NV, Vmin, Vmax, NRes, gmin, gmax, njac, nhess, 0, &evalfF, &evalfG, &evalfDiffF, &evalfDiffG, &ipopt_h); /********************************************************************/ /******************* ipopt flags ************************/ /********************************************************************/ /*tol */ AddIpoptNumOption(nlp, "tol", optData->data->simulationInfo.tolerance); AddIpoptStrOption(nlp, "evaluate_orig_obj_at_resto_trial", "yes"); /* print level */ if(ACTIVE_STREAM(LOG_IPOPT_FULL)) { AddIpoptIntOption(nlp, "print_level", 7); } else if(ACTIVE_STREAM(LOG_IPOPT)) { AddIpoptIntOption(nlp, "print_level", 5); } else if(ACTIVE_STREAM(LOG_STATS)) { AddIpoptIntOption(nlp, "print_level", 3); } else { AddIpoptIntOption(nlp, "print_level", 2); } AddIpoptIntOption(nlp, "file_print_level", 0); /* derivative_test */ if(ACTIVE_STREAM(LOG_IPOPT_JAC) && ACTIVE_STREAM(LOG_IPOPT_HESSE)) { AddIpoptIntOption(nlp, "print_level", 4); AddIpoptStrOption(nlp, "derivative_test", "second-order"); } else if(ACTIVE_STREAM(LOG_IPOPT_JAC)) { AddIpoptIntOption(nlp, "print_level", 4); AddIpoptStrOption(nlp, "derivative_test", "first-order"); } else if(ACTIVE_STREAM(LOG_IPOPT_HESSE)) { AddIpoptIntOption(nlp, "print_level", 4); AddIpoptStrOption(nlp, "derivative_test", "only-second-order"); } else { AddIpoptStrOption(nlp, "derivative_test", "none"); } cflags = (char*)omc_flagValue[FLAG_IPOPT_HESSE]; if(cflags) { if(!strcmp(cflags,"BFGS")) AddIpoptStrOption(nlp, "hessian_approximation", "limited-memory"); else if(!strcmp(cflags,"const") || !strcmp(cflags,"CONST")) AddIpoptStrOption(nlp, "hessian_constant", "yes"); else if(!(!strcmp(cflags,"num") || !strcmp(cflags,"NUM"))) warningStreamPrint(LOG_STDOUT, 0, "not support ipopt_hesse=%s",cflags); } /*linear_solver e.g. mumps, MA27, MA57,... * be sure HSL solver are installed if your try HSL solver*/ cflags = (char*)omc_flagValue[FLAG_LS_IPOPT]; if(cflags) AddIpoptStrOption(nlp, "linear_solver", cflags); AddIpoptNumOption(nlp,"mumps_pivtolmax",1e-5); /* max iter */ cflags = (char*)omc_flagValue[FLAG_IPOPT_MAX_ITER]; if(cflags) { char buffer[100]; char c; int index_e = -1, i = 0; strcpy(buffer,cflags); while(buffer[i] != '\0') { if(buffer[i] == 'e') { index_e = i; break; } ++i; } if(index_e < 0) { max_iter = atoi(cflags); if(max_iter >= 0) AddIpoptIntOption(nlp, "max_iter", max_iter); printf("\nmax_iter = %i",atoi(cflags)); } else { max_iter = (atoi(cflags)*pow(10.0, (double)atoi(cflags+index_e+1))); if(max_iter >= 0) AddIpoptIntOption(nlp, "max_iter", (int)max_iter); printf("\nmax_iter = (int) %i | (double) %g",(int)max_iter, atoi(cflags)*pow(10.0, (double)atoi(cflags+index_e+1))); } } else AddIpoptIntOption(nlp, "max_iter", 5000); /*heuristic optition */ { int ws = 0; cflags = (char*)omc_flagValue[FLAG_IPOPT_WARM_START]; if(cflags) { ws = atoi(cflags); } if(ws > 0) { double shift = pow(10,-1.0*ws); AddIpoptNumOption(nlp,"mu_init",shift); AddIpoptNumOption(nlp,"bound_mult_init_val",shift); AddIpoptStrOption(nlp,"mu_strategy", "monotone"); AddIpoptNumOption(nlp,"bound_push", 1e-5); AddIpoptNumOption(nlp,"bound_frac", 1e-5); AddIpoptNumOption(nlp,"slack_bound_push", 1e-5); AddIpoptNumOption(nlp,"constr_mult_init_max", 1e-5); AddIpoptStrOption(nlp,"bound_mult_init_method","mu-based"); } else { AddIpoptStrOption(nlp,"mu_strategy","adaptive"); AddIpoptStrOption(nlp,"bound_mult_init_method","constant"); } AddIpoptStrOption(nlp,"fixed_variable_treatment","make_parameter"); AddIpoptStrOption(nlp,"dependency_detection_with_rhs","yes"); AddIpoptNumOption(nlp,"nu_init",1e-9); AddIpoptNumOption(nlp,"eta_phi",1e-10); } /********************************************************************/ if(max_iter >=0) { optData->iter_ = 0.0; optData->index = 1; res = IpoptSolve(nlp, vopt, NULL, &obj, mult_g, mult_x_L, mult_x_U, (void*)optData); } if(res != 0 && !ACTIVE_STREAM(LOG_IPOPT)) warningStreamPrint(LOG_STDOUT, 0, "No optimal solution found!\nUse -lv=LOG_IPOPT for more information."); FreeIpoptProblem(nlp); }
static PyObject *create(PyObject * obj, PyObject * args) { PyObject *f = NULL; PyObject *gradf = NULL; PyObject *g = NULL; PyObject *jacg = NULL; PyObject *h = NULL; PyObject *applynew = NULL; DispatchData myowndata; /* * I have to create a new python object here, return this python * object */ int n; /* Number of var */ PyArrayObject *xL = NULL; PyArrayObject *xU = NULL; int m; /* Number of con */ PyArrayObject *gL = NULL; PyArrayObject *gU = NULL; problem *object = NULL; int nele_jac; int nele_hess; Number *x_L = NULL; /* lower bounds on x */ Number *x_U = NULL; /* upper bounds on x */ Number *g_L = NULL; /* lower bounds on g */ Number *g_U = NULL; /* upper bounds on g */ double *xldata, *xudata; double *gldata, *gudata; int i; DispatchData *dp = NULL; PyObject *retval = NULL; /* Init the myowndata field */ myowndata.eval_f_python = NULL; myowndata.eval_grad_f_python = NULL; myowndata.eval_g_python = NULL; myowndata.eval_jac_g_python = NULL; myowndata.eval_h_python = NULL; myowndata.apply_new_python = NULL; myowndata.userdata = NULL; /* "O!", &PyArray_Type &a_x */ if (!PyArg_ParseTuple(args, "iO!O!iO!O!iiOOOO|OO:pyipoptcreate", &n, &PyArray_Type, &xL, &PyArray_Type, &xU, &m, &PyArray_Type, &gL, &PyArray_Type, &gU, &nele_jac, &nele_hess, &f, &gradf, &g, &jacg, &h, &applynew)) { retval = NULL; SAFE_FREE(x_L); SAFE_FREE(x_U); SAFE_FREE(g_L); SAFE_FREE(g_U); return retval; } if (!PyCallable_Check(f) || !PyCallable_Check(gradf) || !PyCallable_Check(g) || !PyCallable_Check(jacg)) { PyErr_SetString(PyExc_TypeError, "Need a callable object for callback functions"); retval = NULL; SAFE_FREE(x_L); SAFE_FREE(x_U); SAFE_FREE(g_L); SAFE_FREE(g_U); return retval; } myowndata.eval_f_python = f; myowndata.eval_grad_f_python = gradf; myowndata.eval_g_python = g; myowndata.eval_jac_g_python = jacg; if (h != NULL) { if (PyCallable_Check(h)) { myowndata.eval_h_python = h; } else { PyErr_SetString(PyExc_TypeError, "Need a callable object for function h."); retval = NULL; SAFE_FREE(x_L); SAFE_FREE(x_U); SAFE_FREE(g_L); SAFE_FREE(g_U); return retval; } } else { logger("[PyIPOPT] Ipopt will use Hessian approximation.\n"); } if (applynew != NULL) { if (PyCallable_Check(applynew)) { myowndata.apply_new_python = applynew; } else { PyErr_SetString(PyExc_TypeError, "Need a callable object for function applynew."); retval = NULL; SAFE_FREE(x_L); SAFE_FREE(x_U); SAFE_FREE(g_L); SAFE_FREE(g_U); return retval; } } if (m < 0 || n < 0) { PyErr_SetString(PyExc_TypeError, "m or n can't be negative"); retval = NULL; SAFE_FREE(x_L); SAFE_FREE(x_U); SAFE_FREE(g_L); SAFE_FREE(g_U); return retval; } x_L = (Number *) malloc(sizeof(Number) * n); x_U = (Number *) malloc(sizeof(Number) * n); if (!x_L || !x_U) { retval = PyErr_NoMemory(); SAFE_FREE(x_L); SAFE_FREE(x_U); SAFE_FREE(g_L); SAFE_FREE(g_U); return retval; } xldata = (double *)xL->data; xudata = (double *)xU->data; for (i = 0; i < n; i++) { x_L[i] = xldata[i]; x_U[i] = xudata[i]; } g_L = (Number *) malloc(sizeof(Number) * m); g_U = (Number *) malloc(sizeof(Number) * m); if (!g_L || !g_U) PyErr_NoMemory(); gldata = (double *)gL->data; gudata = (double *)gU->data; for (i = 0; i < m; i++) { g_L[i] = gldata[i]; g_U[i] = gudata[i]; } /* create the Ipopt Problem */ int C_indexstyle = 0; IpoptProblem thisnlp = CreateIpoptProblem(n, x_L, x_U, m, g_L, g_U, nele_jac, nele_hess, C_indexstyle, &eval_f, &eval_g, &eval_grad_f, &eval_jac_g, &eval_h); logger("[PyIPOPT] Problem created"); if (!thisnlp) { PyErr_SetString(PyExc_MemoryError, "Cannot create IpoptProblem instance"); retval = NULL; SAFE_FREE(x_L); SAFE_FREE(x_U); SAFE_FREE(g_L); SAFE_FREE(g_U); return retval; } object = PyObject_NEW(problem, &IpoptProblemType); if (object != NULL) { object->n_variables = n; object->m_constraints = m; object->nlp = thisnlp; dp = (DispatchData *) malloc(sizeof(DispatchData)); if (!dp) { retval = PyErr_NoMemory(); SAFE_FREE(x_L); SAFE_FREE(x_U); SAFE_FREE(g_L); SAFE_FREE(g_U); return retval; } memcpy((void *)dp, (void *)&myowndata, sizeof(DispatchData)); object->data = dp; retval = (PyObject *) object; SAFE_FREE(x_L); SAFE_FREE(x_U); SAFE_FREE(g_L); SAFE_FREE(g_U); return retval; } else { PyErr_SetString(PyExc_MemoryError, "Can't create a new Problem instance"); retval = NULL; SAFE_FREE(x_L); SAFE_FREE(x_U); SAFE_FREE(g_L); SAFE_FREE(g_U); return retval; } }
/* Main Program */ int main() { Index n=-1; /* number of variables */ Index m=-1; /* number of constraints */ Number* x_L = NULL; /* lower bounds on x */ Number* x_U = NULL; /* upper bounds on x */ Number* g_L = NULL; /* lower bounds on g */ Number* g_U = NULL; /* upper bounds on g */ IpoptProblem nlp = NULL; /* IpoptProblem */ enum ApplicationReturnStatus status; /* Solve return code */ Number* x = NULL; /* starting point and solution vector */ Number* mult_x_L = NULL; /* lower bound multipliers at the solution */ Number* mult_x_U = NULL; /* upper bound multipliers at the solution */ Number obj; /* objective value */ Index i; /* generic counter */ /* Number of nonzeros in the Jacobian of the constraints */ Index nele_jac = 8; /* Number of nonzeros in the Hessian of the Lagrangian (lower or upper triangual part only) */ Index nele_hess = 10; /* indexing style for matrices */ Index index_style = 0; /* C-style; start counting of rows and column indices at 0 */ /* set the number of variables and allocate space for the bounds */ n=4; x_L = (Number*)malloc(sizeof(Number)*n); x_U = (Number*)malloc(sizeof(Number)*n); /* set the values for the variable bounds */ for (i=0; i<n; i++) { x_L[i] = 1.0; x_U[i] = 5.0; } /* set the number of constraints and allocate space for the bounds */ m=2; g_L = (Number*)malloc(sizeof(Number)*m); g_U = (Number*)malloc(sizeof(Number)*m); /* set the values of the constraint bounds */ g_L[0] = 25; g_U[0] = 2e19; g_L[1] = 40; g_U[1] = 40; /* create the IpoptProblem */ nlp = CreateIpoptProblem(n, x_L, x_U, m, g_L, g_U, nele_jac, nele_hess, index_style, &eval_f, &eval_g, &eval_grad_f, &eval_jac_g, &eval_h); /* We can free the memory now - the values for the bounds have been copied internally in CreateIpoptProblem */ free(x_L); free(x_U); free(g_L); free(g_U); /* Set some options. Note the following ones are only examples, they might not be suitable for your problem. */ AddIpoptNumOption(nlp, "tol", 1e-7); AddIpoptStrOption(nlp, "mu_strategy", "adaptive"); AddIpoptStrOption(nlp, "output_file", "ipopt.out"); /* allocate space for the initial point and set the values */ x = (Number*)malloc(sizeof(Number)*n); x[0] = 1.0; x[1] = 5.0; x[2] = 5.0; x[3] = 1.0; /* allocate space to store the bound multipliers at the solution */ mult_x_L = (Number*)malloc(sizeof(Number)*n); mult_x_U = (Number*)malloc(sizeof(Number)*n); /* solve the problem */ status = IpoptSolve(nlp, x, NULL, &obj, NULL, mult_x_L, mult_x_U, NULL); if (status == Solve_Succeeded) { printf("\n\nSolution of the primal variables, x\n"); for (i=0; i<n; i++) { printf("x[%d] = %e\n", i, x[i]); } printf("\n\nSolution of the bound multipliers, z_L and z_U\n"); for (i=0; i<n; i++) { printf("z_L[%d] = %e\n", i, mult_x_L[i]); } for (i=0; i<n; i++) { printf("z_U[%d] = %e\n", i, mult_x_U[i]); } printf("\n\nObjective value\n"); printf("f(x*) = %e\n", obj); } /* free allocated memory */ FreeIpoptProblem(nlp); free(x); free(mult_x_L); free(mult_x_U); return 0; }
/* Main Program */ int main() { Index n=-1; /* number of variables */ Index m=-1; /* number of constraints */ Index nele_jac; /* number of nonzeros in Jacobian */ Index nele_hess; /* number of nonzeros in Hessian */ Index index_style; /* indexing style for matrices */ Number* x_L = NULL; /* lower bounds on x */ Number* x_U = NULL; /* upper bounds on x */ Number* g_L = NULL; /* lower bounds on g */ Number* g_U = NULL; /* upper bounds on g */ IpoptProblem nlp = NULL; /* IpoptProblem */ enum ApplicationReturnStatus status; /* Solve return code */ Number* x = NULL; /* starting point and solution vector */ Number* mult_x_L = NULL; /* lower bound multipliers at the solution */ Number* mult_x_U = NULL; /* upper bound multipliers at the solution */ Number obj; /* objective value */ Index i; /* generic counter */ int size; /* Size of the problem */ ProblemData PD; /* Pointer to structure with problem data */ /* Specify size of the problem */ size = 100; /* Set the problem data */ PD = (ProblemData)malloc(sizeof(struct _ProblemData)); PD->N = size; PD->a = malloc(sizeof(double)*(size-2)); for (i=0; i<size-2; i++) { PD->a[i] = ((double)(i+2))/(double)size; } /* set the number of variables and allocate space for the bounds */ n=size; x_L = (Number*)malloc(sizeof(Number)*n); x_U = (Number*)malloc(sizeof(Number)*n); /* set the values for the variable bounds */ for (i=0; i<n; i++) { x_L[i] = -1.5; x_U[i] = 0.; } /* set the number of constraints and allocate space for the bounds */ m=size-2; g_L = (Number*)malloc(sizeof(Number)*m); g_U = (Number*)malloc(sizeof(Number)*m); /* set the values of the constraint bounds */ for (i=0; i<m; i++) { g_L[i] = 0.; g_U[i] = 0.; } /* Number of nonzeros in the Jacobian of the constraints each constraint has three nonzeros */ nele_jac = 3*m; /* Number of nonzeros in the Hessian of the Lagrangian (lower or upper triangual part only) We have the full diagonal, and the first off-diagonal except for the first and last variable */ nele_hess = n + (n-2); /* indexing style for matrices */ index_style = 0; /* C-style; start counting of rows and column indices at 0 */ /* create the IpoptProblem */ nlp = CreateIpoptProblem(n, x_L, x_U, m, g_L, g_U, nele_jac, nele_hess, index_style, &eval_f, &eval_g, &eval_grad_f, &eval_jac_g, &eval_h); /* We can free the memory now - the values for the bounds have been copied internally in CreateIpoptProblem */ free(x_L); free(x_U); free(g_L); free(g_U); /* Set some options. Note the following ones are only examples, they might not be suitable for your problem. */ AddIpoptNumOption(nlp, "tol", 1e-7); AddIpoptStrOption(nlp, "mu_strategy", "adaptive"); AddIpoptStrOption(nlp, "output_file", "ipopt.out"); /* allocate space for the initial point and set the values */ x = (Number*)malloc(sizeof(Number)*n); for (i=0; i<n; i++) { x[i] = -0.5; } #ifdef skip_me /* If checking derivatives, if is useful to choose different values */ for (i=0; i<n; i++) { x[i] = -0.5+0.1*i/n; } #endif /* allocate space to store the bound multipliers at the solution */ mult_x_L = (Number*)malloc(sizeof(Number)*n); mult_x_U = (Number*)malloc(sizeof(Number)*n); /* solve the problem */ status = IpoptSolve(nlp, x, NULL, &obj, NULL, mult_x_L, mult_x_U, (void*)PD); if (status == Solve_Succeeded) { printf("\n\nSolution of the primal variables, x\n"); for (i=0; i<n; i++) { printf("x[%d] = %e\n", i, x[i]); } printf("\n\nSolution of the bound multipliers, z_L and z_U\n"); for (i=0; i<n; i++) { printf("z_L[%d] = %e\n", i, mult_x_L[i]); } for (i=0; i<n; i++) { printf("z_U[%d] = %e\n", i, mult_x_U[i]); } printf("\n\nObjective value\n"); printf("f(x*) = %e\n", obj); } /* free allocated memory */ FreeIpoptProblem(nlp); free(x); free(mult_x_L); free(mult_x_U); /* also for our user data */ free(PD->a); free(PD); return 0; }
/*! \fn ipopt_initialization * * This function is used if ipopt is choosen for initialization. * * \param [ref] [data] * \param [ref] [initData] * \param [in] [useScaling] * * \author lochel */ int ipopt_initialization(DATA *data, INIT_DATA *initData, int useScaling) { int n = initData->nz; /* number of variables */ int m = (initData->nInitResiduals > initData->nz) ? 0 : initData->nInitResiduals; /* number of constraints */ double* x_L = NULL; /* lower bounds on x */ double* x_U = NULL; /* upper bounds on x */ double* g_L = NULL; /* lower bounds on g */ double* g_U = NULL; /* upper bounds on g */ double* x = NULL; /* starting point and solution vector */ double* mult_g = NULL; /* constraint multipliers at the solution */ double* mult_x_L = NULL; /* lower bound multipliers at the solution */ double* mult_x_U = NULL; /* upper bound multipliers at the solution */ double obj; /* objective value */ int i; /* generic counter */ int nele_jac = n*m; /* number of nonzeros in the Jacobian of the constraints */ int nele_hess = 0; /* number of nonzeros in the Hessian of the Lagrangian (lower or upper triangual part only) */ IpoptProblem nlp = NULL; /* ipopt-problem */ enum ApplicationReturnStatus status; /* solve return code */ IPOPT_DATA ipopt_data; ipopt_data.data = data; ipopt_data.initData = initData; ipopt_data.useScaling = useScaling; ipopt_data.useSymbolic = (initialAnalyticJacobianG(data) == 0 ? 1 : 0); if(ipopt_data.useSymbolic == 1) { nele_jac = data->simulationInfo.analyticJacobians[INDEX_JAC_G].sparsePattern.leadindex[n-1]; // sparse DEBUG_INFO1(LOG_INIT, "number of zeros in the Jacobian of the constraints (jac_g): %d", n*m-nele_jac); DEBUG_INFO1(LOG_INIT, "number of nonzeros in the Jacobian of the constraints (jac_g): %d", nele_jac); } /* allocate space for the variable bounds */ x_L = (double*)malloc(n * sizeof(double)); x_U = (double*)malloc(n * sizeof(double)); /* allocate space for the constraint bounds */ g_L = (double*)malloc(m * sizeof(double)); g_U = (double*)malloc(m * sizeof(double)); /* allocate space for the initial point */ x = (double*)malloc(n * sizeof(double)); /* set values of optimization variable bounds */ for(i=0; i<n; ++i) { x[i] = initData->start[i]; x_L[i] = initData->min[i]; x_U[i] = initData->max[i]; } /* set values of constraint bounds */ for(i=0; i<m; ++i) { g_L[i] = 0.0; g_U[i] = 0.0; } /* create the IpoptProblem */ nlp = CreateIpoptProblem( n, /* Number of optimization variables */ x_L, /* Lower bounds on variables */ x_U, /* Upper bounds on variables */ m, /* Number of constraints */ g_L, /* Lower bounds on constraints */ g_U, /* Upper bounds on constraints */ nele_jac, /* Number of non-zero elements in constraint Jacobian */ nele_hess, /* Number of non-zero elements in Hessian of Lagrangian */ 0, /* indexing style for iRow & jCol; 0 for C style, 1 for Fortran style */ &ipopt_f, /* Callback function for evaluating objective function */ &ipopt_g, /* Callback function for evaluating constraint functions */ &ipopt_grad_f, /* Callback function for evaluating gradient of objective function */ &ipopt_jac_g, /* Callback function for evaluating Jacobian of constraint functions */ &ipopt_h); /* Callback function for evaluating Hessian of Lagrangian function */ ASSERT(nlp, "creating of ipopt problem has failed"); /* We can free the memory now - the values for the bounds have been copied internally in CreateIpoptProblem */ free(x_L); free(x_U); free(g_L); free(g_U); /* Set some options. Note the following ones are only examples, they might not be suitable for your problem. */ AddIpoptNumOption(nlp, "tol", 1e-7); AddIpoptIntOption(nlp, "print_level", DEBUG_FLAG(LOG_INIT) ? 5 : 0); AddIpoptIntOption(nlp, "max_iter", 5000); AddIpoptStrOption(nlp, "mu_strategy", "adaptive"); AddIpoptStrOption(nlp, "hessian_approximation", "limited-memory"); /* allocate space to store the bound multipliers at the solution */ mult_g = (double*)malloc(m*sizeof(double)); mult_x_L = (double*)malloc(n*sizeof(double)); mult_x_U = (double*)malloc(n*sizeof(double)); /* solve the problem */ status = IpoptSolve( nlp, /* Problem that is to be optimized */ x, /* Input: Starting point; Output: Optimal solution */ NULL, /* Values of constraint at final point */ &obj, /* Final value of objective function */ mult_g, /* Final multipliers for constraints */ mult_x_L, /* Final multipliers for lower variable bounds */ mult_x_U, /* Final multipliers for upper variable bounds */ &ipopt_data); /* Pointer to user data */ setZ(initData, x); /* free allocated memory */ FreeIpoptProblem(nlp); free(x); free(mult_g); free(mult_x_L); free(mult_x_U); /* debug output */ DEBUG_INFO1(LOG_INIT, "ending with funcValue = %g", obj); DEBUG_INFO_AL(LOG_INIT, "| unfixed variables"); for(i=0; i<initData->nz; i++) DEBUG_INFO_AL4(LOG_INIT, "| | [%ld] %s = %g [scaled: %g]", i+1, initData->name[i], initData->z[i], initData->zScaled[i]); DEBUG_INFO_AL(LOG_INIT, "| residuals (> 0.001)"); for(i=0; i<data->modelData.nInitResiduals; i++) if(fabs(initData->initialResiduals[i]) > 1e-3) DEBUG_INFO_AL3(LOG_INIT, "| | [%ld] %g [scaled: %g]", i+1, initData->initialResiduals[i], (initData->residualScalingCoefficients[i] != 0.0) ? initData->initialResiduals[i]/initData->residualScalingCoefficients[i] : 0.0); if(status != Solve_Succeeded && status != Solved_To_Acceptable_Level) THROW("ipopt failed. see last warning. use [-lv LOG_INIT] for more output."); return (int)status; }
/*! * start main optimization step * author: Vitalij Ruge **/ int startIpopt(DATA* data, SOLVER_INFO* solverInfo, int flag) { int i; int j,k,l; double obj; int res; char *cflags; IpoptProblem nlp = NULL; IPOPT_DATA_ *iData = ((IPOPT_DATA_*)solverInfo->solverData); iData->current_var = 0; iData->current_time = 0; iData->data = data; iData->mayer = mayer(data, &obj); iData->lagrange = lagrange(data, &obj); iData->numObject = 2 - iData->mayer -iData->lagrange; iData->matrixA = initialAnalyticJacobianA((void*) iData->data); iData->matrixB = initialAnalyticJacobianB((void*) iData->data); /* iData->matrixC = initialAnalyticJacobianC((void*) iData->data); iData->matrixD = initialAnalyticJacobianD((void*) iData->data); */ loadDAEmodel(data, iData); iData->index_debug_iter=0; iData->degub_step = 10; iData->index_debug_next=0; cflags = omc_flagValue[FLAG_LS_IPOPT]; if(!cflags) cflags = "mumps"; /*ToDo*/ for(i=0; i<(*iData).nx; i++) { iData->Vmin[i] = (*iData).Vmax[i] = (*iData).x0[i]*iData->scalVar[i]; iData->v[i] = iData->Vmin[i]; if(ACTIVE_STREAM(LOG_IPOPT)) { printf("\nx[%i] = %s = %g",i, iData->data->modelData.realVarsData[i].info.name,iData->v[i]); } } initial_guess_ipopt(iData,solverInfo); if(ACTIVE_STREAM(LOG_IPOPT)) { for(; i<iData->nv; ++i) printf("\nu[%i] = %s = %g",i, iData->data->modelData.realVarsData[iData->index_u + i-iData->nx].info.name,iData->v[i]); } ipoptDebuge(iData,iData->v); if(flag == 5) { nlp = CreateIpoptProblem((*iData).NV, (*iData).Vmin, (*iData).Vmax, (*iData).NRes, (*iData).gmin, (*iData).gmax, (*iData).njac, NULL, 0, &evalfF, &evalfG, &evalfDiffF, &evalfDiffG, &ipopt_h); AddIpoptNumOption(nlp, "tol", iData->data->simulationInfo.tolerance); if(ACTIVE_STREAM(LOG_IPOPT)) { AddIpoptIntOption(nlp, "print_level", 5); AddIpoptIntOption(nlp, "file_print_level", 0); } else if(ACTIVE_STREAM(LOG_STATS)) { AddIpoptIntOption(nlp, "print_level", 3); AddIpoptIntOption(nlp, "file_print_level", 0); } else { AddIpoptIntOption(nlp, "print_level", 2); AddIpoptIntOption(nlp, "file_print_level", 0); } AddIpoptStrOption(nlp, "mu_strategy", "adaptive"); AddIpoptStrOption(nlp, "hessian_approximation", "limited-memory"); if(cflags) AddIpoptStrOption(nlp, "linear_solver", cflags); else AddIpoptStrOption(nlp, "linear_solver", "mumps"); /* AddIpoptStrOption(nlp, "derivative_test", "second-order"); */ /* AddIpoptStrOption(nlp, "derivative_test_print_all", "yes"); */ /* AddIpoptNumOption(nlp,"derivative_test_perturbation",1e-6); */ AddIpoptIntOption(nlp, "max_iter", 5000); res = IpoptSolve(nlp, (*iData).v, NULL, &obj, (*iData).mult_g, (*iData).mult_x_L, (*iData).mult_x_U, (void*)iData); FreeIpoptProblem(nlp); if(ACTIVE_STREAM(LOG_IPOPT)) { for(i =0; i<iData->nv;i++) if(iData->pFile[i]) fclose(iData->pFile[i]); if(iData->pFile) free(iData->pFile); } iData->current_var = 0; res2file(iData,solverInfo); } return 0; }
SimTK::Real InteriorPointOptimizer::optimize( Vector &results ) { int n = getOptimizerSystem().getNumParameters(); int m = getOptimizerSystem().getNumConstraints(); Index index_style = 0; /* C-style; start counting of rows and column indices at 0 */ Index nele_hess = 0; Index nele_jac = n*m; /* always assume dense */ // Parameter limits Number *x_L = NULL, *x_U = NULL; if( getOptimizerSystem().getHasLimits() ) { getOptimizerSystem().getParameterLimits( &x_L, &x_U); } else { x_U = new Number[n]; x_L = new Number[n]; for(int i=0;i<n;i++) { x_U[i] = SimTK::Real(POSITIVE_INF); x_L[i] = SimTK::Real(NEGATIVE_INF); } } SimTK::Real *x = &results[0]; IpoptProblem nlp = CreateIpoptProblem(n, x_L, x_U, m, g_L, g_U, nele_jac, nele_hess, index_style, objectiveFuncWrapper, constraintFuncWrapper, gradientFuncWrapper, constraintJacobianWrapper, hessianWrapper); // If you want to verify which options are getting set in the optimizer, you can create a file ipopt.opt // with "print_user_options yes", and set print_level to (at least 1). It will then print the options to the screen. // sherm 100302: you have to set all of these tolerances to get IpOpt to change // its convergence criteria; see OptimalityErrorConvergenceCheck::CheckConvergence(). // We'll set acceptable tolerances to the same value to disable them. AddIpoptNumOption(nlp, "tol", convergenceTolerance); AddIpoptNumOption(nlp, "dual_inf_tol", convergenceTolerance); AddIpoptNumOption(nlp, "constr_viol_tol", constraintTolerance); AddIpoptNumOption(nlp, "compl_inf_tol", convergenceTolerance); AddIpoptNumOption(nlp, "acceptable_tol", convergenceTolerance); AddIpoptNumOption(nlp, "acceptable_dual_inf_tol", convergenceTolerance); AddIpoptNumOption(nlp, "acceptable_constr_viol_tol", constraintTolerance); AddIpoptNumOption(nlp, "acceptable_compl_inf_tol", convergenceTolerance); AddIpoptIntOption(nlp, "max_iter", maxIterations); AddIpoptStrOption(nlp, "mu_strategy", "adaptive"); AddIpoptStrOption(nlp, "hessian_approximation", "limited-memory"); // needs to be limited-memory unless you have explicit hessians AddIpoptIntOption(nlp, "limited_memory_max_history", limitedMemoryHistory); AddIpoptIntOption(nlp, "print_level", diagnosticsLevel); // default is 4 int i; static const char *advancedRealOptions[] = { "compl_inf_tol", "dual_inf_tol", "constr_viol_tol", "acceptable_tol", "acceptable_compl_inf_tol", "acceptable_constr_viol_tol", "acceptable_dual_inf_tol", "diverging_iterates_tol", "barrier_tol_factor", "obj_scaling_factor", "nlp_scaling_max_gradient", "bounds_relax_factor", "recalc_y_feas_tol", "mu_init", "mu_max_fact", "mu_max", "mu_min", "mu_linear_decrease_factor", "mu_superlinear_decrease_factor", "bound_frac", "bound_push", "bound_mult_init_val", "constr_mult_init_max", "constr_mult_init_val", "warm_start_bound_push", "warm_start_bound_frac", "warm_start_mult_bound_push", "warm_start_mult_init_max", "recalc_y_feas_tol", "expect_infeasible_problem_ctol", "soft_resto_pderror_reduction_factor", "required_infeasibility_reduction", "bound_mult_reset_threshold", "constr_mult_reset_threshold", "max_hessian_perturbation", "min_hessian_perturbation", "first_hessian_perturbation", "perturb_inc_fact_first", "perturb_inc_fact", "perturb_dec_fact", "jacobian_reqularization_value", "derivative_test_perturbation", "derivative_test_tol", 0}; Real value; for(i=0;advancedRealOptions[i];i++) { if(getAdvancedRealOption(advancedRealOptions[i],value)) AddIpoptNumOption(nlp, advancedRealOptions[i], value); } static const std::string advancedStrOptions[] = {"nlp_scaling_method", "honor_original_bounds", "check_derivatives_for_naninf", "mu_strategy", "mu_oracle", "fixed_mu_oracle", "alpha_for_y", "recalc_y", "expect_infeasible_problem", "print_options_documentation", "print_user_options", "start_with_resto", "evaluate_orig_obj_at_resto_trial", "hessian_approximation", "derivative_test", ""}; std::string svalue; for(i=0;!advancedStrOptions[i].empty();i++) { if(getAdvancedStrOption(advancedStrOptions[i], svalue)) AddIpoptStrOption(nlp, advancedStrOptions[i].c_str(), svalue.c_str()); } static const char* advancedIntOptions[] = {"quality_function_max_section_steps", "max_soc", "watchdog_shorted_iter_trigger", "watchdog_trial_iter_max", "max_refinement_steps", "min_refinement_steps", "limited_memory_max_history", "limited_memory_max_skipping", "derivative_test_print_all", 0}; int ivalue; for(i=0;advancedIntOptions[i];i++) { if(getAdvancedIntOption(advancedIntOptions[i], ivalue)) AddIpoptIntOption(nlp, advancedIntOptions[i], ivalue); } // Only makes sense to do a warm start if this is not the first call to optimize() (since we need // reasonable starting multiplier values) bool use_warm_start=false; if(getAdvancedBoolOption("warm_start", use_warm_start) && use_warm_start && !firstOptimization) { AddIpoptStrOption(nlp, "warm_start_init_point", "yes"); AddIpoptStrOption(nlp, "warm_start_entire_iterate", "yes"); //AddIpoptStrOption(nlp, "warm_start_same_structure", "yes"); // couldn't get this one to work } SimTK::Real obj; int status = IpoptSolve(nlp, x, NULL, &obj, mult_g, mult_x_L, mult_x_U, (void *)this ); FreeIpoptProblem(nlp); // Only delete these if they aren't pointing to existing parameter limits if( !getOptimizerSystem().getHasLimits() ) { delete [] x_U; delete [] x_L; } if(status == Solved_To_Acceptable_Level) { std::cout << "Ipopt: Solved to acceptable level" << std::endl; } else if (status != Solve_Succeeded) { if( status != NonIpopt_Exception_Thrown) { char buf[1024]; sprintf(buf, "Ipopt: %s (status %d)",applicationReturnStatusToString(status).c_str(),status); SimTK_THROW1(SimTK::Exception::OptimizerFailed, SimTK::String(buf)); } } firstOptimization = false; return(obj); }