static PyObject *add_int_option(PyObject * self, PyObject * args) { problem *temp = (problem *) self; IpoptProblem nlp = (IpoptProblem) (temp->nlp); char *param; int value; Bool ret; if (!PyArg_ParseTuple(args, "si:int_option", ¶m, &value)) { return NULL; } ret = AddIpoptIntOption(nlp, (char *)param, value); if (ret) { Py_INCREF(Py_True); return Py_True; } else { return PyErr_Format(PyExc_ValueError, "%s is not a valid int option", param); } }
fint F77_FUNC(ipaddintoption,IPADDINTOPTION) (fptr* FProblem, char* KEYWORD, fint* VALUE, int klen) { char* keyword; FUserData* fuser_data = (FUserData*) *FProblem; Int value = *VALUE; fint retval; keyword = f2cstr(KEYWORD, klen); retval = AddIpoptIntOption(fuser_data->Problem, keyword, value); free(keyword); if (retval) { return OKRetVal; } else { return NotOKRetVal; } }
/*! * 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); }
/*! \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); }