- Main Page
- Namespaces
- Classes
- Files
- Related Pages

- File List
- File Members

# /home/coin/SVN-release/OS-2.3.5/OS/src/OSSolverInterfaces/OSKnitroSolver.cpp

Go to the documentation of this file.

    00001 /* $Id: OSKnitroSolver.cpp 2925 2009-09-18 19:47:25Z Gassmann $ */
    00021 #include "OSKnitroSolver.h"
    00022 #include "OSCommonUtil.h"
    00023
    00024 using std::cout;
    00025 using std::endl;
    00026 using std::ostringstream;
    00027 using namespace std;
    00028
    00029 #if defined(_WIN32)
    00030   #include  <windows.h>     //-- FOR LoadLibrary
    00031 #else
    00032   #include  <dlfcn.h>       //-- FOR dlopen
    00033 #endif
    00034
    00035
    00036 //--------------------------------------------------------------------
    00037 //  Static variables and data
    00038 //--------------------------------------------------------------------
    00039
    00040 static NlpProblemDef *  g_pTheNlpProblemDefInstance = NULL;
    00041
    00042 //for calling the solver and feeding the nlp problem
    00043 static NlpProblemDef *  g_pOptProblem = NULL;
    00044
    00045 static int  wrapperEvalFC (const int             evalRequestCode,
    00046                            const int             n,
    00047                            const int             m,
    00048                            const int             nnzJ,
    00049                            const int             nnzH,
    00050                            const double * const  daX,
    00051                            const double * const  daLambda,
    00052                                  double * const  dObj,
    00053                                  double * const  daC,
    00054                                  double * const  daG,
    00055                                  double * const  daJ,
    00056                                  double * const  daH,
    00057                                  double * const  daHV,
    00058                                  void   *        userParams){
    00059     if (g_pOptProblem == NULL)
    00060         {
    00061         cout << "*** Problem not defined  <wrapperEvalFC>\n";
    00062         return( -1 );
    00063         }
    00064     if (evalRequestCode != KTR_RC_EVALFC)
    00065         {
    00066         cout << "*** Bad request code " << evalRequestCode
    00067              << "  <wrapperEvalFC>\n";
    00068         return( -1 );
    00069         }
    00070     return( g_pOptProblem->evalFC (daX, dObj, daC, userParams) );
    00071 }//wrapperEvalFC
    00072
    00073
    00074 //--------------------------------------------------------------------
    00075 //  Internal Function:  wrapperEvalGA
    00076 //--------------------------------------------------------------------
    00080 static int  wrapperEvalGA (const int             evalRequestCode,
    00081                            const int             n,
    00082                            const int             m,
    00083                            const int             nnzJ,
    00084                            const int             nnzH,
    00085                            const double * const  daX,
    00086                            const double * const  daLambda,
    00087                                  double * const  dObj,
    00088                                  double * const  daC,
    00089                                  double * const  daG,
    00090                                  double * const  daJ,
    00091                                  double * const  daH,
    00092                                  double * const  daHV,
    00093                                  void   *        userParams){
    00094     if (g_pOptProblem == NULL)
    00095         {
    00096         cout << "*** Problem not defined  <wrapperEvalGA>\n";
    00097         return( -1 );
    00098         }
    00099     if (evalRequestCode != KTR_RC_EVALGA)
    00100         {
    00101         cout << "*** Bad request code " << evalRequestCode
    00102              << "  <wrapperEvalGA>\n";
    00103         return( -1 );
    00104         }
    00105     return( g_pOptProblem->evalGA (daX, daG, daJ, userParams) );
    00106 }//wrapperEvalGA
    00107
    00108
    00109 //--------------------------------------------------------------------
    00110 //  Internal Function:  wrapperEvalHorHV
    00111 //--------------------------------------------------------------------
    00115 static int  wrapperEvalHorHV (const int             evalRequestCode,
    00116                               const int             n,
    00117                               const int             m,
    00118                               const int             nnzJ,
    00119                               const int             nnzH,
    00120                               const double * const  daX,
    00121                               const double * const  daLambda,
    00122                                     double * const  dObj,
    00123                                     double * const  daC,
    00124                                     double * const  daG,
    00125                                     double * const  daJ,
    00126                                     double * const  daH,
    00127                                     double * const  daHV,
    00128                                     void   *        userParams){
    00129     if (g_pOptProblem == NULL)
    00130         {
    00131         cout << "*** Problem not defined  <wrapperEvalHorHV>\n";
    00132         return( -1 );
    00133         }
    00134     if (evalRequestCode == KTR_RC_EVALH)
    00135         {
    00136         if (g_pOptProblem->areDerivativesImplemented (nCAN_COMPUTE_H) == false)
    00137             {
    00138             cout << "*** This problem not evaluate H  <wrapperEvalHorHV>\n";
    00139             return( -1 );
    00140             }
    00141         return( g_pOptProblem->evalH (daX, daLambda, daH, userParams) );
    00142         }
    00143     else if (evalRequestCode == KTR_RC_EVALHV)
    00144         {
    00145         if (g_pOptProblem->areDerivativesImplemented (nCAN_COMPUTE_HV) == false)
    00146             {
    00147             cout << "*** This problem not evaluate H*v  <wrapperEvalHorHV>\n";
    00148             return( -1 );
    00149             }
    00150         return( g_pOptProblem->evalHV (daX, daLambda, daHV, userParams) );
    00151         }
    00152     else
    00153         {
    00154         cout << "*** Bad request code " << evalRequestCode
    00155              << "  <wrapperEvalHorHV>\n";
    00156         return( -1 );
    00157         }
    00158 }//wrapperEvalHorHV
    00159
    00160
    00161
    00162 //--------------------------------------------------------------------
    00163 //  Exported Function:  getNlpProblemDef
    00164 //--------------------------------------------------------------------
    00165 //++ Export a function that returns the static pointer to this class.
    00166 #ifdef __cplusplus
    00167 extern "C"
    00168 {
    00169     #if defined(_WIN32)
    00170     __declspec(dllexport) NlpProblemDef *  getNlpProblemDef (void)
    00171     #else
    00172      NlpProblemDef *  getNlpProblemDef (void)
    00173     #endif
    00174     {
    00175         if (g_pTheNlpProblemDefInstance == NULL)
    00176             g_pTheNlpProblemDefInstance = new KnitroProblem(NULL, NULL);
    00177
    00178         return( g_pTheNlpProblemDefInstance );
    00179     }
    00180 }
    00181 #endif
    00182
    00183
    00184 KnitroProblem::KnitroProblem(OSInstance *osinstance_,  OSResult *osresult_ ) {
    00185
    00186         _daXInit = NULL;
    00187         osinstance = osinstance_;
    00188         osresult = osresult_;
    00189 }
    00190
    00191
    00192
    00193 KnitroProblem::~KnitroProblem() {
    00194     delete [] _daXInit;
    00195         _daXInit = NULL;
    00196 }
    00197
    00198
    00199
    00200 //--------------------------------------------------------------------
    00201 //  Simple access methods
    00202 //--------------------------------------------------------------------
    00203
    00204 int  KnitroProblem::getN (void){
    00205     return( _nN );
    00206 }//getN
    00207
    00208
    00209 int  KnitroProblem::getM (void){
    00210     return( _nM );
    00211 }//getM
    00212
    00213
    00214 void  KnitroProblem::getInitialX (double * const  daX){
    00215     if (_daXInit == NULL){
    00216         cout << "*** Must call 'loadProblemIntoKnitro' before 'KnitroSolver::getInitialX'\n";
    00217         exit( EXIT_FAILURE );
    00218         }
    00219
    00220         for (int  i = 0; i < _nN; i++){
    00221         daX[i] = _daXInit[i];
    00222         }
    00223     return;
    00224 }//getM
    00225
    00226 //--------------------------------------------------------------------
    00227 //  Method:  loadProblemIntoKnitro
    00228 //--------------------------------------------------------------------
    00232 bool  KnitroProblem::loadProblemIntoKnitro (KTR_context_ptr  kc){
    00233         int i;
    00234         if(osinstance->getObjectiveNumber() <= 0) throw ErrorClass("Knitro NEEDS AN OBJECTIVE FUNCTION");
    00235         // number of variables
    00236         _nN = osinstance->getVariableNumber();
    00237         // number of constraints
    00238         _nM = osinstance->getConstraintNumber();
    00239         cout << "number variables  !!!!!!!!!!!!!!!!!!!!!!!!!!!"   <<   _nN << endl;
    00240         cout << "number constraints  !!!!!!!!!!!!!!!!!!!!!!!!!!!" <<   _nM << endl;
    00241         try{
    00242                 osinstance->initForAlgDiff( );
    00243         }
    00244         catch(const ErrorClass& eclass){
    00245                 knitroErrorMsg = eclass.errormsg;
    00246                 throw;
    00247         }
    00248
    00249         // variables lower bounds
    00250         double * mdVarLB = osinstance->getVariableLowerBounds();
    00251         std::cout << "GET BOUNDS INFORMATION FOR KNITRO!!!!!!!!!!!!!!!" << std::endl;
    00252         // variables upper bounds
    00253         double * mdVarUB = osinstance->getVariableUpperBounds();
    00254
    00255         _daXLo  = new double[_nN];
    00256     _daXUp  = new double[_nN];
    00257         for(i = 0; i < _nN; i++){
    00258                 if( mdVarLB[ i] == -OSDBL_MAX) _daXLo[i] = -KTR_INFBOUND;
    00259                         else _daXLo[i] = mdVarLB[ i];
    00260                 if( mdVarUB[ i] == OSDBL_MAX) _daXUp[i] = KTR_INFBOUND;
    00261                         else _daXUp[i] = mdVarUB[ i];
    00262                 //cout << "x_l !!!!!!!!!!!!!!!!!!!!!!!!!!!" << x_l[i] << endl;
    00263                 //cout << "x_u !!!!!!!!!!!!!!!!!!!!!!!!!!!" << x_u[i] << endl;
    00264         }
    00265
    00266         //constraint lower bounds
    00267         double * mdConLB = osinstance->getConstraintLowerBounds();
    00268         //constraint upper bounds
    00269         double * mdConUB = osinstance->getConstraintUpperBounds();
    00270
    00271         _naCType = new int[ _nM];
    00272     _daCLo   = new double[ _nM];
    00273     _daCUp   = new double[ _nM];
    00274     _naCType[0] = KTR_CONTYPE_LINEAR;
    00275         for(i = 0; i < _nM; i++){
    00276                 if( mdConLB[ i] == -OSDBL_MAX) _daCLo[i] = -KTR_INFBOUND;
    00277                         else _daCLo[i] = mdConLB[ i];
    00278                 if( mdConUB[ i] == OSDBL_MAX) _daCUp[i] = KTR_INFBOUND;
    00279                         else _daCUp[i] = mdConUB[ i];
    00280                 //cout << "lower !!!!!!!!!!!!!!!!!!!!!!!!!!!" << _daCLo[i] << endl;
    00281                 //cout << "upper !!!!!!!!!!!!!!!!!!!!!!!!!!!" << _daCUp[i] << endl;
    00282                 _naCType[i] = KTR_CONTYPE_GENERAL; //need change
    00283         }
    00284
    00285         // use the OS Expression tree for function evaluations instead of CppAD
    00286         osinstance->bUseExpTreeForFunEval = true;
    00287         std::cout << "Call sparse jacobian" << std::endl;
    00288         SparseJacobianMatrix *sparseJacobian = NULL;
    00289         try{
    00290                 sparseJacobian = osinstance->getJacobianSparsityPattern();
    00291         }
    00292         catch(const ErrorClass& eclass){
    00293                 knitroErrorMsg = eclass.errormsg;
    00294                 throw;
    00295         }
    00296         std::cout << "Done calling sparse jacobian" << std::endl;
    00297         _nNnzJ = sparseJacobian->valueSize;
    00298         //cout << "_nNnzJ  !!!!!!!!!!!!!!!!!!!!!!!!!!!" << _nNnzJ << endl;
    00299     _naJacIndexVars = new int[_nNnzJ];
    00300     _naJacIndexCons = new int[_nNnzJ];
    00301         int k, idx;
    00302         i = 0;
    00303         for(idx = 0; idx < _nM; idx++){
    00304                 for(k = *(sparseJacobian->starts + idx); k < *(sparseJacobian->starts + idx + 1); k++){
    00305                         _naJacIndexCons[i] = idx;
    00306                         _naJacIndexVars[i] = *(sparseJacobian->indexes + k);
    00307                         //cout << "ROW IDX  !!!!!!!!!!!!!!!!!!!!!!!!!!!"  << _naJacIndexCons[i] << endl;
    00308                         //cout << "COL IDX  !!!!!!!!!!!!!!!!!!!!!!!!!!!"  << _naJacIndexVars[i] << endl;
    00309                         i++;
    00310                 }
    00311         }
    00312
    00313
    00314         // nonzeros in upper hessian
    00315         if( (osinstance->getNumberOfNonlinearExpressions() == 0) && (osinstance->getNumberOfQuadraticTerms() == 0) ) {
    00316                 cout << "This is a linear program"  << endl;
    00317                 _nNnzH = 0;
    00318         }
    00319         else{
    00320                 std::cout << "Get Lagrangain Hessian Sparsity Pattern " << std::endl;
    00321                 SparseHessianMatrix *sparseHessian = osinstance->getLagrangianHessianSparsityPattern();
    00322                 std::cout << "Done Getting Lagrangain Hessian Sparsity Pattern " << std::endl;
    00323                 _nNnzH = sparseHessian->hessDimension;
    00324                 _naHessRows = new int[_nNnzH];
    00325                 _naHessCols = new int[_nNnzH];
    00326                 for(i = 0; i < _nNnzH; i++){
    00327                         _naHessCols[i] = *(sparseHessian->hessColIdx + i);
    00328                         _naHessRows[i] = *(sparseHessian->hessRowIdx + i);
    00329                                 cout << "ROW HESS IDX  !!!!!!!!!!!!!!!!!!!!!!!!!!!"  << _naHessRows[i] << endl;
    00330                                 cout << "COL HESS IDX  !!!!!!!!!!!!!!!!!!!!!!!!!!!"  << _naHessCols[i] << endl;
    00331                 }
    00332         }
    00333     //---- INITIAL GUESS FOR x AND lambda.
    00334         // Here, we assume we only have starting values for x, if you code
    00335         // your own NLP, you can provide starting values for the dual variables
    00336         // if you wish
    00337         //cout << "get initial values !!!!!!!!!!!!!!!!!!!!!!!!!! " << endl;
    00338         double *mdXInit = osinstance->getVariableInitialValues();
    00339         _daXInit = new double[_nN];
    00340         if( mdXInit != NULL) {
    00341                 for(i = 0; i < _nN; i++){
    00342                         if(  CommonUtil::ISOSNAN( mdXInit[ i])  == true){
    00343                                 _daXInit[ i] = 1.7171;
    00344                         }
    00345                         else _daXInit[ i] = mdXInit[ i];
    00346                 }
    00347         }
    00348         else{
    00349                 for(i = 0; i < _nN; i++){
    00350                         _daXInit[ i] = 1.7171;
    00351                 }
    00352         }
    00353         //cout << "got initial values !!!!!!!!!!!!!!!!!!!!!!!!!! " << endl;
    00354
    00355         double *  daLambdaInit = new double[_nM + _nN];
    00356     for (i = 0; i < _nM + _nN; i++)
    00357         daLambdaInit[i] = 0.0;
    00358
    00359     // set obj type
    00360     int iObjSense = KTR_OBJGOAL_MINIMIZE;
    00361         if( osinstance->instanceData->objectives->obj[ 0]->maxOrMin.compare("max") == 0){
    00362                 iObjSense = KTR_OBJGOAL_MAXIMIZE;
    00363         }
    00364     int iObjType = KTR_OBJTYPE_GENERAL; //KTR_OBJTYPE_LINEAR, KTR_OBJTYPE_QUADRATIC
    00365         i = KTR_init_problem (kc, _nN,
    00366                           iObjSense, iObjType,
    00367                           _daXLo, _daXUp,
    00368                           _nM, _naCType, _daCLo, _daCUp,
    00369                           _nNnzJ, _naJacIndexVars, _naJacIndexCons,
    00370                           _nNnzH, _naHessRows, _naHessCols,
    00371                           _daXInit, daLambdaInit);
    00372
    00373     delete [] _daXLo;
    00374     delete [] _daXUp;
    00375     delete [] _naCType;
    00376     delete [] _daCLo;
    00377     delete [] _daCUp;
    00378     delete [] _naJacIndexVars;
    00379     delete [] _naJacIndexCons;
    00380     delete [] _naHessRows;
    00381     delete [] _naHessCols;
    00382     delete [] daLambdaInit;
    00383
    00384     if (i != 0)
    00385         {
    00386         cout << "*** KTR_init_problem() returned " << i << "\n";
    00387         return( false );
    00388         }
    00389
    00390     return( true );
    00391 }//loadProblemIntoKnitro
    00392
    00393 //--------------------------------------------------------------------
    00394 //  Method:  areDerivativesImplemented
    00395 //--------------------------------------------------------------------
    00396 bool  KnitroProblem::areDerivativesImplemented(const DerivativesImplementedType  nWhichDers){
    00397      if (nWhichDers == nCAN_COMPUTE_GA)
    00398         return( true );
    00399     if (nWhichDers == nCAN_COMPUTE_H)
    00400         return( true );
    00401     if (nWhichDers == nCAN_COMPUTE_HV)
    00402         return( false);
    00403     return( false );
    00404 }//areDerivativesImplemented
    00405
    00406
    00407 //--------------------------------------------------------------------
    00408 //  Method:  evalFC
    00409 //--------------------------------------------------------------------
    00410 int  KnitroProblem::evalFC (const double * const  daX,
    00411                          double * const  dObj,
    00412                          double * const  daC,
    00413                          void   *        userParams){
    00414         try{
    00415                 *dObj  = osinstance->calculateAllObjectiveFunctionValues((double*)daX, NULL, NULL, true, 0 )[0];
    00416         }
    00417         catch(const ErrorClass& eclass){
    00418                 knitroErrorMsg = eclass.errormsg;
    00419                 return (-1);
    00420         }
    00421         if( CommonUtil::ISOSNAN( *dObj )) return (-1);
    00422
    00423
    00424
    00425         try{
    00426                 double *conVals = osinstance->calculateAllConstraintFunctionValues((double*)daX, NULL, NULL, true, 0 );
    00427                 int i;
    00428                 for(i = 0; i < _nM; i++){
    00429                         if( CommonUtil::ISOSNAN( (double)conVals[ i] ) ) return (-1);
    00430                         daC[i] = conVals[ i]  ;
    00431                 }
    00432         }
    00433         catch(const ErrorClass& eclass){
    00434                 knitroErrorMsg = eclass.errormsg;
    00435                 return (-1);
    00436         }
    00437
    00438
    00439     return( 0 );
    00440 }//evalFC
    00441
    00442
    00443 //--------------------------------------------------------------------
    00444 //  Method:  evalGA
    00445 //--------------------------------------------------------------------
    00446 int  KnitroProblem::evalGA (const double * const  daX,
    00447                          double * const  daG,
    00448                          double * const  daJ,
    00449                          void   *        userParams){
    00450         try{
    00451                 double *objGrad = osinstance->calculateAllObjectiveFunctionGradients((double*)daX, NULL, NULL, true, 1 )[0];
    00452                 int i;
    00453                 std::cout << "EVALUATING OBJ GRADIENT" << std::endl;
    00454                 for(i = 0; i < _nN; i++){
    00455                         if( CommonUtil::ISOSNAN( (double)objGrad[ i] ) ) return (-1);
    00456                         daG[i] = objGrad[ i]  ;
    00457                 }
    00458         }
    00459         catch(const ErrorClass& eclass){
    00460                 knitroErrorMsg = eclass.errormsg;
    00461                 return (-1);
    00462         }
    00463
    00464         SparseJacobianMatrix *sparseJacobian;
    00465         std::cout << "EVALUATING JACOBIAN" << std::endl;
    00466         try{
    00467                 sparseJacobian = osinstance->calculateAllConstraintFunctionGradients((double*)daX, NULL, NULL,  true, 1);
    00468         }
    00469         catch(const ErrorClass& eclass){
    00470                 knitroErrorMsg = eclass.errormsg;
    00471                 return (-1);
    00472         }
    00473         //osinstance->getIterateResults( (double*)x, 0.0, NULL, -1, true,  1);
    00474         for(int i = 0; i < _nNnzJ; i++){
    00475                 daJ[ i] = sparseJacobian->values[i];
    00476                 //daJ[ i] = osinstance->m_mdJacValue[ i];
    00477                 cout << "daJ[i]:!!!!!!!!!!!!  " <<  daJ[ i] << endl;
    00478                 //cout << "m_mdJacValue[ i]:!!!!!!!!!!!!  " <<  osinstance->m_mdJacValue[ i] << endl;
    00479         }
    00480
    00481     return( 0 );
    00482 }//evalGA
    00483
    00484
    00485 //--------------------------------------------------------------------
    00486 //  Method:  evalH
    00487 //--------------------------------------------------------------------
    00488 int  KnitroProblem::evalH (const double * const  daX,
    00489                   const double * const  daLambda,
    00490                         double * const  daH,
    00491                         void   *        userParams){
    00492         SparseHessianMatrix *sparseHessian;
    00493         int i;
    00494         double* objMultipliers = new double[1];
    00495         objMultipliers[0] = 1;
    00496         try{
    00497                 sparseHessian = osinstance->calculateLagrangianHessian((double*)daX, objMultipliers, (double*)daLambda ,  true, 2);
    00498         }
    00499         catch(const ErrorClass& eclass){
    00500                 knitroErrorMsg = eclass.errormsg;
    00501                 return (-1);
    00502         }
    00503         for(i = 0; i < _nNnzH; i++){
    00504                 daH[ i]  = *(sparseHessian->hessValues + i);
    00505                 std::cout << "Hessian Value = " << daH[ i] << std::endl;
    00506         }
    00507         delete[] objMultipliers;
    00508     return( 0 );
    00509 }//evalH
    00510
    00511
    00512 //--------------------------------------------------------------------
    00513 //  Method:  evalHV
    00514 //--------------------------------------------------------------------
    00515 int  KnitroProblem::evalHV (const double * const  daX,
    00516                    const double * const  daLambda,
    00517                          double * const  daHV,
    00518                          void   *        userParams){
    00519
    00520     return( 0 );
    00521 }//evalHV
    00522
    00523 //OS specific default solver methods
    00524
    00525
    00526 KnitroSolver::KnitroSolver() {
    00527         osrlwriter = new OSrLWriter();
    00528         osresult = new OSResult();
    00529         knitroErrorMsg = "";
    00530
    00531 }
    00532
    00533
    00534 void KnitroSolver::buildSolverInstance() throw (ErrorClass) {
    00535         try{
    00536
    00537         }
    00538         catch(const ErrorClass& eclass){
    00539                 std::cout << "THERE IS AN ERROR" << std::endl;
    00540                 osresult->setGeneralMessage( eclass.errormsg);
    00541                 osresult->setGeneralStatusType( "error");
    00542                 osrl = osrlwriter->writeOSrL( osresult);
    00543                 throw ErrorClass( osrl) ;
    00544         }
    00545 }//end buildSolverInstance()
    00546
    00547
    00548
    00549
    00550 void Knitro::setSolverOptions() throw (ErrorClass) {
    00551         try{
    00552
    00553         }
    00554         catch(const ErrorClass& eclass){
    00555                 std::cout << "THERE IS AN ERROR" << std::endl;
    00556                 osresult->setGeneralMessage( eclass.errormsg);
    00557                 osresult->setGeneralStatusType( "error");
    00558                 osrl = osrlwriter->writeOSrL( osresult);
    00559                 throw ErrorClass( osrl) ;
    00560         }
    00561 }//end setSolverOptions()
    00562
    00563 KnitroSolver::~KnitroSolver() {
    00564         #ifdef DEBUG
    00565         cout << "inside KnitroSolver destructor" << endl;
    00566         #endif
    00567         delete osresult;
    00568         osresult = NULL;
    00569         delete osrlwriter;
    00570         osrlwriter = NULL;
    00571         //delete osinstance;
    00572         //osinstance = NULL;
    00573         #ifdef DEBUG
    00574         cout << "leaving KnitroSolver destructor" << endl;
    00575         #endif
    00576 }
    00577
    00578 void KnitroSolver::solve() throw (ErrorClass) {
    00579         try{
    00580                 OSiLReader* osilreader = NULL;
    00581                 //osresult = new OSResult();
    00582                 if(osil.length() == 0 && osinstance == NULL) throw ErrorClass("there is no instance");
    00583                 clock_t start, finish;
    00584                 double duration;
    00585                 start = clock();
    00586                 bool newOSiLReader = false;
    00587                 if( osinstance == NULL){
    00588                         osilreader = new OSiLReader();
    00589                         osinstance = osilreader->readOSiL( osil);
    00590                         newOSiLReader = true;
    00591                 }
    00592                 OSiLWriter osilwriter;
    00593                 //cout << osilwriter.writeOSiL( osinstance) << endl;
    00594                 if(osinstance->getVariableNumber() <= 0)throw ErrorClass("Knitro requires decision variables");
    00595                 finish = clock();
    00596                 duration = (double) (finish - start) / CLOCKS_PER_SEC;
    00597                 cout << "Parsing took (seconds): "<< duration << endl;
    00598                 //dataEchoCheck();
    00599
    00600                 /***************now the Knitro invokation*********************/
    00601                 // Create a new instance of your nlp
    00602                 NlpProblemDef *pOptProb = new KnitroProblem(osinstance, osresult);
    00603                 bool bWantToSolve;
    00604
    00605                 //---- OPEN A NEW INSTANCE OF KNITRO.
    00606                 KTR_context  *kc;
    00607                 kc = KTR_new();
    00608                 if (kc == NULL){
    00609                         cout << "*** KTR_new failed, maybe a license issue?\n";
    00610                         exit( EXIT_FAILURE );
    00611         }
    00612
    00613                 //---- APPLY ANY USER OPTIONS (PROCEED EVEN IF THERE IS AN ERROR).
    00614                 KTR_load_param_file (kc, "knitro.opt");
    00615                 //---- LOAD THE PROBLEM INTO KNITRO.
    00616                 if (pOptProb->loadProblemIntoKnitro ( kc) == false){
    00617                         cout << "*** loadProblemIntoKnitro failed\n";
    00618                         exit( EXIT_FAILURE );
    00619         }
    00620
    00621                 //---- SET CALLBACK POINTERS FOR EVALUATION OF PROBLEM INFORMATION.
    00622                 //---- IF THE TEST CODE DOES NOT SUPPLY DERIVATIVES, THEN THE
    00623                 //---- USER OPTIONS IN "knitro.opt" SHOULD REQUEST AN ALTERNATIVE,
    00624                 //---- SUCH AS FINITE DIFFERENCES.
    00625             g_pOptProblem = pOptProb;
    00626                 if (KTR_set_func_callback (kc, wrapperEvalFC) != 0){
    00627                         cout << "*** KTR_set_func_callback failed\n";
    00628                         exit( EXIT_FAILURE );
    00629                 }
    00630                 if (pOptProb->areDerivativesImplemented (nCAN_COMPUTE_GA) == true){
    00631                         if (KTR_set_grad_callback (kc, wrapperEvalGA) != 0){
    00632                                 cout << "*** KTR_set_grad_callback failed\n";
    00633                                 exit( EXIT_FAILURE );
    00634                         }
    00635         }
    00636             if ((pOptProb->areDerivativesImplemented (nCAN_COMPUTE_H) == true)
    00637                         || (pOptProb->areDerivativesImplemented (nCAN_COMPUTE_HV) == true)){
    00638                         if (KTR_set_hess_callback (kc, wrapperEvalHorHV) != 0){
    00639             cout << "*** KTR_set_hess_callback failed\n";
    00640             exit( EXIT_FAILURE );
    00641             }
    00642         }
    00643
    00644                 //---- ALLOCATE ARRAYS
    00645                 double *  daX      = new double[pOptProb->getN()];
    00646                 double *  daLambda = new double[pOptProb->getM() + pOptProb->getN()];
    00647                 double* mdObjValues = new double[1];
    00648                 bWantToSolve = true;
    00649                 if (bWantToSolve == true){
    00650                         //---- CALL KNITRO AND SOLVE.
    00651                         double  dFinalObj;
    00652                         int  nStatus = KTR_solve (kc, daX, daLambda, 0, &dFinalObj,
    00653                                                                         NULL, NULL, NULL, NULL, NULL, NULL);
    00654                         std::cout << "dFinalObj =  " << dFinalObj << std::endl;
    00655                         cout << "*** Final KNITRO status = " << nStatus << "\n";
    00656                         cout << "dax[0] = " << daX[0] << "\n";
    00657
    00658                         //construct osresult
    00659                         int solIdx = 0;
    00660
    00661                         std::string message = "Knitro solver finishes to the end.";
    00662                         std::string solutionDescription = "";
    00663
    00664                         // resultHeader infomration
    00665                         if(osresult->setServiceName( "Knitro solver service") != true)
    00666                                 throw ErrorClass("OSResult error: setServiceName");
    00667                         if(osresult->setInstanceName(  osinstance->getInstanceName()) != true)
    00668                                 throw ErrorClass("OSResult error: setInstanceName");
    00669
    00670                         //if(osresult->setJobID( osoption->jobID) != true)
    00671                         //      throw ErrorClass("OSResult error: setJobID");
    00672
    00673                         // set basic problem parameters
    00674                         if(osresult->setVariableNumber( osinstance->getVariableNumber()) != true)
    00675                                 throw ErrorClass("OSResult error: setVariableNumer");
    00676                         if(osresult->setObjectiveNumber( 1) != true)
    00677                                 throw ErrorClass("OSResult error: setObjectiveNumber");
    00678                         if(osresult->setConstraintNumber( osinstance->getConstraintNumber()) != true)
    00679                                 throw ErrorClass("OSResult error: setConstraintNumber");
    00680                         if(osresult->setSolutionNumber(  1) != true)
    00681                                 throw ErrorClass("OSResult error: setSolutionNumer");
    00682
    00683
    00684                         if(osresult->setGeneralMessage( message) != true)
    00685                                 throw ErrorClass("OSResult error: setGeneralMessage");
    00686                 std::cout << "START CASES  " << 0 << endl;
    00687                         switch( nStatus){
    00688                                 case 0:
    00689                                         std::cout << "WE ARE IN CASE " << 0 << endl;
    00690                                         solutionDescription = "LOCALLY OPTIMAL SOLUTION FOUND[KNITRO STATUS 0]: Knitro found a locally optimal point which satisfies the stopping criterion.If the problem is convex (for example, a linear program), then this point corresponds to a globally optimal solution.";
    00691                                         osresult->setSolutionStatus(solIdx,  "locallyOptimal", solutionDescription);
    00692                                         std::cout << "SET SOLUTION STATUS " << endl;
    00693                                         osresult->setPrimalVariableValuesDense(solIdx, daX);
    00694                                         std::cout << "SET PRIMAL VALUES " << endl;
    00695                                         osresult->setDualVariableValuesDense(solIdx, daLambda);
    00696                                         mdObjValues[0] = dFinalObj;
    00697                                         osresult->setObjectiveValuesDense(solIdx, mdObjValues);
    00698                                         std::cout << "SET OBJECTIVE VALUES " << endl;
    00699                                 break;
    00700                                 case -1:
    00701                                         solutionDescription = "Iteration limit reached[KNITRO STATUS -1]: The iteration limit was reached before being able to satisfy the required stopping criteria.";
    00702                                         osresult->setSolutionStatus(solIdx,  "stoppedByLimit", solutionDescription);
    00703                                         osresult->setPrimalVariableValuesDense(solIdx, daX);
    00704                                         osresult->setDualVariableValuesDense(solIdx, daLambda);
    00705                                         mdObjValues[0] = dFinalObj;
    00706                                         osresult->setObjectiveValuesDense(solIdx, mdObjValues);
    00707                                 break;
    00708                                 case -2:
    00709                                         solutionDescription = "Convergence to an infeasible point[KNITRO STATUS -2]: Problem may be locally infeasible.The algorithm has converged to an infeasible point from which it cannot further decrease the infeasibility measure. This happens when the problem is infeasible, but may also occur on occasion for feasible problems with nonlinear constraints or badly scaled problems. It is recommended to try various initial points. If this occurs for a variety of initial points, it is likely the problem is infeasible.";
    00710                                         osresult->setSolutionStatus(solIdx,  "infeasible", solutionDescription);
    00711                                 break;
    00712                                 case -3:
    00713                                         solutionDescription = "Problem appears to be unbounded[KNITRO STATUS -3]: Iterate is feasible and objective magnitude > objrange. The objective function appears to be decreasing without bound, while satisfying the constraints.If the problem really is bounded, increase the size of the parameter objrange to avoid terminating with this message.";
    00714                                         osresult->setSolutionStatus(solIdx,  "unbounded", solutionDescription);
    00715                                 break;
    00716                                 case -4:
    00717                                         solutionDescription = "Relative change in solution estimate < xtol[KNITRO STATUS -4]: The relative change in the solution estimate is less than that specified by the paramater xtol.To try to get more accuracy one may decrease xtol. If xtol is very small already, it is an indication that no more significant progress can be made. If the current point is feasible, it is possible it may be optimal, however the stopping tests cannot be satisfied (perhaps because of degeneracy, ill-conditioning or bad scaling).";
    00718                                         osresult->setSolutionStatus(solIdx,  "stoppedByLimit", solutionDescription);
    00719                                         osresult->setPrimalVariableValuesDense(solIdx, daX);
    00720                                         osresult->setDualVariableValuesDense(solIdx, daLambda);
    00721                                         mdObjValues[0] = dFinalObj;
    00722                                         osresult->setObjectiveValuesDense(solIdx, mdObjValues);
    00723                                 break;
    00724                                 case -5:
    00725                                         solutionDescription = "Current solution estimate cannot be improved. Point appears to be optimal, but desired accuracy could not be achieved.[KNITRO  STATUS -5]: No more progress can be made, but the stopping tests are close to being satisfied (within a factor of 100) and so the current approximate solution is believed to be optimal.";
    00726                                         osresult->setSolutionStatus(solIdx,  "locallyOptimal", solutionDescription);
    00727                                         osresult->setPrimalVariableValuesDense(solIdx, daX);
    00728                                         osresult->setDualVariableValuesDense(solIdx, daLambda);
    00729                                         mdObjValues[0] = dFinalObj;
    00730                                         osresult->setObjectiveValuesDense(solIdx, mdObjValues);
    00731                                 break;
    00732                                 case -6:
    00733                                         solutionDescription = "Time limit reached[KNITRO STATUS -6]: The time limit was reached before being able to satisfy the required stopping criteria.";
    00734                                         osresult->setSolutionStatus(solIdx,  "stoppedByLimit", solutionDescription);
    00735                                         osresult->setPrimalVariableValuesDense(solIdx, daX);
    00736                                         osresult->setDualVariableValuesDense(solIdx, daLambda);
    00737                                         mdObjValues[0] = dFinalObj;
    00738                                         osresult->setObjectiveValuesDense(solIdx, mdObjValues);
    00739                                 break;
    00740                                 case -50:
    00741                                 case -51:
    00742                                 case -52:
    00743                                 case -53:
    00744                                 case -54:
    00745                                 case -55:
    00746                                 case -56:
    00747                                 case -57:
    00748                                 case -58:
    00749                                 case -59:
    00750                                 case -60:
    00751                                         solutionDescription = "Input Error[KNITRO STATUS -50 to -60]: Termination values in this range imply some input error. If outlev>0 details of this error will be printed to standard output or the file knitro.log depending on the value of outmode.";
    00752                                         osresult->setSolutionStatus(solIdx,  "error", solutionDescription);
    00753                                 break;
    00754                                 case -90:
    00755                                         solutionDescription = "Callback function error[KNITRO STATUS -90]: This termination value indicates that an error (i.e., negative return value) occurred in a user provided callback routine.";
    00756                                         osresult->setSolutionStatus(solIdx,  "error", solutionDescription);
    00757                                 break;
    00758                                 case -97:
    00759                                         solutionDescription = "LP solver error[KNITRO STATUS -97]: This termination value indicates that an unrecoverable error occurred in the LP solver used in the active-set algorithm preventing the optimization from continuing.";
    00760                                         osresult->setSolutionStatus(solIdx,  "error", solutionDescription);
    00761                                 break;
    00762                                 case -98:
    00763                                         solutionDescription = "Evaluation error[KNITRO STATUS -98]: This termination value indicates that an evaluation error occurred (e.g., divide by 0, taking the square root of a negative number), preventing the optimization from continuing.";
    00764                                         osresult->setSolutionStatus(solIdx,  "error", solutionDescription);
    00765                                 break;
    00766                                 case -99:
    00767                                         solutionDescription = "Not enough memory available to solve problem[KNITRO STATUS -99]: This termination value indicates that there was not enough memory available to solve the problem.";
    00768                                         osresult->setSolutionStatus(solIdx,  "error", solutionDescription);
    00769                                 break;
    00770                                 default:
    00771                                         solutionDescription = "OTHER[KNITRO]: other unknown solution status from Knitro solver";
    00772                                         osresult->setSolutionStatus(solIdx,  "other", solutionDescription);
    00773                         }
    00774
    00775                         osresult->setGeneralStatusType("normal");
    00776                         osrl = osrlwriter->writeOSrL( osresult);
    00777                 }
    00778                 else{
    00779                         //---- USE KNITRO TO CHECK THE DERIVATIVES CODED IN THE TEST PROBLEM.
    00780                         pOptProb->getInitialX (daX);
    00781                         KTR_check_first_ders (kc, daX, 2, 1.0e-14, 1.0e-14,
    00782                                                                 0, 0.0, NULL, NULL, NULL, NULL);
    00783                 }
    00784
    00785                 if(newOSiLReader == true){
    00786                         delete osilreader;
    00787                         osilreader = NULL;
    00788                 }
    00789                 delete [] daX;
    00790                 delete [] daLambda;
    00791                 delete [] mdObjValues;
    00792
    00793                 KTR_free( &kc);
    00794                 delete pOptProb;
    00795
    00796
    00797                 //return( EXIT_SUCCESS );       //to do
    00798         }
    00799         catch(const ErrorClass& eclass){
    00800                 osresult->setGeneralMessage( eclass.errormsg);
    00801                 osresult->setGeneralStatusType( "error");
    00802                 osrl = osrlwriter->writeOSrL( osresult);
    00803                 //throw ErrorClass( osrl) ; //to do
    00804         }
    00805 }//solve
    00806
    00807
    00808 void KnitroSolver::dataEchoCheck(){
    00809
    00810         int i;
    00811
    00812         // print out problem parameters
    00813         cout << "This is problem:  " << osinstance->getInstanceName() << endl;
    00814         cout << "The problem source is:  " << osinstance->getInstanceSource() << endl;
    00815         cout << "The problem description is:  " << osinstance->getInstanceDescription() << endl;
    00816         cout << "number of variables = " << osinstance->getVariableNumber() << endl;
    00817         cout << "number of Rows = " << osinstance->getConstraintNumber() << endl;
    00818
    00819         // print out the variable information
    00820         if(osinstance->getVariableNumber() > 0){
    00821                 for(i = 0; i < osinstance->getVariableNumber(); i++){
    00822                         if(osinstance->getVariableNames() != NULL) cout << "variable Names  " << osinstance->getVariableNames()[ i]  << endl;
    00823                         if(osinstance->getVariableTypes() != NULL) cout << "variable Types  " << osinstance->getVariableTypes()[ i]  << endl;
    00824                         if(osinstance->getVariableLowerBounds() != NULL) cout << "variable Lower Bounds  " << osinstance->getVariableLowerBounds()[ i]  << endl;
    00825                         if(osinstance->getVariableUpperBounds() != NULL) cout << "variable Upper Bounds  " <<  osinstance->getVariableUpperBounds()[i] << endl;
    00826                 }
    00827         }
    00828
    00829         // print out objective function information
    00830         if(osinstance->getVariableNumber() > 0 || osinstance->instanceData->objectives->obj != NULL || osinstance->instanceData->objectives->numberOfObjectives > 0){
    00831                 if( osinstance->getObjectiveMaxOrMins()[0] == "min")  cout <<  "problem is a minimization" << endl;
    00832                 else cout <<  "problem is a maximization" << endl;
    00833                 for(i = 0; i < osinstance->getVariableNumber(); i++){
    00834                         cout << "OBJ COEFFICIENT =  " <<  osinstance->getDenseObjectiveCoefficients()[0][i] << endl;
    00835                 }
    00836         }
    00837         // print out constraint information
    00838         if(osinstance->getConstraintNumber() > 0){
    00839                 for(i = 0; i < osinstance->getConstraintNumber(); i++){
    00840                         if(osinstance->getConstraintNames() != NULL) cout << "row name = " << osinstance->getConstraintNames()[i] <<  endl;
    00841                         if(osinstance->getConstraintLowerBounds() != NULL) cout << "row lower bound = " << osinstance->getConstraintLowerBounds()[i] <<  endl;
    00842                         if(osinstance->getConstraintUpperBounds() != NULL) cout << "row upper bound = " << osinstance->getConstraintUpperBounds()[i] <<  endl;
    00843                 }
    00844         }
    00845
    00846         // print out linear constraint data
    00847         cout << endl;
    00848         cout << "number of nonzeros =  " << osinstance->getLinearConstraintCoefficientNumber() << endl;
    00849         for(i = 0; i <= osinstance->getVariableNumber(); i++){
    00850                 cout << "Start Value =  " << osinstance->getLinearConstraintCoefficientsInColumnMajor()->starts[ i] << endl;
    00851         }
    00852         cout << endl;
    00853         for(i = 0; i < osinstance->getLinearConstraintCoefficientNumber(); i++){
    00854                 cout << "Index Value =  " << osinstance->getLinearConstraintCoefficientsInColumnMajor()->indexes[i] << endl;
    00855                 cout << "Nonzero Value =  " << osinstance->getLinearConstraintCoefficientsInColumnMajor()->values[i] << endl;
    00856         }
    00857
    00858         // print out quadratic data
    00859         cout << "number of qterms =  " <<  osinstance->getNumberOfQuadraticTerms() << endl;
    00860         for(int i = 0; i <  osinstance->getNumberOfQuadraticTerms(); i++){
    00861                 cout << "Row Index = " <<  osinstance->getQuadraticTerms()->rowIndexes[i] << endl;
    00862                 cout << "Var Index 1 = " << osinstance->getQuadraticTerms()->varOneIndexes[ i] << endl;
    00863                 cout << "Var Index 2 = " << osinstance->getQuadraticTerms()->varTwoIndexes[ i] << endl;
    00864                 cout << "Coefficient = " << osinstance->getQuadraticTerms()->coefficients[ i] << endl;
    00865         }
    00866 } // end dataEchoCheck
    00867
    00868
    00869 NlpProblemDef::~NlpProblemDef (void)
    00870 {
    00871     //---- DO NOTHING.
    00872    //return;
    00873   }
    00874
    00875
    00876
    00877