00001
00019 #define DEBUG
00020
00021 #include "OSIpoptSolver.h"
00022 #include "OSDataStructures.h"
00023 #include "OSParameters.h"
00024 #include "OSCommonUtil.h"
00025 #include "OSMathUtil.h"
00026
00027
00028 using std::cout;
00029 using std::endl;
00030 using std::ostringstream;
00031 using namespace Ipopt;
00032
00033
00034 IpoptSolver::IpoptSolver() {
00035 osrlwriter = new OSrLWriter();
00036 osresult = new OSResult();
00037 m_osilreader = NULL;
00038 m_osolreader = NULL;
00039 ipoptErrorMsg = "";
00040 }
00041
00042 IpoptSolver::~IpoptSolver() {
00043 #ifdef DEBUG
00044 cout << "inside IpoptSolver destructor" << endl;
00045 #endif
00046 if(m_osilreader != NULL) delete m_osilreader;
00047 m_osilreader = NULL;
00048 if(m_osolreader != NULL) delete m_osolreader;
00049 m_osolreader = NULL;
00050 delete osresult;
00051 osresult = NULL;
00052 delete osrlwriter;
00053 osrlwriter = NULL;
00054
00055
00056 #ifdef DEBUG
00057 cout << "leaving IpoptSolver destructor" << endl;
00058 #endif
00059 }
00060
00061
00062 bool IpoptProblem::get_nlp_info(Index& n, Index& m, Index& nnz_jac_g,
00063 Index& nnz_h_lag, IndexStyleEnum& index_style)
00064 {
00065 if(osinstance->getObjectiveNumber() <= 0) throw ErrorClass("Ipopt NEEDS AN OBJECTIVE FUNCTION");
00066
00067 n = osinstance->getVariableNumber();
00068
00069 m = osinstance->getConstraintNumber();
00070 #ifdef DEBUG
00071 cout << "number variables !!!!!!!!!!!!!!!!!!!!!!!!!!!" << n << endl;
00072 cout << "number constraints !!!!!!!!!!!!!!!!!!!!!!!!!!!" << m << endl;
00073 #endif
00074 try{
00075 osinstance->initForAlgDiff( );
00076 }
00077 catch(const ErrorClass& eclass){
00078 #ifdef DEBUG
00079 cout << "error in OSIpoptSolver, line 78:\n" << eclass.errormsg << endl;
00080 #endif
00081 ipoptErrorMsg = eclass.errormsg;
00082 throw;
00083 }
00084
00085 osinstance->bUseExpTreeForFunEval = true;
00086
00087 SparseJacobianMatrix *sparseJacobian = NULL;
00088 try{
00089 sparseJacobian = osinstance->getJacobianSparsityPattern();
00090 }
00091 catch(const ErrorClass& eclass){
00092 #ifdef DEBUG
00093 cout << "error in OSIpoptSolver, line 91:\n" << eclass.errormsg << endl;
00094 #endif
00095 ipoptErrorMsg = eclass.errormsg;
00096 throw;
00097 }
00098
00099 nnz_jac_g = sparseJacobian->valueSize;
00100 #ifdef DEBUG
00101 cout << "nnz_jac_g !!!!!!!!!!!!!!!!!!!!!!!!!!!" << nnz_jac_g << endl;
00102 #endif
00103
00104
00105 if( (osinstance->getNumberOfNonlinearExpressions() == 0) && (osinstance->getNumberOfQuadraticTerms() == 0) ) {
00106 #ifdef DEBUG
00107 cout << "This is a linear program" << endl;
00108 #endif
00109 nnz_h_lag = 0;
00110 }
00111 else{
00112
00113 SparseHessianMatrix *sparseHessian = osinstance->getLagrangianHessianSparsityPattern();
00114
00115 nnz_h_lag = sparseHessian->hessDimension;
00116 }
00117 #ifdef DEBUG
00118 cout << "print nnz_h_lag (OSIpoptSolver.cpp)" << endl;
00119 cout << "nnz_h_lag !!!!!!!!!!!!!!!!!!!!!!!!!!!" << nnz_h_lag << endl;
00120 cout << "set index_style (OSIpoptSolver.cpp)" << endl;
00121 #endif
00122
00123 index_style = TNLP::C_STYLE;
00124 #ifdef DEBUG
00125 cout << "return from get_nlp_info (OSIpoptSolver.cpp)" << nnz_h_lag << endl;
00126 #endif
00127
00129
00130 return true;
00131 }
00132
00133
00134 bool IpoptProblem::get_bounds_info(Index n, Number* x_l, Number* x_u,
00135 Index m, Number* g_l, Number* g_u){
00136 int i;
00137 double * mdVarLB = osinstance->getVariableLowerBounds();
00138
00139
00140 double * mdVarUB = osinstance->getVariableUpperBounds();
00141
00142 for(i = 0; i < n; i++){
00143 x_l[ i] = mdVarLB[ i];
00144 x_u[ i] = mdVarUB[ i];
00145
00146
00147 }
00148
00149
00150
00151
00152
00153
00154 double * mdConLB = osinstance->getConstraintLowerBounds();
00155
00156 double * mdConUB = osinstance->getConstraintUpperBounds();
00157
00158 for(int i = 0; i < m; i++){
00159 g_l[ i] = mdConLB[ i];
00160 g_u[ i] = mdConUB[ i];
00161
00162
00163 }
00164 return true;
00165 }
00166
00167
00168
00169 bool IpoptProblem::get_starting_point(Index n, bool init_x, Number* x,
00170 bool init_z, Number* z_L, Number* z_U, Index m, bool init_lambda,
00171 Number* lambda) {
00172
00173
00174
00175 assert(init_x == true);
00176 assert(init_z == false);
00177 assert(init_lambda == false);
00178 int i, m1, n1;
00179
00180 #ifdef DEBUG
00181 cout << "get initial values !!!!!!!!!!!!!!!!!!!!!!!!!! " << endl;
00182 #endif
00183
00184
00185 #ifdef DEBUG
00186 cout << "get number of initial values !!!!!!!!!!!!!!!!!!!!!!!!!! " << endl;
00187 cout << "Is osoption = NULL? " << (osoption == NULL) << endl;
00188 #endif
00189 int k;
00190 if (osoption != NULL)
00191 m1 = osoption->getNumberOfInitVarValues();
00192 else
00193 m1 = 0;
00194 #ifdef DEBUG
00195 cout << "number of variables initialed: " << m1 << endl;
00196 #endif
00197
00198 n1 = osinstance->getVariableNumber();
00199 bool* initialed;
00200 initialed = new bool[n1];
00201 #ifdef DEBUG
00202 cout << "number of variables in total: " << n1 << endl;
00203 #endif
00204
00205 for(k = 0; k < n1; k++)
00206 initialed[k] = false;
00207
00208 if (m1 > 0)
00209 {
00210 #ifdef DEBUG
00211 cout << "get initial values " << endl;
00212 #endif
00213
00214 InitVarValue** initVarVector = osoption->getInitVarValuesSparse();
00215 #ifdef DEBUG
00216 cout << "done " << endl;
00217 #endif
00218 try
00219 {
00220 double initval;
00221 for(k = 0; k < m1; k++)
00222 { cout << "process component " << k << " -- index " << initVarVector[k]->idx << endl;
00223 i = initVarVector[k]->idx;
00224 if (initVarVector[k]->idx > n1)
00225 throw ErrorClass ("Illegal index value in variable initialization");
00226
00227 initval = initVarVector[k]->value;
00228 if (osinstance->instanceData->variables->var[k]->ub == OSDBL_MAX)
00229 { if (osinstance->instanceData->variables->var[k]->lb > initval)
00230 throw ErrorClass ("Initial value outside of bounds");
00231 }
00232 else
00233 if (osinstance->instanceData->variables->var[k]->lb == -OSDBL_MAX)
00234 { if (osinstance->instanceData->variables->var[k]->ub < initval)
00235 throw ErrorClass ("Initial value outside of bounds");
00236 }
00237 else
00238 { if ((osinstance->instanceData->variables->var[k]->lb > initval) ||
00239 (osinstance->instanceData->variables->var[k]->ub < initval))
00240 throw ErrorClass ("Initial value outside of bounds");
00241 }
00242
00243 x[initVarVector[k]->idx] = initval;
00244 initialed[initVarVector[k]->idx] = true;
00245 }
00246 }
00247 catch(const ErrorClass& eclass)
00248 { cout << "Error in IpoptProblem::get_starting_point (OSIpoptSolver.cpp, line 247)";
00249 cout << endl << endl << endl;
00250 }
00251 }
00252
00253 double default_initval;
00254 default_initval = 1.7171;
00255
00256 for(k = 0; k < n1; k++)
00257 { cout << "verify component " << k << endl;
00258 if (!initialed[k])
00259 if (osinstance->instanceData->variables->var[k]->ub == OSDBL_MAX)
00260 if (osinstance->instanceData->variables->var[k]->lb <= default_initval)
00261 x[k] = default_initval;
00262 else
00263 x[k] = osinstance->instanceData->variables->var[k]->lb;
00264 else
00265 if (osinstance->instanceData->variables->var[k]->lb == -OSDBL_MAX)
00266 if (osinstance->instanceData->variables->var[k]->ub >= default_initval)
00267 x[k] = default_initval;
00268 else
00269 x[k] = osinstance->instanceData->variables->var[k]->ub;
00270 else
00271 if ((osinstance->instanceData->variables->var[k]->lb <= default_initval) &&
00272 (osinstance->instanceData->variables->var[k]->ub >= default_initval))
00273 x[k] = default_initval;
00274 else
00275 if (osinstance->instanceData->variables->var[k]->lb > default_initval)
00276 x[k] = osinstance->instanceData->variables->var[k]->lb;
00277 else
00278 x[k] = osinstance->instanceData->variables->var[k]->ub;
00279 }
00280
00281 for(i = 0; i < n1; i++){
00282 std::cout << "INITIAL VALUE !!!!!!!!!!!!!!!!!!!! " << x[ i] << std::endl;
00283 }
00284
00285
00286 delete[] initialed;
00287
00288 return true;
00289 }
00290
00291
00292 bool IpoptProblem::eval_f(Index n, const Number* x, bool new_x, Number& obj_value){
00293 try{
00294 obj_value = osinstance->calculateAllObjectiveFunctionValues( const_cast<double*>(x), NULL, NULL, new_x, 0 )[ 0];
00295 }
00296 catch(const ErrorClass& eclass){
00297 #ifdef DEBUG
00298 cout << "error in OSIpoptSolver, line 296:\n" << eclass.errormsg << endl;
00299 #endif
00300 ipoptErrorMsg = eclass.errormsg;
00301 throw;
00302 }
00303 if( CommonUtil::ISOSNAN( (double)obj_value) ) return false;
00304 return true;
00305 }
00306
00307 bool IpoptProblem::eval_grad_f(Index n, const Number* x, bool new_x, Number* grad_f){
00308 int i;
00309 double *objGrad;
00310 try{
00311
00312 objGrad = osinstance->calculateObjectiveFunctionGradient( const_cast<double*>(x), NULL, NULL, -1, new_x, 1);
00313 }
00314 catch(const ErrorClass& eclass){
00315 #ifdef DEBUG
00316 cout << "error in OSIpoptSolver, line 314:\n" << eclass.errormsg << endl;
00317 #endif
00318 ipoptErrorMsg = eclass.errormsg;
00319 throw;
00320 }
00321 for(i = 0; i < n; i++){
00322 grad_f[ i] = objGrad[ i];
00323 }
00324 return true;
00325 }
00326
00327
00328 bool IpoptProblem::eval_g(Index n, const Number* x, bool new_x, Index m, Number* g) {
00329 try{
00330 double *conVals = osinstance->calculateAllConstraintFunctionValues( const_cast<double*>(x), NULL, NULL, new_x, 0 );
00331 int i;
00332 for(i = 0; i < m; i++){
00333 if( CommonUtil::ISOSNAN( (double)conVals[ i] ) ) return false;
00334 g[i] = conVals[ i] ;
00335 }
00336 return true;
00337 }
00338 catch(const ErrorClass& eclass){
00339 #ifdef DEBUG
00340 cout << "error in OSIpoptSolver, line 338:\n" << eclass.errormsg << endl;
00341 #endif
00342 ipoptErrorMsg = eclass.errormsg;
00343 throw;
00344 }
00345 }
00346
00347
00348
00349 bool IpoptProblem::eval_jac_g(Index n, const Number* x, bool new_x,
00350 Index m, Index nele_jac, Index* iRow, Index *jCol,
00351 Number* values){
00352 SparseJacobianMatrix *sparseJacobian;
00353 if (values == NULL) {
00354
00355
00356
00357
00358
00359 try{
00360 sparseJacobian = osinstance->getJacobianSparsityPattern();
00361 }
00362 catch(const ErrorClass& eclass){
00363 #ifdef DEBUG
00364 cout << "error in OSIpoptSolver, line 362:\n" << eclass.errormsg << endl;
00365 #endif
00366 ipoptErrorMsg = eclass.errormsg;
00367 throw;
00368 }
00369 int i = 0;
00370 int k, idx;
00371 for(idx = 0; idx < m; idx++){
00372 for(k = *(sparseJacobian->starts + idx); k < *(sparseJacobian->starts + idx + 1); k++){
00373 iRow[i] = idx;
00374 jCol[i] = *(sparseJacobian->indexes + k);
00375
00376
00377 i++;
00378 }
00379 }
00380 }
00381 else {
00382
00383 try{
00384 sparseJacobian = osinstance->calculateAllConstraintFunctionGradients( const_cast<double*>(x), NULL, NULL, new_x, 1);
00385 }
00386 catch(const ErrorClass& eclass){
00387 #ifdef DEBUG
00388 cout << "error in OSIpoptSolver, line 386:\n" << eclass.errormsg << endl;
00389 #endif
00390 ipoptErrorMsg = eclass.errormsg;
00391 throw;
00392 }
00393
00394 for(int i = 0; i < nele_jac; i++){
00395 values[ i] = sparseJacobian->values[i];
00396
00397
00398
00399 }
00400 }
00401 return true;
00402 }
00403
00404
00405 bool IpoptProblem::eval_h(Index n, const Number* x, bool new_x,
00406 Number obj_factor, Index m, const Number* lambda,
00407 bool new_lambda, Index nele_hess, Index* iRow,
00408 Index* jCol, Number* values){
00409
00411 SparseHessianMatrix *sparseHessian;
00412
00413 int i;
00414 if (values == NULL) {
00415
00416
00417 try{
00418 sparseHessian = osinstance->getLagrangianHessianSparsityPattern( );
00419 }
00420 catch(const ErrorClass& eclass){
00421 #ifdef DEBUG
00422 cout << "error in OSIpoptSolver, line 420:\n" << eclass.errormsg << endl;
00423 #endif
00424 ipoptErrorMsg = eclass.errormsg;
00425 throw;
00426 }
00427
00428 for(i = 0; i < nele_hess; i++){
00429 iRow[i] = *(sparseHessian->hessColIdx + i);
00430 jCol[i] = *(sparseHessian->hessRowIdx + i);
00431
00432
00433 }
00434 }
00435 else {
00436
00437
00438 double* objMultipliers = new double[1];
00439 objMultipliers[0] = obj_factor;
00440 try{
00441 sparseHessian = osinstance->calculateLagrangianHessian( const_cast<double*>(x), objMultipliers, (double*)lambda , new_x, 2);
00442 delete[] objMultipliers;
00443 }
00444 catch(const ErrorClass& eclass){
00445 #ifdef DEBUG
00446 cout << "error in OSIpoptSolver, line 444:\n" << eclass.errormsg << endl;
00447 #endif
00448 ipoptErrorMsg = eclass.errormsg;
00449 delete[] objMultipliers;
00450 throw;
00451 }
00452 for(i = 0; i < nele_hess; i++){
00453 values[ i] = *(sparseHessian->hessValues + i);
00454 }
00455 }
00457 return true;
00458 }
00459
00460 bool IpoptProblem::get_scaling_parameters(Number& obj_scaling,
00461 bool& use_x_scaling, Index n,
00462 Number* x_scaling,
00463 bool& use_g_scaling, Index m,
00464 Number* g_scaling){
00465 if( osinstance->instanceData->objectives->obj[ 0]->maxOrMin.compare("min") != 0){
00466 obj_scaling = -1;
00467 }
00468 else obj_scaling = 1;
00469 use_x_scaling = false;
00470 use_g_scaling = false;
00471 return true;
00472 }
00473
00474 void IpoptProblem::finalize_solution(SolverReturn status,
00475 Index n, const Number* x, const Number* z_L, const Number* z_U,
00476 Index m, const Number* g, const Number* lambda,
00477 Number obj_value,
00478 const IpoptData* ip_data,
00479 IpoptCalculatedQuantities* ip_cq)
00480 {
00481
00482
00483
00484 OSrLWriter *osrlwriter ;
00485 osrlwriter = new OSrLWriter();
00486 #ifdef DEBUG
00487 printf("\n\nSolution of the primal variables, x\n");
00488 for (Index i=0; i<n; i++) {
00489 printf("x[%d] = %e\n", i, x[i]);
00490 }
00491
00492 printf("\n\nSolution of the bound multipliers, z_L and z_U\n");
00493 for (Index i=0; i<n; i++) {
00494 printf("z_L[%d] = %e\n", i, z_L[i]);
00495 }
00496 for (Index i=0; i<n; i++) {
00497 printf("z_U[%d] = %e\n", i, z_U[i]);
00498 }
00499 #endif
00500 printf("\nObjective value f(x*) = %e\n", obj_value);
00501
00502 int solIdx = 0;
00503 int numberOfOtherVariableResults;
00504 int otherIdx;
00505 ostringstream outStr;
00506
00507 std::string *rcost = NULL;
00508 double* mdObjValues = new double[1];
00509 std::string message = "Ipopt solver finishes to the end.";
00510 std::string solutionDescription = "";
00511
00512 try{
00513
00514 if(osresult->setServiceName( "Ipopt solver service") != true)
00515 throw ErrorClass("OSResult error: setServiceName");
00516 if(osresult->setInstanceName( osinstance->getInstanceName()) != true)
00517 throw ErrorClass("OSResult error: setInstanceName");
00518
00519
00520
00521
00522
00523 if(osresult->setVariableNumber( osinstance->getVariableNumber()) != true)
00524 throw ErrorClass("OSResult error: setVariableNumer");
00525 if(osresult->setObjectiveNumber( 1) != true)
00526 throw ErrorClass("OSResult error: setObjectiveNumber");
00527 if(osresult->setConstraintNumber( osinstance->getConstraintNumber()) != true)
00528 throw ErrorClass("OSResult error: setConstraintNumber");
00529 if(osresult->setSolutionNumber( 1) != true)
00530 throw ErrorClass("OSResult error: setSolutionNumer");
00531
00532
00533 if(osresult->setGeneralMessage( message) != true)
00534 throw ErrorClass("OSResult error: setGeneralMessage");
00535
00536 switch( status){
00537 case SUCCESS:
00538 solutionDescription = "SUCCESS[IPOPT]: Algorithm terminated successfully at a locally optimal point, satisfying the convergence tolerances.";
00539 osresult->setSolutionStatus(solIdx, "locallyOptimal", solutionDescription);
00540 osresult->setPrimalVariableValues(solIdx, const_cast<double*>(x), osinstance->getVariableNumber());
00541 osresult->setDualVariableValues(solIdx, const_cast<double*>( lambda), osinstance->getConstraintNumber());
00542 mdObjValues[0] = obj_value;
00543 osresult->setObjectiveValues(solIdx, mdObjValues, 1);
00544
00545
00546
00547
00548 numberOfOtherVariableResults = 2;
00549 osresult->setNumberOfOtherVariableResults(solIdx, numberOfOtherVariableResults);
00550
00551
00552 rcost = new std::string[ osinstance->getVariableNumber()];
00553
00554
00555 for (Index i = 0; i < n; i++) {
00556 rcost[ i] = os_dtoa_format( z_L[i]);
00557 }
00558 otherIdx = 0;
00559 osresult->setAnOtherVariableResult(solIdx, otherIdx, "varL", "Lagrange Multiplier on the Variable Lower Bound", rcost, osinstance->getVariableNumber());
00560
00561
00562 for (Index i = 0; i < n; i++) {
00563 rcost[ i] = os_dtoa_format( z_U[i]);
00564 }
00565 otherIdx = 1;
00566 osresult->setAnOtherVariableResult(solIdx, otherIdx, "varU", "Lagrange Multiplier on the Variable Upper Bound", rcost, osinstance->getVariableNumber());
00567
00568 delete[] rcost;
00569
00570
00571
00572
00573 break;
00574 case MAXITER_EXCEEDED:
00575 solutionDescription = "MAXITER_EXCEEDED[IPOPT]: Maximum number of iterations exceeded.";
00576 osresult->setSolutionStatus(solIdx, "stoppedByLimit", solutionDescription);
00577 osresult->setPrimalVariableValues(solIdx, const_cast<double*>(x), osinstance->getVariableNumber());
00578 osresult->setDualVariableValues(solIdx, const_cast<double*>( lambda), osinstance->getConstraintNumber());
00579 mdObjValues[0] = obj_value;
00580 osresult->setObjectiveValues(solIdx, mdObjValues, 1);
00581 break;
00582 case STOP_AT_TINY_STEP:
00583 solutionDescription = "STOP_AT_TINY_STEP[IPOPT]: Algorithm proceeds with very little progress.";
00584 osresult->setSolutionStatus(solIdx, "stoppedByLimit", solutionDescription);
00585 osresult->setPrimalVariableValues(solIdx, const_cast<double*>( x), osinstance->getVariableNumber());
00586 osresult->setDualVariableValues(solIdx, const_cast<double*>( lambda), osinstance->getConstraintNumber());
00587 mdObjValues[0] = obj_value;
00588 osresult->setObjectiveValues(solIdx, mdObjValues, 1);
00589 break;
00590 case STOP_AT_ACCEPTABLE_POINT:
00591 solutionDescription = "STOP_AT_ACCEPTABLE_POINT[IPOPT]: Algorithm stopped at a point that was converged, not to _desired_ tolerances, but to _acceptable_ tolerances";
00592 osresult->setSolutionStatus(solIdx, "IpoptAccetable", solutionDescription);
00593 osresult->setPrimalVariableValues(solIdx, const_cast<double*>(x), osinstance->getVariableNumber());
00594 osresult->setDualVariableValues(solIdx, const_cast<double*>( lambda), osinstance->getConstraintNumber());
00595 mdObjValues[0] = obj_value;
00596 osresult->setObjectiveValues(solIdx, mdObjValues, 1);
00597 break;
00598 case LOCAL_INFEASIBILITY:
00599 solutionDescription = "LOCAL_INFEASIBILITY[IPOPT]: Algorithm converged to a point of local infeasibility. Problem may be infeasible.";
00600 osresult->setSolutionStatus(solIdx, "infeasible", solutionDescription);
00601 break;
00602 case USER_REQUESTED_STOP:
00603 solutionDescription = "USER_REQUESTED_STOP[IPOPT]: The user call-back function intermediate_callback returned false, i.e., the user code requested a premature termination of the optimization.";
00604 osresult->setSolutionStatus(solIdx, "error", solutionDescription);
00605 break;
00606 case DIVERGING_ITERATES:
00607 solutionDescription = "DIVERGING_ITERATES[IPOPT]: It seems that the iterates diverge.";
00608 osresult->setSolutionStatus(solIdx, "unbounded", solutionDescription);
00609 break;
00610 case RESTORATION_FAILURE:
00611 solutionDescription = "RESTORATION_FAILURE[IPOPT]: Restoration phase failed, algorithm doesn't know how to proceed.";
00612 osresult->setSolutionStatus(solIdx, "error", solutionDescription);
00613 break;
00614 case ERROR_IN_STEP_COMPUTATION:
00615 solutionDescription = "ERROR_IN_STEP_COMPUTATION[IPOPT]: An unrecoverable error occurred while IPOPT tried to compute the search direction.";
00616 osresult->setSolutionStatus(solIdx, "error", solutionDescription);
00617 break;
00618 case INVALID_NUMBER_DETECTED:
00619 solutionDescription = "INVALID_NUMcatBER_DETECTED[IPOPT]: Algorithm received an invalid number (such as NaN or Inf) from the NLP; see also option check_derivatives_for_naninf.";
00620 osresult->setSolutionStatus(solIdx, "error", solutionDescription);
00621 break;
00622 case INTERNAL_ERROR:
00623 solutionDescription = "INTERNAL_ERROR[IPOPT]: An unknown internal error occurred. Please contact the IPOPT authors through the mailing list.";
00624 osresult->setSolutionStatus(solIdx, "error", solutionDescription);
00625 break;
00626 default:
00627 solutionDescription = "OTHER[IPOPT]: other unknown solution status from Ipopt solver";
00628 osresult->setSolutionStatus(solIdx, "other", solutionDescription);
00629 }
00630 osresult->setGeneralStatusType("normal");
00631 delete osrlwriter;
00632 delete[] mdObjValues;
00633 osrlwriter = NULL;
00634
00635 }
00636 catch(const ErrorClass& eclass){
00637 #ifdef DEBUG
00638 cout << "error in OSIpoptSolver, line 636:\n" << eclass.errormsg << endl;
00639 #endif
00640 osresult->setGeneralMessage( eclass.errormsg);
00641 osresult->setGeneralStatusType( "error");
00642 std::string osrl = osrlwriter->writeOSrL( osresult);
00643 delete osrlwriter;
00644 osrlwriter = NULL;
00645 throw ErrorClass( osrl) ;
00646 delete[] mdObjValues;
00647 mdObjValues = NULL;
00648 }
00650 }
00651
00652
00653 void IpoptSolver::setSolverOptions() throw (ErrorClass) {
00654 try{
00655
00656 this->bSetSolverOptions = true;
00657 app->Options()->SetNumericValue("tol", 1e-9);
00658 app->Options()->SetIntegerValue("print_level", 0);
00659 app->Options()->SetIntegerValue("max_iter", 20000);
00660 app->Options()->SetStringValue("mu_strategy", "adaptive");
00661 app->Options()->SetStringValue("output_file", "ipopt.out");
00662 app->Options()->SetStringValue("check_derivatives_for_naninf", "yes");
00663
00664
00665 if(osoption == NULL && osol.length() > 0)
00666 {
00667 m_osolreader = new OSoLReader();
00668 osoption = m_osolreader->readOSoL( osol);
00669 }
00670
00671 if( osoption != NULL && osoption->getNumberOfSolverOptions() > 0 ){
00672 std::cout << "number of solver options " << osoption->getNumberOfSolverOptions() << std::endl;
00673 std::vector<SolverOption*> optionsVector;
00674 optionsVector = osoption->getSolverOptions( "ipopt");
00675 char *pEnd;
00676 int i;
00677 int num_ipopt_options = optionsVector.size();
00678 for(i = 0; i < num_ipopt_options; i++){
00679 std::cout << "ipopt solver option " << optionsVector[ i]->name << std::endl;
00680 if(optionsVector[ i]->type == "numeric" ){
00681 std::cout << "FOUND A NUMERIC OPTION " << os_strtod( optionsVector[ i]->value.c_str(), &pEnd ) << std::endl;
00682 app->Options()->SetNumericValue(optionsVector[ i]->name, os_strtod( optionsVector[ i]->value.c_str(), &pEnd ) );
00683 }
00684 else if(optionsVector[ i]->type == "integer" ){
00685 std::cout << "FOUND AN INTEGER OPTION " << atoi( optionsVector[ i]->value.c_str() ) << std::endl;
00686 app->Options()->SetIntegerValue(optionsVector[ i]->name, atoi( optionsVector[ i]->value.c_str() ) );
00687 }
00688 else if(optionsVector[ i]->type == "string" ){
00689 std::cout << "FOUND A STRING OPTION " << optionsVector[ i]->value.c_str() << std::endl;
00690 app->Options()->SetStringValue(optionsVector[ i]->name, optionsVector[ i]->value);
00691 }
00692 }
00693 }
00694 }
00695 catch(const ErrorClass& eclass){
00696 #ifdef DEBUG
00697 cout << "error in OSIpoptSolver, line 695:\n" << eclass.errormsg << endl;
00698 #endif
00699 std::cout << "THERE IS AN ERROR" << std::endl;
00700 osresult->setGeneralMessage( eclass.errormsg);
00701 osresult->setGeneralStatusType( "error");
00702 osrl = osrlwriter->writeOSrL( osresult);
00703 throw ErrorClass( osrl) ;
00704 }
00705 }
00706
00707
00708
00709 void IpoptSolver::buildSolverInstance() throw (ErrorClass) {
00710 try{
00711
00712 if(osil.length() == 0 && osinstance == NULL) throw ErrorClass("there is no instance");
00713 if(osinstance == NULL){
00714 m_osilreader = new OSiLReader();
00715 osinstance = m_osilreader->readOSiL( osil);
00716 }
00717
00718 nlp = new IpoptProblem( osinstance, osoption, osresult);
00719 app = new IpoptApplication();
00720 this->bCallbuildSolverInstance = true;
00721 }
00722 catch(const ErrorClass& eclass){
00723 #ifdef DEBUG
00724 cout << "error in OSIpoptSolver, line 722:\n" << eclass.errormsg << endl;
00725 #endif
00726 std::cout << "THERE IS AN ERROR" << std::endl;
00727 osresult->setGeneralMessage( eclass.errormsg);
00728 osresult->setGeneralStatusType( "error");
00729 osrl = osrlwriter->writeOSrL( osresult);
00730 throw ErrorClass( osrl) ;
00731 }
00732 }
00733
00734
00735
00736 void IpoptSolver::solve() throw (ErrorClass) {
00737 if( this->bCallbuildSolverInstance == false) buildSolverInstance();
00738 if( this->bSetSolverOptions == false) setSolverOptions();
00739 try{
00740 clock_t start, finish;
00741 double duration;
00742 start = clock();
00743
00744
00745 if(osinstance->getVariableNumber() <= 0)throw ErrorClass("Ipopt requires decision variables");
00746 finish = clock();
00747 duration = (double) (finish - start) / CLOCKS_PER_SEC;
00748 cout << "Parsing took (seconds): " << duration << endl;
00749
00750
00751
00752 if(osinstance->getObjectiveNumber() <= 0) throw ErrorClass("Ipopt NEEDS AN OBJECTIVE FUNCTION");
00753 if( (osinstance->getNumberOfNonlinearExpressions() == 0) && (osinstance->getNumberOfQuadraticTerms() == 0) )
00754 app->Options()->SetStringValue("hessian_approximation", "limited-memory");
00755
00756 if( osinstance->instanceData->objectives->obj[ 0]->maxOrMin.compare("min") != 0){
00757 app->Options()->SetStringValue("nlp_scaling_method", "user-scaling");
00758 }
00759
00760 std::cout << "Call Ipopt Initialize" << std::endl;
00761 app->Initialize();
00762 std::cout << "Finished Ipopt Initialize" << std::endl;
00763
00764
00765 std::cout << "Call Ipopt Optimize" << std::endl;
00766 ApplicationReturnStatus status = app->OptimizeTNLP( nlp);
00767 std::cout << "Finish Ipopt Optimize" << std::endl;
00768 osrl = osrlwriter->writeOSrL( osresult);
00769 std::cout << "Finish writing the osrl" << std::endl;
00770
00771 if (status < -2) {
00772 throw ErrorClass("Ipopt FAILED TO SOLVE THE PROBLEM: " + ipoptErrorMsg);
00773 }
00774 }
00775 catch(const ErrorClass& eclass){
00776 #ifdef DEBUG
00777 cout << "error in OSIpoptSolver, line 775:\n" << eclass.errormsg << endl;
00778 #endif
00779 osresult->setGeneralMessage( eclass.errormsg);
00780 osresult->setGeneralStatusType( "error");
00781 osrl = osrlwriter->writeOSrL( osresult);
00782 throw ErrorClass( osrl) ;
00783 }
00784 }
00785
00786
00787 void IpoptSolver::dataEchoCheck(){
00788
00789 int i;
00790
00791
00792 cout << "This is problem: " << osinstance->getInstanceName() << endl;
00793 cout << "The problem source is: " << osinstance->getInstanceSource() << endl;
00794 cout << "The problem description is: " << osinstance->getInstanceDescription() << endl;
00795 cout << "number of variables = " << osinstance->getVariableNumber() << endl;
00796 cout << "number of Rows = " << osinstance->getConstraintNumber() << endl;
00797
00798
00799 if(osinstance->getVariableNumber() > 0){
00800 for(i = 0; i < osinstance->getVariableNumber(); i++){
00801 if(osinstance->getVariableNames() != NULL) cout << "variable Names " << osinstance->getVariableNames()[ i] << endl;
00802 if(osinstance->getVariableTypes() != NULL) cout << "variable Types " << osinstance->getVariableTypes()[ i] << endl;
00803 if(osinstance->getVariableLowerBounds() != NULL) cout << "variable Lower Bounds " << osinstance->getVariableLowerBounds()[ i] << endl;
00804 if(osinstance->getVariableUpperBounds() != NULL) cout << "variable Upper Bounds " << osinstance->getVariableUpperBounds()[i] << endl;
00805 }
00806 }
00807
00808
00809 if(osinstance->getVariableNumber() > 0 || osinstance->instanceData->objectives->obj != NULL || osinstance->instanceData->objectives->numberOfObjectives > 0){
00810 if( osinstance->getObjectiveMaxOrMins()[0] == "min") cout << "problem is a minimization" << endl;
00811 else cout << "problem is a maximization" << endl;
00812 for(i = 0; i < osinstance->getVariableNumber(); i++){
00813 cout << "OBJ COEFFICIENT = " << osinstance->getDenseObjectiveCoefficients()[0][i] << endl;
00814 }
00815 }
00816
00817 if(osinstance->getConstraintNumber() > 0){
00818 for(i = 0; i < osinstance->getConstraintNumber(); i++){
00819 if(osinstance->getConstraintNames() != NULL) cout << "row name = " << osinstance->getConstraintNames()[i] << endl;
00820 if(osinstance->getConstraintLowerBounds() != NULL) cout << "row lower bound = " << osinstance->getConstraintLowerBounds()[i] << endl;
00821 if(osinstance->getConstraintUpperBounds() != NULL) cout << "row upper bound = " << osinstance->getConstraintUpperBounds()[i] << endl;
00822 }
00823 }
00824
00825
00826 cout << endl;
00827 cout << "number of nonzeros = " << osinstance->getLinearConstraintCoefficientNumber() << endl;
00828 for(i = 0; i <= osinstance->getVariableNumber(); i++){
00829 cout << "Start Value = " << osinstance->getLinearConstraintCoefficientsInColumnMajor()->starts[ i] << endl;
00830 }
00831 cout << endl;
00832 for(i = 0; i < osinstance->getLinearConstraintCoefficientNumber(); i++){
00833 cout << "Index Value = " << osinstance->getLinearConstraintCoefficientsInColumnMajor()->indexes[i] << endl;
00834 cout << "Nonzero Value = " << osinstance->getLinearConstraintCoefficientsInColumnMajor()->values[i] << endl;
00835 }
00836
00837
00838 cout << "number of qterms = " << osinstance->getNumberOfQuadraticTerms() << endl;
00839 for(int i = 0; i < osinstance->getNumberOfQuadraticTerms(); i++){
00840 cout << "Row Index = " << osinstance->getQuadraticTerms()->rowIndexes[i] << endl;
00841 cout << "Var Index 1 = " << osinstance->getQuadraticTerms()->varOneIndexes[ i] << endl;
00842 cout << "Var Index 2 = " << osinstance->getQuadraticTerms()->varTwoIndexes[ i] << endl;
00843 cout << "Coefficient = " << osinstance->getQuadraticTerms()->coefficients[ i] << endl;
00844 }
00845 }
00846
00847
00848 IpoptProblem::IpoptProblem(OSInstance *osinstance_, OSOption *osoption_, OSResult *osresult_) {
00849 osinstance = osinstance_;
00850 osoption = osoption_;
00851 osresult = osresult_;
00852 }
00853
00854 IpoptProblem::~IpoptProblem() {
00855
00856 }
00857
00858
00859