Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members

OsiXprSolverInterface.cpp

00001 // copyright (C) 2000, International Business Machines
00002 // Corporation and others.  All Rights Reserved.
00003 
00004 #if defined(_MSC_VER)
00005 // Turn off compiler warning about long names
00006 #  pragma warning(disable:4786)
00007 #endif
00008 
00009 #include <cassert>
00010 #include <numeric>
00011 #include <strstream>
00012 
00013 #ifdef _WIN32
00014 #define DLL
00015 #endif
00016 
00017 #define __ANSIC_
00018 #include <xpresso.h>
00019 #undef  __ANSIC_
00020 
00021 #include "OsiXprSolverInterface.hpp"
00022 
00023 // xpresso.h is redefining range in away that
00024 // is in conflict with other usages
00025 #define rangeTemp range
00026 #undef range
00027 #include "CoinHelperFunctions.hpp"
00028 #include "OsiCuts.hpp"
00029 #include "OsiColCut.hpp"
00030 #include "CoinPackedMatrix.hpp"
00031 #include "OsiRowCut.hpp"
00032 #include "CoinWarmStartBasis.hpp"
00033 
00034 // Let Xpress have its own definition of range again
00035 #define range rangeTemp
00036 
00037 //#############################################################################
00038 // Solve methods
00039 //#############################################################################
00040 
00041 void
00042 OsiXprSolverInterface::initialSolve(){
00043    activateMe();
00044 
00045    freeSolution();
00046 
00047    if ( objsense_ == 1.0 ) {
00048      if (getLogFilePtr()!=NULL) {
00049        fprintf(getLogFilePtr(),"minim(\"l\");\n");
00050      }
00051       minim("l");
00052    }
00053    else if ( objsense_ == -1.0 ) {
00054      if (getLogFilePtr()!=NULL) {
00055        fprintf(getLogFilePtr(),"maxim(\"l\");\n");
00056      }
00057       maxim("l");
00058    }
00059 }
00060 
00061 //-----------------------------------------------------------------------------
00062 
00063 void
00064 OsiXprSolverInterface::resolve(){
00065    activateMe();
00066 
00067    freeSolution();
00068 
00069    if ( objsense_ == 1.0 ) {
00070      if (getLogFilePtr()!=NULL) {
00071        fprintf(getLogFilePtr(),"minim(\"dl\");\n");
00072      }
00073       minim("dl");
00074    }
00075    else if ( objsense_ == -1.0 ) {
00076      if (getLogFilePtr()!=NULL) {
00077        fprintf(getLogFilePtr(),"maxim(\"dl\");\n");
00078      }
00079       maxim("dl");
00080    }
00081 }
00082 
00083 //-----------------------------------------------------------------------------
00084 
00085 void
00086 OsiXprSolverInterface::branchAndBound(){
00087   activateMe();
00088   
00089   freeSolution();
00090 
00091   if (getLogFilePtr()!=NULL) {
00092     fprintf(getLogFilePtr(),"global;\n");
00093   }
00094   global();
00095 }
00096 
00097 //#############################################################################
00098 // Parameter related methods
00099 //#############################################################################
00100 
00101 bool
00102 OsiXprSolverInterface::setIntParam(OsiIntParam key, int value)
00103 {
00104   bool retval = false;
00105   
00106   switch (key) {
00107   case OsiMaxNumIteration:
00108     retval = seticv(N_ITRLIM, value) == 0;
00109     break;
00110   case OsiMaxNumIterationHotStart:
00111     retval = false;
00112     break;
00113   case OsiLastIntParam:
00114     retval = false;
00115     break;
00116   }
00117   return retval;
00118 }
00119 
00120 //-----------------------------------------------------------------------------
00121 
00122 bool
00123 OsiXprSolverInterface::setDblParam(OsiDblParam key, double value)
00124 {
00125   bool retval = false;
00126   switch (key) {
00127   case OsiDualObjectiveLimit:
00128     retval = setdcv(N_CUTOFF, value) == 0;
00129     break;
00130   case OsiPrimalObjectiveLimit:
00131     retval = false;     
00132     break;
00133   case OsiDualTolerance:
00134     retval = false;     
00135     break;
00136   case OsiPrimalTolerance:
00137     retval = false;     
00138     break;
00139   case OsiObjOffset: 
00140     return OsiSolverInterface::setDblParam(key, value);
00141   case OsiLastDblParam:
00142     retval = false;
00143     break;
00144   }
00145   return retval;
00146 }
00147 //-----------------------------------------------------------------------------
00148 
00149 bool
00150 OsiXprSolverInterface::setStrParam(OsiStrParam key, const std::string & value)
00151 {
00152   bool retval=false;
00153   switch (key) {
00154 
00155   case OsiProbName:
00156     OsiSolverInterface::setStrParam(key,value);
00157     return retval = true;
00158 
00159   case OsiLastStrParam:
00160     return false;
00161   }
00162   return false;
00163 }
00164 //-----------------------------------------------------------------------------
00165 
00166 bool
00167 OsiXprSolverInterface::getIntParam(OsiIntParam key, int& value) const
00168 {
00169   bool retval = false;
00170 
00171   switch (key) {
00172   case OsiMaxNumIteration:
00173     retval = geticv(N_ITRLIM, &value)==1 ? true : false;
00174     break;
00175   case OsiMaxNumIterationHotStart:
00176     retval = false;
00177     break;
00178   case OsiLastIntParam:
00179     retval = false;
00180     break;
00181   }
00182   return retval;
00183 }
00184 
00185 //-----------------------------------------------------------------------------
00186 
00187 bool
00188 OsiXprSolverInterface::getDblParam(OsiDblParam key, double& value) const
00189 {
00190   bool retval = false;
00191 
00192   switch (key) {
00193   case OsiDualObjectiveLimit:
00194     retval = getdcv(N_CUTOFF, &value)==1 ? true : false;
00195     break;
00196   case OsiPrimalObjectiveLimit:
00197     retval = false;
00198     break;
00199   case OsiDualTolerance:
00200     retval = false;
00201     break;
00202   case OsiPrimalTolerance:
00203     retval = false;
00204     break;
00205   case OsiObjOffset:
00206     retval = OsiSolverInterface::getDblParam(key, value);
00207     break;
00208   case OsiLastDblParam:
00209     retval = false;
00210     break;
00211   }
00212   return retval;
00213 }
00214 
00215 //-----------------------------------------------------------------------------
00216 
00217 bool
00218 OsiXprSolverInterface::getStrParam(OsiStrParam key, std::string & value) const
00219 {
00220   bool retval = false;
00221   switch (key) {
00222   case OsiProbName:
00223     OsiSolverInterface::getStrParam(key, value);
00224     retval = true;
00225     break;
00226   case OsiSolverName:
00227     value = "xpress";
00228     retval = true;
00229     break;
00230   case OsiLastStrParam:
00231     retval = false;
00232   }
00233   return retval;
00234 }
00235 //#############################################################################
00236 // Methods returning info on how the solution process terminated
00237 //#############################################################################
00238 
00239 bool OsiXprSolverInterface::isAbandoned() const
00240 {
00241   activateMe();
00242 
00243   int  status, glstat;
00244 
00245   getipv(N_STATUS, &status);
00246   getipv(N_GLSTAT, &glstat);
00247 
00248   return status == 4 || glstat == 3 || glstat == 4;
00249   // LP unfinished || global search incomplete -- no int sol ||
00250   // global search incomplete -- int sol found
00251 }
00252 
00253 bool OsiXprSolverInterface::isProvenOptimal() const
00254 {
00255   activateMe();
00256 
00257   int  status, glstat;
00258 
00259   getipv(N_STATUS, &status);
00260   getipv(N_GLSTAT, &glstat);
00261 
00262   return status == 1 || status == 3 || glstat == 6;
00263   // LP optimal || LP obj worse than cutoff || 
00264   // global search complete -- int found
00265 }
00266 
00267 bool OsiXprSolverInterface::isProvenPrimalInfeasible() const
00268 {
00269   activateMe();
00270 
00271   int status;
00272 
00273   getipv(N_STATUS, &status);
00274 
00275   return status == 2;           // LP infeasible
00276 }
00277 
00278 bool OsiXprSolverInterface::isProvenDualInfeasible() const
00279 {
00280   activateMe();
00281 
00282   int status;
00283 
00284   getipv(N_STATUS, &status);
00285 
00286   return status == 5;           // LP Unbounded
00287 }
00288 
00289 bool OsiXprSolverInterface::isPrimalObjectiveLimitReached() const
00290 {
00291   activateMe();
00292 
00293   return false;                 // N/A in XOSL
00294 }
00295 
00296 bool OsiXprSolverInterface::isDualObjectiveLimitReached() const
00297 {
00298   activateMe();
00299 
00300   int status;
00301 
00302   getipv(N_STATUS, &status);
00303 
00304   return status == 6;           // LP cut off in dual
00305 }
00306 
00307 bool OsiXprSolverInterface::isIterationLimitReached() const
00308 {
00309   activateMe();
00310 
00311   int itrlim, itcnt;
00312 
00313   geticv(N_ITRLIM, &itrlim);
00314   getipv(N_ITCNT, &itcnt);
00315 
00316   return itcnt >= itrlim;
00317 }
00318 
00319 //#############################################################################
00320 // WarmStart related methods
00321 //#############################################################################
00322 
00323 CoinWarmStart* OsiXprSolverInterface::getWarmStart() const
00324 {
00325   activateMe();
00326 
00327   int pstat, retstat;
00328 
00329   getipv(N_PSTAT, &pstat);
00330   if ( pstat != 7 ) return NULL;
00331 
00332   CoinWarmStartBasis *ws = NULL;
00333   int numcols = getNumCols();
00334   int numrows = getNumRows();
00335   const double *lb = getColLower();
00336   double infty = getInfinity();
00337   int *rstatus = new int[numrows];
00338   int *cstatus = new int[numcols];
00339 
00340   retstat = getbasis(rstatus, cstatus);
00341 
00342   if ( retstat == 0 ) {
00343     int i;
00344 
00345     ws = new CoinWarmStartBasis;
00346     ws->setSize( numcols, numrows );
00347       
00348     for( i = 0;  i < numrows;  i++ ) {
00349       switch( rstatus[i] ) {
00350       case 0:
00351         ws->setArtifStatus(i, CoinWarmStartBasis::atLowerBound);
00352         break;
00353       case 1:
00354         ws->setArtifStatus(i, CoinWarmStartBasis::basic);
00355         break;
00356       case 2:
00357         ws->setArtifStatus(i, CoinWarmStartBasis::atUpperBound);
00358         break;
00359       default:  // unknown row status
00360         delete ws;
00361         ws = NULL;
00362         goto TERMINATE;
00363       }
00364     }
00365 
00366     for( i = 0;  i < numcols;  i++ ) {
00367       switch( cstatus[i] ) {
00368       case 0:
00369         if ( lb[i] <= -infty )
00370           ws->setStructStatus(i, CoinWarmStartBasis::isFree);
00371         else
00372           ws->setStructStatus(i, CoinWarmStartBasis::atLowerBound);
00373         break;
00374       case 1:
00375         ws->setStructStatus( i, CoinWarmStartBasis::basic );
00376         break;
00377       case 2:
00378         ws->setStructStatus( i, CoinWarmStartBasis::atUpperBound );
00379         break;
00380       default:  // unknown column status
00381         delete ws;
00382         ws = NULL;
00383         goto TERMINATE;
00384       }
00385     }
00386   }
00387 
00388  TERMINATE:
00389   delete[] cstatus;
00390   delete[] rstatus;
00391 
00392   return ws;
00393 }
00394 
00395 //-----------------------------------------------------------------------------
00396 
00397 bool OsiXprSolverInterface::setWarmStart(const CoinWarmStart* warmstart)
00398 {
00399   const CoinWarmStartBasis* ws = dynamic_cast<const CoinWarmStartBasis*>(warmstart);
00400 
00401   if ( !ws ) return false;
00402 
00403   activateMe();
00404 
00405   int numcols = ws->getNumStructural();
00406   int numrows = ws->getNumArtificial();
00407 
00408   if ( numcols != getNumCols() || numrows != getNumRows() )
00409     return false;
00410 
00411   bool retval;
00412   int retstat;
00413   int *cstatus = new int[numcols];
00414   int *rstatus = new int[numrows];
00415   int i;
00416 
00417   for ( i = 0;  i < numrows;  i++ ) {
00418     switch( ws->getArtifStatus(i) ) {
00419     case CoinWarmStartBasis::atLowerBound:
00420       rstatus[i] = 0;
00421       break;
00422     case CoinWarmStartBasis::basic:
00423       rstatus[i] = 1;
00424       break;
00425     case CoinWarmStartBasis::atUpperBound:
00426       rstatus[i] = 2;
00427       break;
00428     default:  // unknown row status
00429       retval = false;
00430       goto TERMINATE;
00431     }
00432   }
00433 
00434   for( i = 0;  i < numcols;  i++ ) {
00435     switch( ws->getStructStatus(i) ) {
00436     case CoinWarmStartBasis::atLowerBound: 
00437     case CoinWarmStartBasis::isFree:
00438       cstatus[i] = 0;
00439       break;
00440     case CoinWarmStartBasis::basic:
00441       cstatus[i] = 1;
00442       break;
00443     case CoinWarmStartBasis::atUpperBound:
00444       cstatus[i] = 2;
00445       break;
00446     default:  // unknown row status
00447       retval = false;
00448       goto TERMINATE;
00449     }
00450   }
00451 
00452   retstat = loadbasis(rstatus, cstatus);
00453   retval = (retstat == 0);
00454 
00455  TERMINATE:
00456   delete[] cstatus;
00457   delete[] rstatus;
00458   return retval;
00459   
00460 }
00461 
00462 //#############################################################################
00463 // Hotstart related methods (primarily used in strong branching)
00464 //#############################################################################
00465 
00466 void OsiXprSolverInterface::markHotStart()
00467 {
00468   // *FIXME* : do better... -LL
00469   OsiSolverInterface::markHotStart();
00470 }
00471 
00472 void OsiXprSolverInterface::solveFromHotStart()
00473 {
00474   // *FIXME* : do better... -LL
00475   OsiSolverInterface::solveFromHotStart();
00476 }
00477 
00478 void OsiXprSolverInterface::unmarkHotStart()
00479 {
00480   // *FIXME* : do better... -LL
00481   OsiSolverInterface::unmarkHotStart();
00482 }
00483 
00484 //#############################################################################
00485 // Problem information methods (original data)
00486 //#############################################################################
00487 
00488 //------------------------------------------------------------------
00489 // Get number of rows and columns
00490 //------------------------------------------------------------------
00491 int
00492 OsiXprSolverInterface::getNumCols() const
00493 {
00494   activateMe();
00495 
00496   if ( !isDataLoaded() ) return 0;
00497 
00498   if (getLogFilePtr()!=NULL) {
00499     fprintf(getLogFilePtr(),"{\n");
00500     fprintf(getLogFilePtr(),"  int ncols;\n");
00501     fprintf(getLogFilePtr(),"  getipv(N_NCOL,&ncols);\n");
00502     fprintf(getLogFilePtr(),"}\n");
00503   }
00504 
00505   int     ncols;
00506 
00507   getipv(N_NCOL, &ncols);
00508 
00509   return ncols;
00510 }
00511 //-----------------------------------------------------------------------------
00512 int
00513 OsiXprSolverInterface::getNumRows() const
00514 {
00515    activateMe();
00516 
00517    if ( !isDataLoaded() ) return 0;
00518 
00519    if (getLogFilePtr()!=NULL) {
00520     fprintf(getLogFilePtr(),"{\n");
00521     fprintf(getLogFilePtr(),"  int nrows;\n");
00522     fprintf(getLogFilePtr(),"  getipv(N_NROW,&nrows);\n");
00523     fprintf(getLogFilePtr(),"}\n");
00524   }
00525 
00526    int     nrows;
00527 
00528    getipv(N_NROW, &nrows);
00529 
00530    return nrows;
00531 }
00532 //-----------------------------------------------------------------------------
00533 int
00534 OsiXprSolverInterface::getNumElements() const
00535 {
00536    activateMe();
00537 
00538    if ( !isDataLoaded() ) return 0;
00539 
00540    if (getLogFilePtr()!=NULL) {
00541     fprintf(getLogFilePtr(),"{\n");
00542     fprintf(getLogFilePtr(),"  int nels;\n");
00543     fprintf(getLogFilePtr(),"  getipv(N_NELEM,&nels);\n");
00544     fprintf(getLogFilePtr(),"}\n");
00545   }
00546 
00547    int     retVal;
00548 
00549    getipv(N_NELEM, &retVal);
00550 
00551    return retVal;
00552 }
00553 
00554 //------------------------------------------------------------------
00555 // Get pointer to rim vectors
00556 //------------------------------------------------------------------  
00557 const double *
00558 OsiXprSolverInterface::getColLower() const
00559 {
00560    if ( collower_ == NULL ) {
00561       activateMe();
00562 
00563       if ( isDataLoaded() ) {
00564          int     ncols = getNumCols();
00565          
00566          if (getLogFilePtr()!=NULL) {
00567            fprintf(getLogFilePtr(),"{\n");
00568            fprintf(getLogFilePtr(),"  double * cl[%d];\n",ncols);
00569            fprintf(getLogFilePtr(),"  getbdl(cl,0,ncols-1);\n");
00570            fprintf(getLogFilePtr(),"}\n");
00571          }
00572 
00573          collower_ = new double[ncols];
00574          getbdl(collower_, 0, ncols - 1);
00575       }
00576    }
00577 
00578    return collower_;
00579 }
00580 //-----------------------------------------------------------------------------
00581 const double *
00582 OsiXprSolverInterface::getColUpper() const
00583 {
00584    if ( colupper_ == NULL ) {
00585       activateMe();
00586 
00587       if ( isDataLoaded() ) {
00588          int     ncols = getNumCols();   
00589          
00590          if (getLogFilePtr()!=NULL) {
00591            fprintf(getLogFilePtr(),"{\n");
00592            fprintf(getLogFilePtr(),"  double * cu[%d];\n",ncols);
00593            fprintf(getLogFilePtr(),"  getbdu(cu,0,ncols-1);\n");
00594            fprintf(getLogFilePtr(),"}\n");
00595          }
00596 
00597          colupper_ = new double[ncols];
00598          getbdu(colupper_, 0, ncols - 1);
00599       }
00600    }
00601 
00602    return colupper_;
00603 }
00604 //-----------------------------------------------------------------------------
00605 const char *
00606 OsiXprSolverInterface::getRowSense() const
00607 {
00608    if ( rowsense_ == NULL ) {
00609       activateMe();
00610 
00611       if ( isDataLoaded() ) {
00612          int     nrows = getNumRows();
00613        
00614         if (getLogFilePtr()!=NULL) {
00615           fprintf(getLogFilePtr(),"{\n");
00616           fprintf(getLogFilePtr(),"  char rowsense[%d];\n",nrows);
00617           fprintf(getLogFilePtr(),"  getrowtype(rowsense, 0, %d);\n",nrows-1);
00618           fprintf(getLogFilePtr(),"}\n");
00619         }
00620         rowsense_ = new char[nrows];
00621         getrowtype(rowsense_, 0, nrows - 1);
00622       }
00623    }
00624 
00625    return rowsense_;
00626 }
00627 //-----------------------------------------------------------------------------
00628 const double *
00629 OsiXprSolverInterface::getRightHandSide() const
00630 {
00631    if ( rhs_ == NULL ) {
00632       activateMe();
00633 
00634       if ( isDataLoaded() ) {
00635          int     nrows = getNumRows();  
00636          
00637         if (getLogFilePtr()!=NULL) {
00638           fprintf(getLogFilePtr(),"{\n");
00639           fprintf(getLogFilePtr(),"  double rhs[%d];\n",nrows);
00640           fprintf(getLogFilePtr(),"  getrhs(rhs, 0, %d);\n",nrows-1);
00641           fprintf(getLogFilePtr(),"}\n");
00642         }
00643 
00644          rhs_ = new double[nrows];
00645          getrhs(rhs_, 0, nrows - 1);
00646 
00647          // Make sure free rows have rhs of zero
00648          const char * rs = getRowSense();
00649          int nr = getNumRows();
00650          int i;
00651          for ( i = 0;  i < nr;  i++ ) {
00652            if ( rs[i] == 'N' ) rhs_[i]=0.0;
00653          }
00654       }
00655    }
00656 
00657    return rhs_;
00658 }
00659 //-----------------------------------------------------------------------------
00660 const double *
00661 OsiXprSolverInterface::getRowRange() const
00662 {
00663    if ( rowrange_ == NULL ) {
00664       activateMe();
00665 
00666       if ( isDataLoaded() ) {
00667          int     nrows = getNumRows();
00668 
00669         if (getLogFilePtr()!=NULL) {
00670           fprintf(getLogFilePtr(),"{\n");
00671           fprintf(getLogFilePtr(),"  double rowrange[%d];\n",nrows);
00672           fprintf(getLogFilePtr(),"  getrng(rowrange, 0, %d);\n",nrows-1);
00673           fprintf(getLogFilePtr(),"}\n");
00674         }
00675          rowrange_ = new double[nrows];
00676          getrng(rowrange_, 0, nrows - 1);
00677 
00678          // Make sure non-R rows have range of 0.0
00679          // XPRESS seems to set N and L rows to a range of Infinity
00680          const char * rs = getRowSense();
00681          int nr = getNumRows();
00682          int i;
00683          for ( i = 0;  i < nr;  i++ ) {
00684            if ( rs[i] != 'R' ) rowrange_[i] = 0.0;
00685          }
00686       }
00687    }
00688 
00689    return rowrange_;
00690 }
00691 //-----------------------------------------------------------------------------
00692 const double *
00693 OsiXprSolverInterface::getRowLower() const
00694 {
00695    if ( rowlower_ == NULL ) {
00696       int     nrows = getNumRows();
00697       const   char    *rowsense = getRowSense();
00698       const   double  *rhs      = getRightHandSide();
00699       const   double  *rowrange = getRowRange();
00700 
00701       if ( nrows > 0 ) {
00702          rowlower_ = new double[nrows];
00703 
00704          double dum1;
00705          for ( int i = 0;  i < nrows;  i++ ) {
00706            convertSenseToBound(rowsense[i], rhs[i], rowrange[i],
00707                                rowlower_[i], dum1);
00708          }
00709       }
00710    }
00711 
00712    return rowlower_;
00713 }
00714 //-----------------------------------------------------------------------------
00715 const double *
00716 OsiXprSolverInterface::getRowUpper() const
00717 {
00718    if ( rowupper_ == NULL ) {
00719       int     nrows = getNumRows();
00720       const   char    *rowsense = getRowSense();
00721       const   double  *rhs      = getRightHandSide();
00722       const   double  *rowrange = getRowRange();
00723 
00724       if ( nrows > 0 ) {
00725          rowupper_ = new double[nrows];
00726 
00727          double dum1;
00728          for ( int i = 0;  i < nrows;  i++ ) {
00729            convertSenseToBound(rowsense[i], rhs[i], rowrange[i],
00730                                dum1, rowupper_[i]);
00731          }
00732       }
00733    }
00734 
00735    return rowupper_;
00736 }
00737 //-----------------------------------------------------------------------------
00738 const double *
00739 OsiXprSolverInterface::getObjCoefficients() const
00740 {
00741    if ( objcoeffs_ == NULL ) {
00742       activateMe();
00743 
00744       if ( isDataLoaded() ) {
00745          int     ncols = getNumCols();
00746 
00747         if (getLogFilePtr()!=NULL) {
00748           fprintf(getLogFilePtr(),"{\n");
00749           fprintf(getLogFilePtr(),"  double objc[%d];\n",ncols);
00750           fprintf(getLogFilePtr(),"  getobj(objc,0,%d);\n",ncols);
00751           fprintf(getLogFilePtr(),"}\n");
00752         }
00753          objcoeffs_ = new double[ncols];
00754          getobj(objcoeffs_, 0, ncols - 1);
00755       }
00756    }
00757 
00758    return objcoeffs_;
00759 }
00760 //-----------------------------------------------------------------------------
00761 double
00762 OsiXprSolverInterface::getObjSense() const
00763 {
00764    return objsense_;
00765 }
00766 
00767 //-----------------------------------------------------------------------------
00768 // Return information on integrality
00769 //-----------------------------------------------------------------------------
00770 
00771 bool
00772 OsiXprSolverInterface::isContinuous(int colNumber) const
00773 {
00774    getVarTypes();
00775 
00776    //std::cerr <<"OsiXprSolverInterface::isContinuous " <<vartype_[colNumber] <<std::endl;
00777    if ( vartype_ == NULL ) return true;
00778    if ( vartype_[colNumber] == 'C' ) return true;
00779    return false;
00780 }
00781 //-----------------------------------------------------------------------------
00782 #if 0
00783 bool
00784 OsiXprSolverInterface::isInteger( int colNumber ) const
00785 {
00786    return !(isContinuous(colNumber));
00787 }
00788 //-----------------------------------------------------------------------------
00789 bool
00790 OsiXprSolverInterface::isBinary( int colNumber ) const
00791 {
00792    const double *cu = colupper();
00793    const double *cl = collower();
00794   
00795    getVarTypes();
00796 
00797    if ( vartype_ == NULL ) return false;
00798    return (vartype_[colNumber] == 'I' || vartype_[colNumber] == 'B') && 
00799       (cu[colNumber] == 0.0 || cu[colNumber] == 1.0) && 
00800       (cl[colNumber] == 0.0 || cl[colNumber] == 1.0);
00801 }
00802 //-----------------------------------------------------------------------------
00803 bool
00804 OsiXprSolverInterface::isIntegerNonBinary( int colNumber ) const
00805 {
00806    getVarTypes();
00807 
00808    if ( vartype_ == NULL ) return false;
00809    return (vartype_[colNumber] == 'I' || vartype_[colNumber] == 'B') &&
00810       !isBinary(colNumber);  
00811 }
00812 //-----------------------------------------------------------------------------
00813 bool
00814 OsiXprSolverInterface::isFreeBinary( int colNumber ) const
00815 {
00816    const   double  *colupper = this->colupper();
00817    const   double  *collower = this->collower();
00818 
00819    getVarTypes();
00820 
00821    return isBinary(colNumber) && colupper[colNumber] != collower[colNumber];
00822 }
00823 #endif
00824 
00825 //------------------------------------------------------------------
00826 // Row and column copies of the matrix ...
00827 //------------------------------------------------------------------
00828 
00829 const CoinPackedMatrix *
00830 OsiXprSolverInterface::getMatrixByRow() const
00831 {
00832   if ( matrixByRow_ == NULL ) {
00833     activateMe();
00834 
00835     if ( isDataLoaded() ) {
00836 
00837       int     nrows = getNumRows();
00838       int     ncols = getNumCols();
00839       int     nelems;
00840 
00841       getrows(NULL, NULL, NULL, 0, &nelems, 0, nrows - 1);
00842          
00843       if (getLogFilePtr()!=NULL) {
00844         fprintf(getLogFilePtr(),"{\n");
00845         fprintf(getLogFilePtr(),"   int start[%d];\n",nrows+1);
00846         fprintf(getLogFilePtr(),"   int length[%d];\n",nrows);
00847         fprintf(getLogFilePtr(),"   int index[%d];\n",nelems);
00848         fprintf(getLogFilePtr(),"   double element[%d];\n",nelems);
00849         fprintf(getLogFilePtr(),"   int nelems;\n");
00850         fprintf(getLogFilePtr(),"   getrows(NULL, NULL, NULL, 0, &nelems, 0, %d);\n",nrows-1);       
00851         fprintf(getLogFilePtr(),"   getrows(start, index, element, nelems, &nelems, 0, %d);\n",nrows-1);
00852         fprintf(getLogFilePtr(),"}\n");
00853       }
00854          
00855       int     *start   = new int   [nrows + 1];
00856       int     *length  = new int   [nrows];
00857       int     *index   = new int   [nelems];
00858       double  *element = new double[nelems];
00859 
00860       getrows(start, index, element, nelems, &nelems, 0, nrows - 1);
00861 
00862       std::adjacent_difference(start + 1, start + (nrows+1), length);
00863       
00864       matrixByRow_ = new CoinPackedMatrix();
00865       matrixByRow_->assignMatrix(false /* not column ordered */,
00866                                  ncols, nrows, nelems,
00867                                  element, index, start, length);
00868     } else {
00869       matrixByRow_ = new CoinPackedMatrix();
00870       matrixByRow_->reverseOrdering();
00871     }
00872   }
00873 
00874   return matrixByRow_;
00875 } 
00876 
00877 //-----------------------------------------------------------------------------
00878 const CoinPackedMatrix *
00879 OsiXprSolverInterface::getMatrixByCol() const
00880 {
00881    if ( matrixByCol_ == NULL ) {
00882       matrixByCol_ = new CoinPackedMatrix(*getMatrixByRow());
00883       matrixByCol_->reverseOrdering();
00884    }
00885 
00886    return matrixByCol_;
00887 }
00888 
00889 //------------------------------------------------------------------
00890 // Get solver's value for infinity
00891 //------------------------------------------------------------------
00892 double
00893 OsiXprSolverInterface::getInfinity() const
00894 {
00895    return DPLINF;
00896 }
00897 
00898 //#############################################################################
00899 // Problem information methods (results)
00900 //#############################################################################
00901 
00902 const double *
00903 OsiXprSolverInterface::getColSolution() const
00904 {
00905    if ( colsol_ == NULL ) {
00906       activateMe();
00907 
00908       if ( isDataLoaded() ) {
00909 
00910         int nc = getNumCols();
00911 
00912         if (getLogFilePtr()!=NULL) {
00913           fprintf(getLogFilePtr(),"{\n");
00914           fprintf(getLogFilePtr(),"  double colsol[%d];\n",nc);
00915           fprintf(getLogFilePtr(),"  solution(colsol, NULL, NULL, NULL);\n");
00916           fprintf(getLogFilePtr(),"}\n");
00917         }
00918 
00919          colsol_ = new double[nc];
00920          solution(colsol_, NULL, NULL, NULL);
00921       }
00922    }
00923 
00924    return colsol_;
00925 }
00926 
00927 //-----------------------------------------------------------------------------
00928 
00929 const double *
00930 OsiXprSolverInterface::getRowPrice() const
00931 {
00932    if ( rowprice_ == NULL ) {
00933       activateMe();
00934       int nr = getNumRows();
00935 
00936       if ( isDataLoaded() ) {
00937         if (getLogFilePtr()!=NULL) {
00938           fprintf(getLogFilePtr(),"{\n");
00939           fprintf(getLogFilePtr(),"  double rowprice[%d];\n",nr);
00940           fprintf(getLogFilePtr(),"  solution(NULL, NULL, rowprice, NULL);\n");
00941           fprintf(getLogFilePtr(),"}\n");
00942         }
00943          rowprice_ = new double[nr];
00944          solution(NULL, NULL, rowprice_, NULL);
00945       }
00946    }
00947    return rowprice_;
00948 }
00949 
00950 //-----------------------------------------------------------------------------
00951 
00952 const double * OsiXprSolverInterface::getReducedCost() const
00953 {
00954   if ( colprice_ == NULL ) {
00955     activateMe();
00956     int nc = getNumCols();
00957 
00958     if ( isDataLoaded() ) {
00959       if (getLogFilePtr()!=NULL) {
00960         fprintf(getLogFilePtr(),"{\n");
00961         fprintf(getLogFilePtr(),"  double rowprice[%d];\n",nc);
00962         fprintf(getLogFilePtr(),"  solution(NULL, NULL, NULL, colprice_);\n");
00963         fprintf(getLogFilePtr(),"}\n");
00964       }
00965       colprice_ = new double[nc];
00966       solution(NULL, NULL, NULL, colprice_);
00967     }
00968   }
00969   return colprice_;
00970 }
00971 
00972 //-----------------------------------------------------------------------------
00973 
00974 const double * OsiXprSolverInterface::getRowActivity() const
00975 {
00976   if( rowact_ == NULL ) {
00977     activateMe();
00978 
00979     if ( isDataLoaded() ) {
00980       int nrows = getNumRows();
00981       const double *rhs = getRightHandSide();
00982       if( nrows > 0 ) {
00983         int status;
00984 
00985         rowact_ = new double[nrows];
00986 
00987         getipv(N_PSTAT, &status);
00988 
00989         if ( status == 7 ) {
00990           int i;
00991 
00992           solution(NULL, rowact_, NULL, NULL);
00993 
00994           for ( i = 0;  i < nrows;  i++ )
00995             rowact_[i] = rhs[i] - rowact_[i];
00996         } else {
00997           CoinFillN(rowact_, nrows, 0.0);
00998         }
00999       }
01000     }
01001   }
01002   return rowact_;
01003 }
01004 
01005 //-----------------------------------------------------------------------------
01006 
01007 double
01008 OsiXprSolverInterface::getObjValue() const
01009 {
01010    activateMe();
01011 
01012    double  objvalue = 0;
01013 
01014    if ( isDataLoaded() ) {
01015      if (getLogFilePtr()!=NULL) {
01016        fprintf(getLogFilePtr(),"{\n");
01017        fprintf(getLogFilePtr(),"  double objvalue;\n");
01018        fprintf(getLogFilePtr(),"  getdpv(N_DOBJVL, &objvalue);\n");
01019        fprintf(getLogFilePtr(),"}\n");
01020      }
01021      getdpv(N_DOBJVL, &objvalue);
01022    }
01023 
01024    return objvalue;
01025 }
01026 
01027 //-----------------------------------------------------------------------------
01028 
01029 int OsiXprSolverInterface::getIterationCount() const
01030 {
01031   int itcnt;
01032 
01033   getipv(N_ITCNT, &itcnt);
01034 
01035   return itcnt;
01036 }
01037 
01038 //-----------------------------------------------------------------------------
01039 
01040 std::vector<double*> OsiXprSolverInterface::getDualRays(int maxNumRays) const
01041 {
01042   // *FIXME* : must write the method -LL
01043   throw CoinError("method is not yet written", "getDualRays",
01044                  "OsiXprSolverInterface");
01045   return std::vector<double*>();
01046 }
01047 
01048 //-----------------------------------------------------------------------------
01049 
01050 std::vector<double*> OsiXprSolverInterface::getPrimalRays(int maxNumRays) const
01051 {
01052 #if 0
01053   // *FIXME* : Still need to expand column into full ncols-length vector
01054 
01055   const int nrows = getNumRows();
01056   int nrspar;
01057   getipv(N_NRSPAR, &nrspar);
01058   int junb;
01059   int retcode;
01060 
01061   retcode = getunb(&junb);
01062 
01063   if ( retcode != 0 ) 
01064     return std::vector<double *>(0, (double *) NULL);;
01065 
01066   double *ray = new double[nrows];
01067 
01068 
01069   if ( junb < nrows ) {         // it's a slack
01070     int i;
01071 
01072     for ( i = 0;  i < nrows;  i++ ) ray[i] = 0.0; 
01073     ray[junb] = 1.0; 
01074     retcode = ftran(ray);
01075   } else if ( junb >= nrows + nrspar && 
01076               junb < nrows + nrspar + getNumCols() ){                   
01077                                 // it's a structural variable
01078     int *mstart = new int[nrows];
01079     int *mrowind = new int[nrows];
01080     double *dmatval = new double[nrows];
01081     int nelt;
01082     int jcol = junb - nrows - nrspar;
01083 
01084     retcode = getcols(mstart, mrowind, dmatval, nrows, &nelt, 
01085                       jcol, jcol); 
01086     /* Unpack into the zeroed array y */ 
01087     int i, ielt;
01088 
01089     for ( i = 0;  i < nrows;  i++ ) ray[i] = 0.0; 
01090     for ( ielt = 0;  ielt < nelt;  ielt++ ) 
01091       ray[mrowind[ielt]] = dmatval[ielt]; 
01092     retcode = ftran(ray);
01093 
01094     delete [] mstart;
01095     delete [] mrowind;
01096     delete [] dmatval;
01097   } else {                      // it's an error
01098     retcode = 1;
01099   }
01100 
01101   if ( retcode == 0 ) return std::vector<double *>(1, ray);
01102   else {
01103     delete ray;
01104     return std::vector<double *>(0, (double *) NULL); 
01105   }
01106 #endif
01107 
01108   // *FIXME* : must write the method -LL
01109   throw CoinError("method is not yet written", "getPrimalRays",
01110                  "OsiXprSolverInterface");
01111   return std::vector<double*>();
01112 }
01113 
01114 //-----------------------------------------------------------------------------
01115 
01116 #if 0
01117 OsiVectorInt
01118 OsiXprSolverInterface::getFractionalIndices(const double etol) const
01119 {
01120    OsiVectorInt retVal;
01121    int     numInts = numintvars();
01122    const   double  *sol = colsol();
01123 
01124    getVarTypes();
01125   
01126    OsiRelFltEq eq(etol);
01127 
01128    for ( int i = 0;  i < numInts;  i++ ) {
01129       double colSolElem = sol[ivarind_[i]];
01130       double distanceFromInteger = colSolElem - floor(colSolElem + 0.5);
01131 
01132       if ( !eq( distanceFromInteger, 0.0 ) )
01133          retVal.push_back(ivarind_[i]);
01134    }
01135 
01136    return retVal;
01137 }
01138 #endif
01139 
01140 //#############################################################################
01141 // Problem modifying methods (rim vectors)
01142 //#############################################################################
01143 
01144 void
01145 OsiXprSolverInterface::setObjCoeff( int elementIndex, double elementValue )
01146 {
01147    activateMe();
01148 
01149    if ( isDataLoaded() ) {
01150       chgobj(1, &elementIndex, &elementValue);
01151       freeCachedResults();
01152    }
01153 }
01154 
01155 //-----------------------------------------------------------------------------
01156 
01157 void
01158 OsiXprSolverInterface::setColLower( int elementIndex, double elementValue )
01159 {
01160    activateMe();
01161 
01162    if ( isDataLoaded() ) {
01163       char boundType = 'L';
01164 
01165       getVarTypes();
01166       
01167       if (getLogFilePtr()!=NULL) {
01168         fprintf(getLogFilePtr(),"chgbds(1, %d, %c, %f );\n",
01169           elementIndex,boundType,elementValue);
01170       }
01171 
01172       if ( vartype_ &&
01173            vartype_[elementIndex] == 'B' && 
01174            (elementValue != 0.0 && elementValue != 1.0) ) {
01175         char elementType = 'I';
01176         
01177         if (getLogFilePtr()!=NULL) {
01178           fprintf(getLogFilePtr(),"chgcoltype(1, %d, %c );\n",
01179             elementIndex,elementType);
01180         }
01181         chgcoltype(1, &elementIndex, &elementType);
01182       }
01183       chgbds(1, &elementIndex, &boundType, &elementValue);
01184 
01185       freeCachedResults();
01186       //    delete [] collower_;
01187       //    collower_ = NULL;
01188    }
01189 }
01190 
01191 //-----------------------------------------------------------------------------
01192 
01193 void
01194 OsiXprSolverInterface::setColUpper( int elementIndex, double elementValue )
01195 {
01196    activateMe();
01197 
01198    if ( isDataLoaded() ) {
01199       char boundType = 'U';
01200 
01201       getVarTypes();      
01202       if (getLogFilePtr()!=NULL) {
01203         fprintf(getLogFilePtr(),"chgbds(1, %d, %c, %f );\n",
01204                 elementIndex,boundType,elementValue);
01205       }
01206       chgbds(1, &elementIndex, &boundType, &elementValue);
01207       if ( vartype_ &&
01208            vartype_[elementIndex] == 'B' && 
01209            (elementValue != 0.0 && elementValue != 1.0) ) {
01210          char elementType = 'I';  
01211          
01212         if (getLogFilePtr()!=NULL) {
01213           fprintf(getLogFilePtr(),"chgcoltype(1, %d, %c );\n",
01214                   elementIndex,elementType);
01215         }
01216 
01217          chgcoltype(1, &elementIndex, &elementType);
01218       }
01219       freeCachedResults();
01220       //    delete [] colupper_;
01221       //    colupper_ = NULL;
01222    } 
01223 }
01224 
01225 //-----------------------------------------------------------------------------
01226 
01227 void OsiXprSolverInterface::setColBounds(const int elementIndex, double lower, double upper )
01228 {
01229    activateMe();
01230 
01231    if ( isDataLoaded() ) {
01232      char qbtype[2] = { 'L', 'U' };
01233      int mindex[2];
01234      double bnd[2];
01235 
01236      getVarTypes();
01237      mindex[0] = elementIndex;
01238      mindex[1] = elementIndex;
01239      bnd[0] = lower;
01240      bnd[1] = upper;
01241 
01242      if (getLogFilePtr()!=NULL) {
01243        fprintf(getLogFilePtr(),"chgbds(2, [%d %d], [%c %c], [%f %f]);\n",
01244                mindex[0], mindex[1], qbtype[0], qbtype[1], bnd[0], bnd[1]);
01245      }
01246      chgbds(2, mindex, qbtype, bnd);
01247        
01248      if ( vartype_ && 
01249           vartype_[mindex[0]] == 'B' && 
01250           !((lower == 0.0 && upper == 0.0) ||
01251             (lower == 1.0 && upper == 1.0) ||
01252             (lower == 0.0 && upper == 1.0)) ) {
01253        char elementType = 'I';  
01254          
01255        if (getLogFilePtr()!=NULL) {
01256          fprintf(getLogFilePtr(),"chgcoltype(1, %d, %c );\n",
01257                  mindex[0], elementType);
01258        }
01259 
01260        chgcoltype(1, &mindex[0], &elementType);
01261      }
01262      freeCachedResults();
01263      //    delete [] colupper_;
01264      //    colupper_ = NULL;
01265    }
01266 }
01267 
01268 //-----------------------------------------------------------------------------
01269 
01270 void OsiXprSolverInterface::setColSetBounds(const int* indexFirst,
01271                                             const int* indexLast,
01272                                             const double* boundList)
01273 {
01274   OsiSolverInterface::setColSetBounds(indexFirst, indexLast, boundList);
01275 }
01276 
01277 //-----------------------------------------------------------------------------
01278 
01279 void
01280 OsiXprSolverInterface::setRowLower( int elementIndex, double elementValue )
01281 {
01282   // activateMe();
01283 
01284   double rhs   = getRightHandSide()[elementIndex];
01285   double range = getRowRange()[elementIndex];
01286   char   sense = getRowSense()[elementIndex];
01287   double lower, upper;
01288 
01289   convertSenseToBound(sense, rhs, range, lower, upper);
01290   if( lower != elementValue ) {
01291     convertBoundToSense(elementValue, upper, sense, rhs, range);
01292     setRowType(elementIndex, sense, rhs, range);
01293     // freeCachedResults(); --- invoked in setRowType()
01294   }
01295 }
01296 
01297 //-----------------------------------------------------------------------------
01298 
01299 void
01300 OsiXprSolverInterface::setRowUpper( int elementIndex, double elementValue )
01301 {
01302   // activateMe();
01303 
01304   double rhs   = getRightHandSide()[elementIndex];
01305   double range = getRowRange()[elementIndex];
01306   char   sense = getRowSense()[elementIndex];
01307   double lower, upper;
01308 
01309   convertSenseToBound( sense, rhs, range, lower, upper );
01310   if( upper != elementValue ) {
01311     convertBoundToSense(lower, elementValue, sense, rhs, range);
01312     setRowType(elementIndex, sense, rhs, range);
01313     // freeCachedResults(); --- invoked in setRowType()
01314   }
01315 }
01316 
01317 //-----------------------------------------------------------------------------
01318 
01319 void
01320 OsiXprSolverInterface::setRowBounds( int elementIndex, double lower, double upper )
01321 {
01322   double rhs, range;
01323   char sense;
01324   
01325   convertBoundToSense( lower, upper, sense, rhs, range );
01326   setRowType( elementIndex, sense, rhs, range );
01327   // freeCachedRowRim(); --- invoked in setRowType()
01328 }
01329 
01330 //-----------------------------------------------------------------------------
01331 
01332 void
01333 OsiXprSolverInterface::setRowType(int index, char sense, double rightHandSide,
01334                                   double range)
01335 {
01336   activateMe();
01337 
01338   if ( isDataLoaded() ) {
01339     int mindex[1] = {index};
01340     char qrtype[1] = {sense}; 
01341     double rhs[1] = {rightHandSide};
01342     double rng[1] = {range};
01343 
01344     chgrowtype(1, mindex, qrtype);
01345     chgrhs(1, mindex, rhs);
01346     chgrng(1, mindex, rng);
01347 
01348     freeCachedResults();
01349   }
01350 }
01351 
01352 //-----------------------------------------------------------------------------
01353 
01354 void OsiXprSolverInterface::setRowSetBounds(const int* indexFirst,
01355                                             const int* indexLast,
01356                                             const double* boundList)
01357 {
01358   OsiSolverInterface::setRowSetBounds(indexFirst, indexLast, boundList);
01359 }
01360 
01361 //-----------------------------------------------------------------------------
01362 
01363 void
01364 OsiXprSolverInterface::setRowSetTypes(const int* indexFirst,
01365                                       const int* indexLast,
01366                                       const char* senseList,
01367                                       const double* rhsList,
01368                                       const double* rangeList)
01369 {
01370   OsiSolverInterface::setRowSetTypes(indexFirst, indexLast, senseList, rhsList, rangeList);
01371 }
01372 
01373 //#############################################################################
01374 void 
01375 OsiXprSolverInterface::setContinuous(int index) 
01376 {
01377   activateMe();
01378 
01379   if ( isDataLoaded() ) {
01380     int pstat;
01381 
01382     getipv(N_PSTAT, &pstat);
01383 
01384     if ( (pstat & 6) == 0 ) {           // not presolved
01385       char qctype = 'C';
01386 
01387       chgcoltype(1, &index, &qctype);
01388       freeCachedResults();
01389     }
01390   }
01391 }
01392 
01393 void 
01394 OsiXprSolverInterface::setInteger(int index) 
01395 {
01396   activateMe();
01397 
01398   if ( isDataLoaded() ) {
01399     int pstat;
01400 
01401     getipv(N_PSTAT, &pstat);
01402 
01403     if ( (pstat & 6) == 0 ) {           // not presolved
01404       char qctype;
01405 
01406       if ( getColLower()[index] == 0.0 && 
01407            getColUpper()[index] == 1.0 ) 
01408         qctype = 'B';
01409       else
01410         qctype = 'I';
01411 
01412       chgcoltype(1, &index, &qctype);
01413       freeCachedResults();
01414     }
01415   }
01416 }
01417 
01418 void 
01419 OsiXprSolverInterface::setContinuous(const int* indices, int len) 
01420 {
01421   activateMe();
01422 
01423   if ( isDataLoaded() ) {
01424     int pstat;
01425 
01426     getipv(N_PSTAT, &pstat);
01427 
01428     if ( (pstat & 6) == 0 ) {           // not presolved
01429       char *qctype = new char[len];
01430 
01431       CoinFillN(qctype, len, 'C');
01432       chgcoltype(len, const_cast<int *>(indices), qctype);
01433       freeCachedResults();
01434     }
01435   }
01436 }
01437 
01438 void 
01439 OsiXprSolverInterface::setInteger(const int* indices, int len) 
01440 {
01441   activateMe();
01442 
01443   if ( isDataLoaded() ) {
01444     int pstat;
01445 
01446     getipv(N_PSTAT, &pstat);
01447 
01448     if ( (pstat & 6) == 0 ) {           // not presolved
01449       char *qctype = new char[len];
01450       const double* clb = getColLower();
01451       const double* cub = getColUpper();
01452 
01453       for ( int i = 0;  i < len;  i++ ) {
01454         if ( clb[indices[i]] == 0.0 && cub[indices[i]] == 1.0 )
01455           qctype[i] = 'B';
01456         else 
01457           qctype[i] = 'I';
01458       }
01459 
01460       chgcoltype(len, const_cast<int *>(indices), qctype);
01461       freeCachedResults();
01462     }
01463   }
01464 }
01465 
01466 //#############################################################################
01467 
01468 void
01469 OsiXprSolverInterface::setObjSense(double s) 
01470 {
01471    objsense_ = s;
01472 }
01473 
01474 //-----------------------------------------------------------------------------
01475 
01476 void
01477 OsiXprSolverInterface::setColSolution(const double *colsol)
01478 {
01479    activateMe();
01480 
01481    freeSolution();
01482 
01483    colsol_ = new double[getNumCols()];
01484 
01485    for ( int i = 0;  i < getNumCols();  i++ )
01486       colsol_[i] = colsol[i];
01487 }
01488 
01489 //-----------------------------------------------------------------------------
01490 
01491 void
01492 OsiXprSolverInterface::setRowPrice(const double *rowprice)
01493 {
01494    activateMe();
01495 
01496    freeSolution();
01497 
01498    rowprice_ = new double[getNumRows()];
01499 
01500    for ( int i = 0;  i < getNumRows();  i++ )
01501       rowprice_[i] = rowprice[i];
01502 }
01503 
01504 //#############################################################################
01505 // Problem modifying methods (matrix)
01506 //#############################################################################
01507 
01508 void 
01509 OsiXprSolverInterface::addCol(const CoinPackedVectorBase& vec,
01510                               const double collb, const double colub,   
01511                               const double obj)
01512 {
01513   activateMe();
01514 
01515   if ( isDataLoaded() ) {
01516     freeCachedResults();
01517 
01518     int mstart = 0;
01519 
01520     addcols(1, vec.getNumElements(), const_cast<double*>(&obj),
01521             &mstart,
01522             const_cast<int*>(vec.getIndices()),
01523             const_cast<double*>(vec.getElements()),
01524             const_cast<double*>(&collb),
01525             const_cast<double*>(&colub));
01526   }
01527 }
01528 //-----------------------------------------------------------------------------
01529 void 
01530 OsiXprSolverInterface::addCols(const int numcols,
01531                                const CoinPackedVectorBase * const * cols,
01532                                const double* collb, const double* colub,   
01533                                const double* obj)
01534 {
01535   // activateMe();
01536   // freeCachedResults();
01537 
01538   for( int i = 0;  i < numcols;  i++ )
01539     addCol( *(cols[i]), collb[i], colub[i], obj[i] );
01540 }
01541 //-----------------------------------------------------------------------------
01542 void 
01543 OsiXprSolverInterface::deleteCols(const int num, const int *columnIndices)
01544 {
01545   activateMe();
01546   freeCachedResults();
01547   delcols(num, const_cast<int *>(columnIndices));
01548 }
01549 //-----------------------------------------------------------------------------
01550 void 
01551 OsiXprSolverInterface::addRow(const CoinPackedVectorBase& vec,
01552                               const double rowlb, const double rowub)
01553 {
01554   // activateMe(); -- will be invoked
01555   // freeCachedResults(); -- will be invoked
01556 
01557   char sense;
01558   double rhs, range;
01559 
01560   convertBoundToSense(rowlb, rowub, sense, rhs, range);
01561   addRow(vec, sense, rhs, range);
01562 }
01563 //-----------------------------------------------------------------------------
01564 void 
01565 OsiXprSolverInterface::addRow(const CoinPackedVectorBase& vec,
01566                               const char rowsen, const double rowrhs,   
01567                               const double rowrng)
01568 {
01569   activateMe();
01570   freeCachedResults();
01571 
01572   int mstart[1] = {0};
01573 
01574   addrows(1, vec.getNumElements(), 
01575           const_cast<char *>(&rowsen), const_cast<double *>(&rowrhs), 
01576           const_cast<double *>(&rowrng), mstart,
01577           const_cast<int *>(vec.getIndices()),
01578           const_cast<double *>(vec.getElements()));
01579 }
01580 //-----------------------------------------------------------------------------
01581 void 
01582 OsiXprSolverInterface::addRows(const int numrows,
01583                                const CoinPackedVectorBase * const * rows,
01584                                const double* rowlb, const double* rowub)
01585 {
01586   // *FIXME* : must write the method -LL
01587   throw CoinError("method is not yet written", "addRows",
01588                  "OsiXprSolverInterface");
01589 }
01590 //-----------------------------------------------------------------------------
01591 void 
01592 OsiXprSolverInterface::addRows(const int numrows,
01593                                const CoinPackedVectorBase * const * rows,
01594                                const char* rowsen, const double* rowrhs,   
01595                                const double* rowrng)
01596 {
01597   // *FIXME* : must write the method -LL
01598   throw CoinError("method is not yet written", "addRows",
01599                  "OsiXprSolverInterface");
01600 }
01601 //-----------------------------------------------------------------------------
01602 void 
01603 OsiXprSolverInterface::deleteRows(const int num, const int * rowIndices)
01604 {
01605   activateMe();
01606   freeCachedResults();
01607 
01608   delrows(num, const_cast<int *>(rowIndices));
01609 }
01610 
01611 //#############################################################################
01612 // Methods to input a problem
01613 //#############################################################################
01614 
01615 void
01616 OsiXprSolverInterface::loadProblem(const CoinPackedMatrix& matrix,
01617                                    const double* collb, const double* colub,   
01618                                    const double* obj,
01619                                    const double* rowlb, const double* rowub)
01620 {
01621   const double inf = getInfinity();
01622   
01623   char   * rowSense = new char  [matrix.getNumRows()];
01624   double * rowRhs   = new double[matrix.getNumRows()];
01625   double * rowRange = new double[matrix.getNumRows()];
01626   
01627   int i;
01628   for ( i = matrix.getNumRows() - 1; i >= 0; --i) {
01629     
01630     double rlb;
01631     if ( rowlb!=NULL )
01632       rlb = rowlb[i];
01633     else
01634       rlb = -inf;
01635     
01636      double rub;
01637      if ( rowub!=NULL )
01638        rub = rowub[i];
01639      else
01640        rub = inf;
01641      
01642      convertBoundToSense(rlb,rub,rowSense[i],rowRhs[i],rowRange[i]);
01643 #if 0
01644      if ( rlb==rub ) {
01645        rowSense[i]='E';
01646        rowRhs[i]  =rlb;
01647        rowRange[i]=0.0;
01648        continue;
01649      }
01650      if ( rlb<=-inf && rub>=inf ) {
01651        rowSense[i]='N';
01652        rowRhs[i]  =inf;
01653        rowRange[i]=0.0;
01654        continue;
01655      }
01656      if ( rlb<=-inf && !(rub>=inf) ) {
01657        rowSense[i]='L';
01658        rowRhs[i]  =rub;
01659        rowRange[i]=0.0;
01660        continue;
01661      }
01662      if ( !(rlb<=-inf) && rub>=inf ) {
01663        rowSense[i]='G';
01664        rowRhs[i]  =rlb;
01665        rowRange[i]=0.0;
01666        continue;
01667      }
01668      if ( !(rlb<=-inf) && !(rub>=inf) ) {
01669        rowSense[i]='R';
01670        rowRhs[i]  =rub;
01671        rowRange[i]=rub-rlb;
01672        continue;
01673      }
01674 #endif
01675    }
01676   
01677    loadProblem(matrix, collb, colub, obj, rowSense, rowRhs, rowRange ); 
01678    
01679    delete [] rowSense;
01680    delete [] rowRhs;
01681    delete [] rowRange;
01682 }
01683 
01684 //-----------------------------------------------------------------------------
01685 
01686 void
01687 OsiXprSolverInterface::assignProblem(CoinPackedMatrix*& matrix,
01688                                      double*& collb, double*& colub,
01689                                      double*& obj,
01690                                      double*& rowlb, double*& rowub)
01691 {
01692    loadProblem(*matrix, collb, colub, obj, rowlb, rowub);
01693    delete matrix;   matrix = 0;
01694    delete[] collb;  collb = 0;
01695    delete[] colub;  colub = 0;
01696    delete[] obj;    obj = 0;
01697    delete[] rowlb;  rowlb = 0;
01698    delete[] rowub;  rowub = 0;
01699 }
01700 
01701 //-----------------------------------------------------------------------------
01702 
01703 // #define OSIXPR_ADD_OBJ_ROW
01704 
01705 void
01706 OsiXprSolverInterface::loadProblem(const CoinPackedMatrix& matrix,
01707                                    const double* collb, const double* colub,
01708                                    const double* obj,
01709                                    const char* rowsen, const double* rowrhs,   
01710                                    const double* rowrng)
01711 {
01712   assert( rowsen != NULL );
01713   assert( rowrhs != NULL );
01714 
01715   activateMe();
01716   freeCachedResults();
01717   int i;
01718  
01719   // Set column values to defaults if NULL pointer passed
01720   int nc=matrix.getNumCols();
01721   double * clb;  
01722   double * cub;
01723   double * ob;
01724   if ( collb!=NULL ) {
01725     clb=const_cast<double*>(collb);
01726   }
01727   else {
01728     clb = new double[nc];
01729     for( i=0; i<nc; i++ ) clb[i]=0.0;
01730   }
01731   if ( colub!=NULL ) 
01732     cub=const_cast<double*>(colub);
01733   else {
01734     cub = new double[nc];
01735     for( i=0; i<nc; i++ ) cub[i]=DPLINF;
01736   }
01737   if ( obj!=NULL ) 
01738     ob=const_cast<double*>(obj);
01739   else {
01740     ob = new double[nc];
01741     for( i=0; i<nc; i++ ) ob[i]=0.0;
01742   }
01743   
01744   bool freeMatrixRequired = false;
01745   CoinPackedMatrix * m = NULL;
01746   if ( !matrix.isColOrdered() ) {
01747     m = new CoinPackedMatrix();
01748     m->reverseOrderedCopyOf(matrix);
01749     freeMatrixRequired = true;
01750   } else {
01751     m = const_cast<CoinPackedMatrix *>(&matrix);
01752   }
01753   
01754   // Generate a problem name
01755   char probName[256];
01756   sprintf(probName, "Prob%i", osiSerial_);
01757 
01758   
01759   nc = m->getNumCols();
01760   int nr =  m->getNumRows();
01761   
01762   if ( getLogFilePtr()!=NULL ) {   
01763     fprintf(getLogFilePtr(),"{\n"); 
01764 
01765     fprintf(getLogFilePtr(),"  char rowsen[%d];\n",nr);
01766     for ( i=0; i<nr; i++ )
01767       fprintf(getLogFilePtr(),"  rowsen[%d]='%c';\n",i,rowsen[i]);
01768 
01769     fprintf(getLogFilePtr(),"  double rowrhs[%d];\n",nr);
01770     for ( i=0; i<nr; i++ )
01771       fprintf(getLogFilePtr(),"  rowrhs[%d]=%f;\n",i,rowrhs[i]);
01772     
01773     fprintf(getLogFilePtr(),"  double rowrng[%d];\n",nr);
01774     for ( i=0; i<nr; i++ )
01775       fprintf(getLogFilePtr(),"  rowrng[%d]=%f;\n",i,rowrng[i]);
01776 
01777     fprintf(getLogFilePtr(),"  double ob[%d];\n",nc);
01778     for ( i=0; i<nc; i++ )
01779       fprintf(getLogFilePtr(),"  ob[%d]=%f;\n",i,ob[i]);
01780 
01781     fprintf(getLogFilePtr(),"  double clb[%d];\n",nc);
01782     for ( i=0; i<nc; i++ )
01783       fprintf(getLogFilePtr(),"  clb[%d]=%f;\n",i,clb[i]);
01784 
01785     fprintf(getLogFilePtr(),"  double cub[%d];\n",nc);
01786     for ( i=0; i<nc; i++ )
01787       fprintf(getLogFilePtr(),"  cub[%d]=%f;\n",i,cub[i]);
01788 
01789     fprintf(getLogFilePtr(),"  int vectorStarts[%d];\n",nc+1);
01790     for ( i=0; i<=nc; i++ )
01791       fprintf(getLogFilePtr(),"  vectorStarts[%d]=%d;\n",i,m->getVectorStarts()[i]);
01792 
01793     fprintf(getLogFilePtr(),"  int vectorLengths[%d];\n",nc);
01794     for ( i=0; i<nc; i++ )
01795       fprintf(getLogFilePtr(),"  vectorLengths[%d]=%d;\n",i,m->getVectorLengths()[i]);
01796     
01797     fprintf(getLogFilePtr(),"  int indices[%d];\n",m->getVectorStarts()[nc]);
01798     for ( i=0; i<m->getVectorStarts()[nc]; i++ )
01799       fprintf(getLogFilePtr(),"  indices[%d]=%d;\n",i,m->getIndices()[i]);
01800 
01801     fprintf(getLogFilePtr(),"  double elements[%d];\n",m->getVectorStarts()[nc]);
01802     for ( i=0; i<m->getVectorStarts()[nc]; i++ )
01803       fprintf(getLogFilePtr(),"  elements[%d]=%f;\n",i,m->getElements()[i]);
01804 
01805     fprintf(getLogFilePtr(),
01806             "  int iret = loadprob(\"%s\",\n"
01807             "                      %d,\n"
01808             "                      %d,\n"
01809             "                      rowsen,\n"
01810             "                      rowrhs,\n"
01811             "                      rowrng,\n"
01812             "                      ob,\n"
01813             "                      vectorStarts,\n"
01814             "                      vectorLengths,\n"
01815             "                      indices,\n"
01816             "                      elements,\n"
01817             "                      clb,\n"
01818             "                      cub );\n",probName,nc,nr );    
01819     fprintf(getLogFilePtr(),"}\n");
01820   }
01821   // Need to cast away const'ness
01822   int iret = loadprob(probName,
01823     nc,
01824     nr,
01825     rowsen,
01826     const_cast<double*>(rowrhs),
01827     const_cast<double*>(rowrng),
01828     ob,
01829     const_cast<int*>(m->getVectorStarts()),
01830     const_cast<int*>(m->getVectorLengths()),
01831     const_cast<int*>(m->getIndices()),
01832     const_cast<double*>(m->getElements()),
01833     clb,
01834     cub );
01835   setStrParam(OsiProbName,probName);
01836   
01837   if ( iret != 0 )
01838     getipv(N_ERRNO, &iret);
01839   assert( iret == 0 );
01840   
01841    
01842   if (getLogFilePtr()!=NULL) {
01843     fprintf(getLogFilePtr(),"{\n");
01844     fprintf(getLogFilePtr(),"   char pname[256];\n");
01845     fprintf(getLogFilePtr(),"   getprob(pname);\n");
01846     fprintf(getLogFilePtr(),"}\n");
01847   }
01848 
01849   char pname[256];      // Problem names can be 200 chars in XPRESS 12
01850   getprob(pname);
01851   xprProbname_ = pname;
01852   
01853   if ( collb==NULL ) delete[] clb;
01854   if ( colub==NULL ) delete[] cub;
01855   if ( obj  ==NULL ) delete[] ob;
01856   
01857   if (freeMatrixRequired) {
01858     delete m;
01859   }
01860 }
01861 
01862 //-----------------------------------------------------------------------------
01863 
01864 void
01865 OsiXprSolverInterface::assignProblem(CoinPackedMatrix*& matrix,
01866                                      double*& collb, double*& colub,
01867                                      double*& obj,
01868                                      char*& rowsen, double*& rowrhs,
01869                                      double*& rowrng)
01870 {
01871    loadProblem(*matrix, collb, colub, obj, rowsen, rowrhs, rowrng);
01872    delete matrix;   matrix = 0;
01873    delete[] collb;  collb = 0;
01874    delete[] colub;  colub = 0;
01875    delete[] obj;    obj = 0;
01876    delete[] rowsen; rowsen = 0;
01877    delete[] rowrhs; rowrhs = 0;
01878    delete[] rowrng; rowrng = 0;
01879 }
01880 
01881 //-----------------------------------------------------------------------------
01882 
01883 void
01884 OsiXprSolverInterface::loadProblem(const int numcols, const int numrows,
01885                                    const int* start, const int* index,
01886                                    const double* value,
01887                                    const double* collb, const double* colub,   
01888                                    const double* obj,
01889                                    const double* rowlb, const double* rowub )
01890 {
01891   const double inf = getInfinity();
01892   
01893   char   * rowSense = new char  [numrows];
01894   double * rowRhs   = new double[numrows];
01895   double * rowRange = new double[numrows];
01896   
01897   for ( int i = numrows - 1; i >= 0; --i ) {
01898     const double lower = rowlb ? rowlb[i] : -inf;
01899     const double upper = rowub ? rowub[i] : inf;
01900     convertBoundToSense( lower, upper, rowSense[i], rowRhs[i], rowRange[i] );
01901   }
01902 
01903   loadProblem(numcols, numrows, start, index, value, collb, colub, obj,
01904               rowSense, rowRhs, rowRange);
01905   delete [] rowSense;
01906   delete [] rowRhs;
01907   delete [] rowRange;
01908 
01909 }
01910 
01911 //-----------------------------------------------------------------------------
01912 
01913 void
01914 OsiXprSolverInterface::loadProblem(const int numcols, const int numrows,
01915                                    const int* start, const int* index,
01916                                    const double* value,
01917                                    const double* collb, const double* colub,   
01918                                    const double* obj,
01919                                    const char* rowsen, const double* rowrhs,
01920                                    const double* rowrng )
01921 {
01922   assert( rowsen != NULL );
01923   assert( rowrhs != NULL );
01924 
01925   activateMe();
01926   freeCachedResults();
01927   int i;
01928  
01929   // Set column values to defaults if NULL pointer passed
01930   int nc = numcols;
01931   int nr = numrows;
01932   int * len = new int[nc];
01933   double * clb;  
01934   double * cub;
01935   double * ob;
01936 
01937   std::adjacent_difference(start, start + (nc+1), len);
01938   
01939   if ( collb!=NULL ) {
01940     clb=const_cast<double*>(collb);
01941   }
01942   else {
01943     clb = new double[nc];
01944     for( i=0; i<nc; i++ ) clb[i]=0.0;
01945   }
01946   if ( colub!=NULL ) 
01947     cub=const_cast<double*>(colub);
01948   else {
01949     cub = new double[nc];
01950     for( i=0; i<nc; i++ ) cub[i]=DPLINF;
01951   }
01952   if ( obj!=NULL ) 
01953     ob=const_cast<double*>(obj);
01954   else {
01955     ob = new double[nc];
01956     for( i=0; i<nc; i++ ) ob[i]=0.0;
01957   }
01958 
01959   // Generate a problem name
01960   char probName[256];
01961   sprintf(probName, "Prob%i", osiSerial_);
01962 
01963   if ( getLogFilePtr()!=NULL ) {   
01964     fprintf(getLogFilePtr(),"{\n"); 
01965 
01966     fprintf(getLogFilePtr(),"  char rowsen[%d];\n",nr);
01967     for ( i=0; i<nr; i++ )
01968       fprintf(getLogFilePtr(),"  rowsen[%d]='%c';\n",i,rowsen[i]);
01969 
01970     fprintf(getLogFilePtr(),"  double rowrhs[%d];\n",nr);
01971     for ( i=0; i<nr; i++ )
01972       fprintf(getLogFilePtr(),"  rowrhs[%d]=%f;\n",i,rowrhs[i]);
01973     
01974     fprintf(getLogFilePtr(),"  double rowrng[%d];\n",nr);
01975     for ( i=0; i<nr; i++ )
01976       fprintf(getLogFilePtr(),"  rowrng[%d]=%f;\n",i,rowrng[i]);
01977 
01978     fprintf(getLogFilePtr(),"  double ob[%d];\n",nc);
01979     for ( i=0; i<nc; i++ )
01980       fprintf(getLogFilePtr(),"  ob[%d]=%f;\n",i,ob[i]);
01981 
01982     fprintf(getLogFilePtr(),"  double clb[%d];\n",nc);
01983     for ( i=0; i<nc; i++ )
01984       fprintf(getLogFilePtr(),"  clb[%d]=%f;\n",i,clb[i]);
01985 
01986     fprintf(getLogFilePtr(),"  double cub[%d];\n",nc);
01987     for ( i=0; i<nc; i++ )
01988       fprintf(getLogFilePtr(),"  cub[%d]=%f;\n",i,cub[i]);
01989 
01990     fprintf(getLogFilePtr(),"  int vectorStarts[%d];\n",nc+1);
01991     for ( i=0; i<=nc; i++ )
01992       fprintf(getLogFilePtr(),"  vectorStarts[%d]=%d;\n",i,start[i]);
01993 
01994     fprintf(getLogFilePtr(),"  int vectorLengths[%d];\n",nc);
01995     for ( i=0; i<nc; i++ )
01996       fprintf(getLogFilePtr(),"  vectorLengths[%d]=%d;\n",i,len[i]);
01997     
01998     fprintf(getLogFilePtr(),"  int indices[%d];\n",start[nc]);
01999     for ( i=0; i<start[nc]; i++ )
02000       fprintf(getLogFilePtr(),"  indices[%d]=%d;\n",i,index[i]);
02001 
02002     fprintf(getLogFilePtr(),"  double elements[%d];\n",start[nc]);
02003     for ( i=0; i<start[nc]; i++ )
02004       fprintf(getLogFilePtr(),"  elements[%d]=%f;\n",i,value[i]);
02005 
02006     fprintf(getLogFilePtr(),
02007             "  int iret = loadprob(\"%s\",\n"
02008             "                      %d,\n"
02009             "                      %d,\n"
02010             "                      rowsen,\n"
02011             "                      rowrhs,\n"
02012             "                      rowrng,\n"
02013             "                      ob,\n"
02014             "                      vectorStarts,\n"
02015             "                      vectorLengths,\n"
02016             "                      indices,\n"
02017             "                      elements,\n"
02018             "                      clb,\n"
02019             "                      cub );\n",probName,nc,nr );    
02020     fprintf(getLogFilePtr(),"}\n");
02021   }
02022   // Need to cast away const'ness
02023   int iret = loadprob(probName,
02024     nc,
02025     nr,
02026     rowsen,
02027     const_cast<double*>(rowrhs),
02028     const_cast<double*>(rowrng),
02029     ob,
02030     const_cast<int*>(start),
02031     const_cast<int*>(len),
02032     const_cast<int*>(index),
02033     const_cast<double*>(value),
02034     clb,
02035     cub );
02036   setStrParam(OsiProbName,probName);
02037   
02038   if ( iret != 0 )
02039     getipv(N_ERRNO, &iret);
02040   assert( iret == 0 );
02041   
02042    
02043   if (getLogFilePtr()!=NULL) {
02044     fprintf(getLogFilePtr(),"{\n");
02045     fprintf(getLogFilePtr(),"   char pname[256];\n");
02046     fprintf(getLogFilePtr(),"   getprob(pname);\n");
02047     fprintf(getLogFilePtr(),"}\n");
02048   }
02049 
02050   char pname[256];      // Problem names can be 200 chars in XPRESS 12
02051   getprob(pname);
02052   xprProbname_ = pname;
02053   
02054   if ( collb == NULL ) delete[] clb;
02055   if ( colub == NULL ) delete[] cub;
02056   if ( obj   == NULL ) delete[] ob;
02057   delete[] len;
02058 }
02059 
02060 
02061 
02062 //-----------------------------------------------------------------------------
02063 // Read mps files
02064 //-----------------------------------------------------------------------------
02065 
02066 int
02067 OsiXprSolverInterface::readMps(const char *filename, const char *extension) 
02068 {
02069   activateMe();
02070    
02071 #if 0
02072   if (getLogFilePtr()!=NULL) {
02073     fprintf(getLogFilePtr(),"{\n");
02074     fprintf(getLogFilePtr(),"  input(\"%s\");\n",filename);
02075     fprintf(getLogFilePtr(),"  int namlen;\n");
02076     fprintf(getLogFilePtr(),"  geticv(N_NAMSIZ,&namlen);\n");
02077     fprintf(getLogFilePtr(),"  namlen *= 8;\n");
02078   }
02079  
02080   // Read Mps file.
02081   // XPRESS generates its own file extensions, so we ignore any supplied.
02082   int iret = input(filename);
02083   if ( iret != 0 )  
02084     getipv(N_ERRNO, &iret);
02085   assert( iret == 0 );
02086 
02087   // Get length of Mps names
02088   int namlen;
02089   getipv(N_NAMSIZ, &namlen);
02090   namlen *= 8;
02091 
02092   if (getLogFilePtr()!=NULL) {
02093     fprintf(getLogFilePtr(),"  char objRowName[%d],rowName[%d];\n",namlen,namlen);
02094     fprintf(getLogFilePtr(),"  getccv(N_OBJNAM, objRowName);\n");
02095     fprintf(getLogFilePtr(),"  int nr;\n");
02096     fprintf(getLogFilePtr(),"  seticv(N_NROW, &nr);");
02097   }
02098 
02099   // Allocate space to hold row names.
02100   char * objRowName = new char[namlen+1];
02101   char * rowName    = new char[namlen+1];
02102 
02103   // Get name of objective row.
02104   // If "" returned, then first N row is objective row
02105   getccv(N_OBJNAM,objRowName);
02106 
02107   // Get number of rows
02108   int nr;
02109   getipv(N_NROW, &nr);
02110     
02111   if (getLogFilePtr()!=NULL) {
02112     fprintf(getLogFilePtr(),"  char rs[%d];\n",nr);
02113     fprintf(getLogFilePtr(),"  getrowtype(rs, 0, %d);\n",nr-1);
02114   }
02115 
02116   // Get row sense.
02117   char * rs = new char[nr];
02118   getrowtype(rs, 0, nr - 1);
02119 
02120   // Loop once for each row looking for objective row
02121   int i;
02122   for ( i=0; i<nr; i++ ) {
02123     
02124     // Objective row must be an N row
02125     if ( rs[i]=='N' ) {      
02126       
02127       if (getLogFilePtr()!=NULL) {
02128         fprintf(getLogFilePtr(),"  getnames(1,rowName,%d,%d);\n",i,i);
02129       }
02130       
02131       // Get name of this row
02132       getnames(1,rowName,i,i);
02133       
02134       // Is this the objective row?
02135       if( strcmp(rowName,objRowName)==0 ||
02136         strcmp("",objRowName) == 0 ) {
02137         
02138         if (getLogFilePtr()!=NULL) {
02139           fprintf(getLogFilePtr(),"  int rowToDelete[1];\n");
02140           fprintf(getLogFilePtr(),"  rowToDelete[0]=%d;\n",i);
02141           fprintf(getLogFilePtr(),"  delrows(1,rowToDelete);\n");
02142         }
02143         
02144         // found objective row. now delete it
02145         int rowToDelete[1];
02146         rowToDelete[0] = i;
02147         delrows(1,rowToDelete);
02148         break;
02149       }
02150     }
02151   }
02152 
02153   delete [] rs;
02154   delete [] rowName;
02155   delete [] objRowName;
02156   
02157   if (getLogFilePtr()!=NULL) {
02158     fprintf(getLogFilePtr(),"  char pname[256];\n");
02159     fprintf(getLogFilePtr(),"  getprob(pname);\n");
02160     fprintf(getLogFilePtr(),"}\n");
02161   }
02162   
02163   char pname[256];      // Problem names can be 200 chars in XPRESS 12
02164   getprob(pname);
02165   xprProbname_ = pname;
02166   return 0;
02167 #else
02168   int retVal = OsiSolverInterface::readMps(filename,extension);
02169   getStrParam(OsiProbName,xprProbname_);
02170   return retVal;
02171 #endif
02172 }
02173 
02174 
02175 //-----------------------------------------------------------------------------
02176 // Write mps files
02177 //-----------------------------------------------------------------------------
02178 void OsiXprSolverInterface::writeMps(const char *filename,
02179                                      const char *extension,
02180                                      double objSense) const
02181 {
02182   activateMe();
02183 
02184   // Note: XPRESS insists on ignoring the extension and 
02185   // adding ".mat" instead.  Forewarned is forearmed.
02186   // Note: Passing an empty filename produces a file named after 
02187   // the problem.
02188 
02189   output(filename, "");
02190 }
02191 
02192 //#############################################################################
02193 // Static data and methods
02194 //#############################################################################
02195 
02196 void
02197 OsiXprSolverInterface::incrementInstanceCounter()
02198 {
02199   if ( numInstances_ == 0 ) {          
02200     if ( getLogFilePtr()!=NULL ) {
02201       fprintf(getLogFilePtr(),"{\n");
02202       fprintf(getLogFilePtr(),"  setoptlog(\"xpress.log\");\n");
02203       fprintf(getLogFilePtr(),"  initlz(NULL,0);\n");
02204       fprintf(getLogFilePtr(),"}\n");
02205     }
02206     const char *logfile = "xpress.log";
02207     setoptlog(logfile);
02208     int iret = initlz(NULL, 0);
02209     
02210     // Student Version returns 32
02211     if ( iret != 32 ) {
02212       if ( iret != 0 ) getipv(N_ERRNO, &iret);
02213       assert(iret == 0);
02214     }
02215   }
02216 
02217    numInstances_++;
02218    osiSerial_++;
02219 
02220    //  cout << "Instances = " << numInstances_ << "; Serial = " << osiSerial_ << endl;
02221 }
02222 
02223 //-----------------------------------------------------------------------------
02224 
02225 void
02226 OsiXprSolverInterface::decrementInstanceCounter()
02227 {
02228   assert( numInstances_ != 0 );
02229   numInstances_--;
02230   
02231   //  cout << "Instances = " << numInstances_ << endl;
02232   
02233   if ( numInstances_ == 0 ) {
02234     
02235     if ( getLogFilePtr()!=NULL ) {
02236       fprintf(getLogFilePtr(),"{\n");
02237       fprintf(getLogFilePtr(),"  freexo();\n");
02238       fprintf(getLogFilePtr(),"}\n");
02239     }
02240 
02241     freexo();
02242   }
02243 }
02244 
02245 //-----------------------------------------------------------------------------
02246 
02247 unsigned int
02248 OsiXprSolverInterface::getNumInstances()
02249 {
02250    return numInstances_;
02251 }
02252 
02253 //-----------------------------------------------------------------------------
02254 
02255 // Return XPRESS-MP Version number
02256 int OsiXprSolverInterface::version()
02257 {
02258   int retVal;
02259   geticv( N_VERNO, &retVal );
02260   return retVal;
02261 }
02262 
02263 //-----------------------------------------------------------------------------
02264 
02265 FILE * OsiXprSolverInterface::getLogFilePtr()
02266 {
02267   if (logFilePtr_!=NULL){fclose(logFilePtr_);logFilePtr_=NULL;}
02268   if (logFileName_!=NULL) logFilePtr_ = fopen(logFileName_,"a+");
02269   return logFilePtr_;
02270 }
02271 
02272 //-----------------------------------------------------------------------------
02273 
02274 void OsiXprSolverInterface::setLogFileName( const char * filename )
02275 {
02276   logFileName_ = filename;
02277 }
02278 
02279 //-----------------------------------------------------------------------------
02280 
02281 unsigned int OsiXprSolverInterface::numInstances_ = 0;
02282 
02283 unsigned int OsiXprSolverInterface::osiSerial_ = 0;  
02284 
02285 FILE * OsiXprSolverInterface::logFilePtr_ = NULL;  
02286 
02287 const char * OsiXprSolverInterface::logFileName_ = NULL;
02288 
02289 //#############################################################################
02290 // Constructors, destructors clone and assignment
02291 //#############################################################################
02292 
02293 //-------------------------------------------------------------------
02294 // Default Constructor 
02295 //-------------------------------------------------------------------
02296 OsiXprSolverInterface::OsiXprSolverInterface (int newrows, int newnz) :
02297 OsiSolverInterface(),
02298 xprSaved_(false),
02299 xprMatrixId_(-1),
02300 matrixByRow_(NULL),
02301 matrixByCol_(NULL),
02302 colupper_(NULL),
02303 collower_(NULL),
02304 rowupper_(NULL),
02305 rowlower_(NULL),
02306 rowsense_(NULL),
02307 rhs_(NULL),
02308 rowrange_(NULL),
02309 objcoeffs_(NULL),
02310 objsense_(1),
02311 colsol_(NULL),
02312 rowsol_(NULL),
02313 rowact_(NULL),
02314 rowprice_(NULL),
02315 colprice_(NULL),
02316 ivarind_(NULL),
02317 ivartype_(NULL),
02318 vartype_(NULL)
02319 {
02320   incrementInstanceCounter();
02321   
02322   xprProbname_ = "";
02323   
02324   // newrows and newnz specify room to leave in the solver's matrix
02325   // structure for cuts.  Note that this is a *global* parameter.
02326   // The value in effect when the problem is loaded pertains.
02327   
02328   if ( newrows > 0 && newnz > 0 ) {         
02329     if ( getLogFilePtr()!=NULL ) {
02330       fprintf(getLogFilePtr(),"{\n");
02331       fprintf(getLogFilePtr(),"  seticv(N_NRXTRA, %d);\n",newrows);
02332       fprintf(getLogFilePtr(),"  seticv(N_NMXTRA, %d);\n",newnz);
02333       fprintf(getLogFilePtr(),"}\n");
02334     }
02335     seticv(N_NRXTRA, newrows);
02336     seticv(N_NMXTRA, newnz);
02337   }
02338 }
02339 
02340 //----------------------------------------------------------------
02341 // Clone
02342 //----------------------------------------------------------------
02343 OsiSolverInterface *
02344 OsiXprSolverInterface::clone(bool copyData) const
02345 {  
02346    return (new OsiXprSolverInterface(*this));
02347 }
02348 
02349 //-------------------------------------------------------------------
02350 // Copy constructor 
02351 //-------------------------------------------------------------------
02352 OsiXprSolverInterface::
02353 OsiXprSolverInterface (const OsiXprSolverInterface & source) :
02354    OsiSolverInterface(source),
02355    xprSaved_(false),
02356    xprMatrixId_(-1),
02357    matrixByRow_(NULL),
02358    matrixByCol_(NULL),
02359    colupper_(NULL),
02360    collower_(NULL),
02361    rowupper_(NULL),
02362    rowlower_(NULL),
02363    rowsense_(NULL),
02364    rhs_(NULL),
02365    rowrange_(NULL),
02366    objcoeffs_(NULL),
02367    objsense_(1),
02368    colsol_(NULL),
02369    rowsol_(NULL),
02370    rowact_(NULL),
02371    rowprice_(NULL),
02372    colprice_(NULL),
02373    ivarind_(NULL),
02374    ivartype_(NULL),
02375    vartype_(NULL)
02376 {
02377    incrementInstanceCounter();
02378   
02379    xprProbname_ = "";
02380 
02381    gutsOfCopy(source);
02382 
02383    // Other values remain NULL until requested
02384 }
02385 
02386 //-------------------------------------------------------------------
02387 // Destructor 
02388 //-------------------------------------------------------------------
02389 OsiXprSolverInterface::~OsiXprSolverInterface ()
02390 {
02391    if ( xprSaved_ ) {
02392       //    cout << "Problem " << xprProbname_ << " deleted from matrix " << xprMatrixId_ << "." << endl; 
02393       //    *** Temporarily no matrix deletes until XPRESS bug resolved.
02394       //      int iret = delmat(xprMatrixId_);
02395       //      if ( iret != 0 ) { 
02396       //         getipv(N_ERRNO, &iret);
02397       //         cout << "Deletion reported error " << iret << endl;
02398       //      }
02399       //      assert( iret == 0 );
02400    } else if ( xprCurrentProblem_ == this ) xprCurrentProblem_ = NULL;
02401 
02402    gutsOfDestructor();
02403 
02404    decrementInstanceCounter();
02405 }
02406 
02407 //-------------------------------------------------------------------
02408 // Assignment operator 
02409 //-------------------------------------------------------------------
02410 OsiXprSolverInterface &
02411 OsiXprSolverInterface::operator=(const OsiXprSolverInterface& rhs)
02412 {
02413    if ( this != &rhs ) {    
02414       OsiSolverInterface::operator=(rhs);
02415       osiSerial_++;       // even though numInstances_ doesn't change
02416       gutsOfDestructor();
02417       gutsOfCopy(rhs);
02418    }
02419    return *this;
02420 }
02421 
02422 //#############################################################################
02423 // Applying cuts
02424 //#############################################################################
02425 
02426 void
02427 OsiXprSolverInterface::applyColCut( const OsiColCut & cc )
02428 {
02429    activateMe();
02430 
02431    const double  *collower = getColLower();
02432    const double  *colupper = getColUpper();
02433    const CoinPackedVector & lbs = cc.lbs();
02434    const CoinPackedVector & ubs = cc.ubs();
02435 
02436    int     *index = new int   [lbs.getNumElements() + ubs.getNumElements()];
02437    char    *btype = new char  [lbs.getNumElements() + ubs.getNumElements()];
02438    double  *value = new double[lbs.getNumElements() + ubs.getNumElements()];
02439 
02440    int     i, nbds;
02441 
02442    for ( i = nbds = 0;  i < lbs.getNumElements();  i++, nbds++ ) {
02443       index[nbds] = lbs.getIndices()[i];
02444       btype[nbds] = 'L';
02445       value[nbds] = (collower[index[nbds]] > lbs.getElements()[i]) ?
02446          collower[index[nbds]] : lbs.getElements()[i];
02447    }
02448 
02449    for ( i = 0;  i < ubs.getNumElements();  i++, nbds++ ) {
02450       index[nbds] = ubs.getIndices()[i];
02451       btype[nbds] = 'U';
02452       value[nbds] = (colupper[index[nbds]] < ubs.getElements()[i]) ?
02453          colupper[index[nbds]] : ubs.getElements()[i];
02454    }
02455    
02456     if (getLogFilePtr()!=NULL) {
02457       fprintf(getLogFilePtr(),"{\n");
02458       fprintf(getLogFilePtr(),"   int index[%d];\n",nbds);
02459       fprintf(getLogFilePtr(),"   char btype[%d];\n",nbds);
02460       fprintf(getLogFilePtr(),"   double value[%d];\n",nbds);
02461       for ( i=0; i<nbds; i++ ) {
02462         fprintf(getLogFilePtr(),"   index[%d]=%d;\n",i,index[i]);
02463         fprintf(getLogFilePtr(),"   btype[%d]='%c';\n",i,btype[i]);
02464         fprintf(getLogFilePtr(),"   value[%d]=%f;\n",i,value[i]);
02465       }
02466       fprintf(getLogFilePtr(),"    chgbds(%d, index, btype, value);\n",nbds);
02467       fprintf(getLogFilePtr(),"}\n");
02468     }
02469 
02470    chgbds(nbds, index, btype, value);
02471 
02472    delete [] index;
02473    delete [] btype;
02474    delete [] value;
02475 
02476    freeCachedResults();
02477    //  delete [] colupper_;      colupper_ = NULL;
02478    //  delete [] collower_;      collower_ = NULL;
02479 }
02480 
02481 //-----------------------------------------------------------------------------
02482 
02483 void
02484 OsiXprSolverInterface::applyRowCut( const OsiRowCut & rowCut )
02485 {
02486    activateMe();
02487 
02488    const   CoinPackedVector & row=rowCut.row();
02489    int     start[2] = {0, row.getNumElements()};
02490    char    sense = rowCut.sense();
02491    double  rhs   = rowCut.rhs();
02492 
02493    // XPRESS-MP header file xpresso.h is defining range
02494    // This is causing the rowCut range method name to
02495    // be incorretly changed.
02496    // Play some preprocessor games to get around.
02497 #define rangeTemp range
02498 #undef range
02499    double  r = rowCut.range();
02500 #define range rangeTemp
02501 
02502     if (getLogFilePtr()!=NULL) {
02503       int i;
02504       fprintf(getLogFilePtr(),"{\n");
02505       fprintf(getLogFilePtr(),"  char sense = '%c';\n",sense);
02506       fprintf(getLogFilePtr(),"  double rhs = '%f';\n",rhs);
02507       fprintf(getLogFilePtr(),"  double r = '%f';\n",r);
02508       fprintf(getLogFilePtr(),"  int start[2] = {0,%d};\n",start[1]);
02509       fprintf(getLogFilePtr(),"  int indices[%d];\n",row.getNumElements());
02510       fprintf(getLogFilePtr(),"  double elements[%d];\n",row.getNumElements());
02511       for ( i=0; i<row.getNumElements(); i++ ) {
02512         fprintf(getLogFilePtr(),"  indices[%d]=%d;\n",i,row.getIndices()[i]);
02513         fprintf(getLogFilePtr(),"  elements[%d]=%f;\n",i,row.getElements()[i]);
02514       }
02515       fprintf(getLogFilePtr(),
02516         "  int rc = addrows(1, %d, &sense, &rhs, &r, start,indices, elements);\n",row.getNumElements());
02517       fprintf(getLogFilePtr(),"}\n");
02518     }
02519 
02520    // In XPRESS addrows() prototype, indices and elements should be const, but
02521    // they're not. 
02522    int rc = addrows(1, row.getNumElements(), &sense, &rhs, &r,
02523                     start, const_cast<int *>(row.getIndices()),
02524                     const_cast<double *>(row.getElements())); 
02525    assert( rc == 0 );
02526 
02527    freeCachedResults();
02528 }
02529 
02530 //#############################################################################
02531 // Private methods
02532 //#############################################################################
02533 
02534 void
02535 OsiXprSolverInterface::gutsOfCopy( const OsiXprSolverInterface & source )
02536 {
02537    source.activateMe();
02538 
02539    if ( source.xprProbname_ != "" ) {    // source has data
02540      std::ostrstream pname;
02541      pname << xprProbname_ << "#" << osiSerial_ <<'\0';
02542      xprProbname_ = pname.str();
02543      //    sprintf(xprProbname_, "%s#%d", source.xprProbname_, osiSerial_);
02544      
02545      //    cout << "Problem " << xprProbname_ << " copied to matrix ";
02546      
02547      
02548      if ( getLogFilePtr()!=NULL ) {
02549        fprintf(getLogFilePtr(),"{\n");
02550        fprintf(getLogFilePtr(),"  int matrixId = %d;\n",xprMatrixId_);
02551        fprintf(getLogFilePtr(),"  int iret = cpymat(\"%s\", &matrixId_);\n",xprProbname_.c_str());
02552        fprintf(getLogFilePtr(),"}\n");
02553      }
02554      
02555      int iret = cpymat(xprProbname_.c_str(), &xprMatrixId_);
02556      if ( iret != 0 ) getipv(N_ERRNO, &iret);
02557      assert( iret == 0 );
02558      //    cout << xprMatrixId_ << "." << endl;
02559      xprSaved_ = true;
02560    }
02561 }
02562 
02563 
02564 //-------------------------------------------------------------------
02565 void
02566 OsiXprSolverInterface::gutsOfDestructor()
02567 {
02568    freeCachedResults();
02569 
02570    assert(matrixByRow_ == NULL);
02571    assert(matrixByCol_ == NULL);
02572    assert(colupper_    == NULL);
02573    assert(collower_    == NULL);
02574    assert(rowupper_    == NULL);
02575    assert(rowlower_    == NULL);
02576                     
02577    assert(rowsense_    == NULL);
02578    assert(rhs_         == NULL);
02579    assert(rowrange_    == NULL);
02580                     
02581    assert(objcoeffs_   == NULL);
02582                     
02583    assert(colsol_      == NULL);
02584    assert(rowsol_      == NULL);
02585    assert(rowprice_    == NULL);
02586    assert(colprice_    == NULL);
02587    assert(rowact_      == NULL);
02588    assert(vartype_     == NULL);
02589 }
02590 
02591 //-------------------------------------------------------------------
02592 
02593 void
02594 OsiXprSolverInterface::freeSolution()
02595 {
02596    delete [] colsol_;       colsol_      = NULL;
02597    delete [] rowsol_;       rowsol_      = NULL;
02598    delete [] rowact_;       rowact_      = NULL;
02599    delete [] rowprice_;     rowprice_    = NULL;
02600    delete [] colprice_;     colprice_    = NULL;
02601 }
02602 
02603 //-------------------------------------------------------------------
02604 
02605 void
02606 OsiXprSolverInterface::freeCachedResults()
02607 {
02608    delete matrixByRow_;     matrixByRow_ = NULL;
02609    delete matrixByCol_;     matrixByCol_ = NULL;
02610    delete [] colupper_;     colupper_    = NULL;
02611    delete [] collower_;     collower_    = NULL;
02612    delete [] rowupper_;     rowupper_    = NULL;
02613    delete [] rowlower_;     rowlower_    = NULL;
02614 
02615    delete [] rowsense_;     rowsense_    = NULL;
02616    delete [] rhs_;          rhs_         = NULL;
02617    delete [] rowrange_;     rowrange_    = NULL;
02618 
02619    delete [] objcoeffs_;    objcoeffs_   = NULL;
02620 
02621    freeSolution();
02622 
02623    delete [] ivarind_;      ivarind_     = NULL;
02624    delete [] ivartype_;     ivartype_    = NULL;
02625    delete [] vartype_;      vartype_     = NULL;
02626 }
02627 
02628 //-------------------------------------------------------------------
02629 // Set up lists of integer variables
02630 //-------------------------------------------------------------------
02631 int
02632 OsiXprSolverInterface::getNumIntVars() const
02633 {
02634   activateMe();
02635   
02636   int     nintvars = 0, nsets = 0;
02637   
02638   if ( isDataLoaded() ) {  
02639     
02640     if (getLogFilePtr()!=NULL) {
02641       fprintf(getLogFilePtr(),"{\n");
02642       fprintf(getLogFilePtr(),"   int nintvars,nsets;\n");
02643       fprintf(getLogFilePtr(),"   getglobal(&nintvars, &nsets, NULL, NULL, NULL, NULL, NULL, NULL, NULL);\n");
02644       fprintf(getLogFilePtr(),"}\n");
02645     }
02646     getglobal(&nintvars, &nsets, 
02647       NULL, NULL, NULL, NULL, NULL, NULL, NULL);
02648   }
02649   
02650   return nintvars;
02651 }
02652 
02653 void
02654 OsiXprSolverInterface::getVarTypes() const
02655 {
02656    int     nintvars = getNumIntVars();
02657    int     nsets;
02658    int     ncols = getNumCols();
02659 
02660    if ( vartype_ == NULL && nintvars > 0 ) {
02661       activateMe();
02662    
02663     if (getLogFilePtr()!=NULL) {
02664       fprintf(getLogFilePtr(),"{\n");
02665       fprintf(getLogFilePtr(),"   int nintvars = %d;\n",nintvars);
02666       fprintf(getLogFilePtr(),"   int nsets;\n");
02667       fprintf(getLogFilePtr(),"   char ivartype[%d];\n",nintvars);
02668       fprintf(getLogFilePtr(),"   char ivarind[%d];\n",nintvars);
02669       fprintf(getLogFilePtr(),"   getglobal(&nintvars, &nsets, ivartype, ivarind, NULL, NULL, NULL, NULL, NULL);\n");
02670       fprintf(getLogFilePtr(),"}\n");
02671     }
02672 
02673       ivartype_ = new char[nintvars];
02674       ivarind_  = new int[nintvars];
02675 
02676       getglobal(&nintvars, &nsets, 
02677                 ivartype_, ivarind_, NULL, NULL, NULL, NULL, NULL);
02678       // Currently, only binary and integer vars are supported.
02679 
02680       vartype_  = new char[ncols];
02681 
02682       int     i, j;
02683       for ( i = j = 0;  j < ncols;  j++ ) {
02684          if ( i < nintvars && j == ivarind_[i] ) {
02685             vartype_[j] = ivartype_[i];
02686             i++;
02687          } else 
02688             vartype_[j] = 'C';
02689       }
02690    }
02691 }
02692 
02693 //-------------------------------------------------------------------
02694 // Make the active matrix in XPRESS-MP refer to the current solver 
02695 // object.  If another object is current, then it needs to be saved.
02696 //------------------------------------------------------------------- 
02697 const OsiXprSolverInterface *
02698 OsiXprSolverInterface::xprCurrentProblem_ = NULL;
02699 
02700 void
02701 OsiXprSolverInterface::activateMe() const
02702 {
02703    if ( xprCurrentProblem_ == this ) return; // we're already active
02704 
02705    if ( xprCurrentProblem_ ) {   // someone else is active...
02706       if ( xprCurrentProblem_->xprProbname_ != "" ) {   // ...and has data
02707       
02708         if ( getLogFilePtr()!=NULL ) {
02709           fprintf(getLogFilePtr(),"{\n");
02710           fprintf(getLogFilePtr(),"  int matrixId;\n");
02711           fprintf(getLogFilePtr(),"  int iret = savmat(& matrixId);\n");
02712         }
02713 
02714         //      cout << "Problem " << xprCurrentProblem_->xprProbname_
02715         //         << " saved as matrix ";
02716          int iret = savmat(& xprCurrentProblem_->xprMatrixId_);
02717          if ( iret != 0 ) getipv(N_ERRNO, &iret);
02718          assert( iret == 0 );
02719          //      cout << xprCurrentProblem_->xprMatrixId_ << "." << endl;
02720          xprCurrentProblem_->xprSaved_ = true;
02721      
02722         if ( getLogFilePtr()!=NULL ) {
02723           fprintf(getLogFilePtr(),"  // matrixId returned was %d;\n",xprCurrentProblem_->xprMatrixId_);
02724           fprintf(getLogFilePtr(),"}\n");
02725         }
02726 
02727       }
02728    }
02729 
02730    if ( xprSaved_ ) {           // we were saved before
02731       //    cout << "Problem " << xprProbname_ << " restored from  matrix "
02732       //         << xprMatrixId_ << "." << endl;
02733            
02734         if ( getLogFilePtr()!=NULL ) {
02735           fprintf(getLogFilePtr(),"{\n");
02736           fprintf(getLogFilePtr(),"  int iret = resmat(%d);\n",xprMatrixId_);
02737           fprintf(getLogFilePtr(),"}\n");
02738         }
02739 
02740       int iret = resmat(xprMatrixId_);
02741       if ( iret != 0 ) getipv(N_ERRNO, &iret);
02742       assert( iret == 0 );
02743       xprSaved_ = false;
02744    }
02745 
02746    xprCurrentProblem_ = this;
02747 }
02748 
02749 //-------------------------------------------------------------------
02750 
02751 bool
02752 OsiXprSolverInterface::isDataLoaded() const
02753 {
02754    return xprProbname_ != "";
02755 }
02756 
02757 //#############################################################################

Generated on Wed Dec 3 14:35:36 2003 for Osi by doxygen 1.3.5