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

OsiSpxSolverInterface Class Reference

#include <OsiSpxSolverInterface.hpp>

Inheritance diagram for OsiSpxSolverInterface:

OsiSolverInterface List of all members.

Private methods

enum  keepCachedFlag {
  KEEPCACHED_NONE = 0, KEEPCACHED_COLUMN = 1, KEEPCACHED_ROW = 2, KEEPCACHED_MATRIX = 4,
  KEEPCACHED_RESULTS = 8, KEEPCACHED_PROBLEM = KEEPCACHED_COLUMN | KEEPCACHED_ROW | KEEPCACHED_MATRIX, KEEPCACHED_ALL = KEEPCACHED_PROBLEM | KEEPCACHED_RESULTS, FREECACHED_COLUMN = KEEPCACHED_PROBLEM & !KEEPCACHED_COLUMN,
  FREECACHED_ROW = KEEPCACHED_PROBLEM & !KEEPCACHED_ROW, FREECACHED_MATRIX = KEEPCACHED_PROBLEM & !KEEPCACHED_MATRIX, FREECACHED_RESULTS = KEEPCACHED_ALL & !KEEPCACHED_RESULTS
}
void freeCachedColRim ()
 free cached column rim vectors

void freeCachedRowRim ()
 free cached row rim vectors

void freeCachedResults ()
 free cached result vectors

void freeCachedMatrix ()
 free cached matrices

void freeCachedData (int keepCached=KEEPCACHED_NONE)
 free all cached data (except specified entries, see getLpPtr())

void freeAllMemory ()
 free all allocated memory

void printBounds ()
 Just for testing purposes.


Public Member Functions

virtual void setObjSense (double s)
 Set objective function sense (1 for min (default), -1 for max,).

virtual void setColSolution (const double *colsol)
virtual void setRowPrice (const double *rowprice)
Solve methods
virtual void initialSolve ()
 Solve initial LP relaxation.

virtual void resolve ()
 Resolve an LP relaxation after problem modification.

virtual void branchAndBound ()
 Invoke solver's built-in enumeration algorithm.

Parameter set/get methods
The set methods return true if the parameter was set to the given value, false otherwise. There can be various reasons for failure: the given parameter is not applicable for the solver (e.g., refactorization frequency for the volume algorithm), the parameter is not yet implemented for the solver or simply the value of the parameter is out of the range the solver accepts. If a parameter setting call returns false check the details of your solver.

The get methods return true if the given parameter is applicable for the solver and is implemented. In this case the value of the parameter is returned in the second argument. Otherwise they return false.

bool setIntParam (OsiIntParam key, int value)
bool setDblParam (OsiDblParam key, double value)
bool getIntParam (OsiIntParam key, int &value) const
bool getDblParam (OsiDblParam key, double &value) const
bool getStrParam (OsiStrParam key, std::string &value) const
Methods returning info on how the solution process terminated
virtual bool isAbandoned () const
 Are there a numerical difficulties?

virtual bool isProvenOptimal () const
 Is optimality proven?

virtual bool isProvenPrimalInfeasible () const
 Is primal infeasiblity proven?

virtual bool isProvenDualInfeasible () const
 Is dual infeasiblity proven?

virtual bool isPrimalObjectiveLimitReached () const
 Is the given primal objective limit reached?

virtual bool isDualObjectiveLimitReached () const
 Is the given dual objective limit reached?

virtual bool isIterationLimitReached () const
 Iteration limit reached?

WarmStart related methods
CoinWarmStartgetEmptyWarmStart () const
 Get empty warm start object.

virtual CoinWarmStartgetWarmStart () const
 Get warmstarting information.

virtual bool setWarmStart (const CoinWarmStart *warmstart)
Hotstart related methods (primarily used in strong branching). <br>
The user can create a hotstart (a snapshot) of the optimization process then reoptimize over and over again always starting from there.
NOTE: between hotstarted optimizations only bound changes are allowed.

virtual void markHotStart ()
 Create a hotstart point of the optimization process.

virtual void solveFromHotStart ()
 Optimize starting from the hotstart.

virtual void unmarkHotStart ()
 Delete the snapshot.

Methods related to querying the input data
virtual int getNumCols () const
 Get number of columns.

virtual int getNumRows () const
 Get number of rows.

virtual int getNumElements () const
 Get number of nonzero elements.

virtual const double * getColLower () const
 Get pointer to array[getNumCols()] of column lower bounds.

virtual const double * getColUpper () const
 Get pointer to array[getNumCols()] of column upper bounds.

virtual const char * getRowSense () const
virtual const double * getRightHandSide () const
virtual const double * getRowRange () const
virtual const double * getRowLower () const
 Get pointer to array[getNumRows()] of row lower bounds.

virtual const double * getRowUpper () const
 Get pointer to array[getNumRows()] of row upper bounds.

virtual const double * getObjCoefficients () const
 Get pointer to array[getNumCols()] of objective function coefficients.

virtual double getObjSense () const
 Get objective function sense (1 for min (default), -1 for max).

virtual bool isContinuous (int colNumber) const
 Return true if column is continuous.

virtual const CoinPackedMatrix * getMatrixByRow () const
 Get pointer to row-wise copy of matrix.

virtual const CoinPackedMatrix * getMatrixByCol () const
 Get pointer to column-wise copy of matrix.

virtual double getInfinity () const
 Get solver's value for infinity.

Methods related to querying the solution
virtual const double * getColSolution () const
 Get pointer to array[getNumCols()] of primal solution vector.

virtual const double * getRowPrice () const
 Get pointer to array[getNumRows()] of dual prices.

virtual const double * getReducedCost () const
 Get a pointer to array[getNumCols()] of reduced costs.

virtual const double * getRowActivity () const
virtual double getObjValue () const
 Get objective function value.

virtual int getIterationCount () const
virtual std::vector< double * > getDualRays (int maxNumRays) const
virtual std::vector< double * > getPrimalRays (int maxNumRays) const
Changing bounds on variables and constraints
virtual void setObjCoeff (int elementIndex, double elementValue)
virtual void setColLower (int elementIndex, double elementValue)
virtual void setColUpper (int elementIndex, double elementValue)
virtual void setColBounds (int elementIndex, double lower, double upper)
virtual void setRowLower (int elementIndex, double elementValue)
virtual void setRowUpper (int elementIndex, double elementValue)
virtual void setRowBounds (int elementIndex, double lower, double upper)
virtual void setRowType (int index, char sense, double rightHandSide, double range)
Integrality related changing methods
virtual void setContinuous (int index)
virtual void setInteger (int index)
Methods to expand a problem.<br>
Note that if a column is added then by default it will correspond to a continuous variable.

virtual void addCol (const CoinPackedVectorBase &vec, const double collb, const double colub, const double obj)
virtual void deleteCols (const int num, const int *colIndices)
virtual void addRow (const CoinPackedVectorBase &vec, const double rowlb, const double rowub)
virtual void addRow (const CoinPackedVectorBase &vec, const char rowsen, const double rowrhs, const double rowrng)
virtual void deleteRows (const int num, const int *rowIndices)
Methods to input a problem
virtual void loadProblem (const CoinPackedMatrix &matrix, const double *collb, const double *colub, const double *obj, const double *rowlb, const double *rowub)
virtual void assignProblem (CoinPackedMatrix *&matrix, double *&collb, double *&colub, double *&obj, double *&rowlb, double *&rowub)
virtual void loadProblem (const CoinPackedMatrix &matrix, const double *collb, const double *colub, const double *obj, const char *rowsen, const double *rowrhs, const double *rowrng)
virtual void assignProblem (CoinPackedMatrix *&matrix, double *&collb, double *&colub, double *&obj, char *&rowsen, double *&rowrhs, double *&rowrng)
virtual void loadProblem (const int numcols, const int numrows, const int *start, const int *index, const double *value, const double *collb, const double *colub, const double *obj, const double *rowlb, const double *rowub)
virtual void loadProblem (const int numcols, const int numrows, const int *start, const int *index, const double *value, const double *collb, const double *colub, const double *obj, const char *rowsen, const double *rowrhs, const double *rowrng)
virtual int readMps (const char *filename, const char *extension="mps")
virtual void writeMps (const char *filename, const char *extension="mps", double objSense=0.0) const
Constructors and destructor
 OsiSpxSolverInterface ()
 Default Constructor.

virtual OsiSolverInterfaceclone (bool copyData=true) const
 Clone.

 OsiSpxSolverInterface (const OsiSpxSolverInterface &)
 Copy constructor.

OsiSpxSolverInterfaceoperator= (const OsiSpxSolverInterface &rhs)
 Assignment operator.

virtual ~OsiSpxSolverInterface ()
 Destructor.


Protected Member Functions

Protected methods
virtual void applyRowCut (const OsiRowCut &rc)
 Apply a row cut. Return true if cut was applied.

virtual void applyColCut (const OsiColCut &cc)

Private Types


Private Attributes

Private member data
soplex::SPxSolver spxsolver_
 SOPLEX solver object.

soplex::DIdxSet spxintvars_
 indices of integer variables

soplex::SoPlex::VarStatus * hotStartCStat_
 Hotstart information.

int hotStartCStatSize_
soplex::SoPlex::VarStatus * hotStartRStat_
int hotStartRStatSize_
int hotStartMaxIteration_
Cached information derived from the SOPLEX model
soplex::DVector * obj_
 Pointer to objective Vector.

char * rowsense_
 Pointer to dense vector of row sense indicators.

double * rhs_
 Pointer to dense vector of row right-hand side values.

double * rowrange_
 Pointer to dense vector of slack upper bounds for range constraints (undefined for non-range rows).

soplex::DVector * colsol_
 Pointer to primal solution vector.

soplex::DVector * rowsol_
 Pointer to dual solution vector.

soplex::DVector * redcost_
 Pointer to reduced cost vector.

soplex::DVector * rowact_
 Pointer to row activity (slack) vector.

CoinPackedMatrix * matrixByRow_
 Pointer to row-wise copy of problem matrix coefficients.

CoinPackedMatrix * matrixByCol_
 Pointer to row-wise copy of problem matrix coefficients.


Friends

void OsiSpxSolverInterfaceUnitTest (const std::string &mpsDir, const std::string &netlibDir)

Detailed Description

SOPLEX Solver Interface

Instantiation of OsiSpxSolverInterface for SOPLEX

Definition at line 26 of file OsiSpxSolverInterface.hpp.


Member Enumeration Documentation

enum OsiSpxSolverInterface::keepCachedFlag [private]
 

Enumeration values:
KEEPCACHED_NONE  discard all cached data (default)
KEEPCACHED_COLUMN  column information: objective values, lower and upper bounds, variable types
KEEPCACHED_ROW  row information: right hand sides, ranges and senses, lower and upper bounds for row
KEEPCACHED_MATRIX  problem matrix: matrix ordered by column and by row
KEEPCACHED_RESULTS  LP solution: primal and dual solution, reduced costs, row activities.
KEEPCACHED_PROBLEM  only discard cached LP solution
KEEPCACHED_ALL  keep all cached data (similar to getMutableLpPtr())
FREECACHED_COLUMN  free only cached column and LP solution information
FREECACHED_ROW  free only cached row and LP solution information
FREECACHED_MATRIX  free only cached matrix and LP solution information
FREECACHED_RESULTS  free only cached LP solution information

Definition at line 623 of file OsiSpxSolverInterface.hpp.

00624   {
00626     KEEPCACHED_NONE    = 0,
00628     KEEPCACHED_COLUMN  = 1,
00630     KEEPCACHED_ROW     = 2,
00632     KEEPCACHED_MATRIX  = 4,
00634     KEEPCACHED_RESULTS = 8,
00636     KEEPCACHED_PROBLEM = KEEPCACHED_COLUMN | KEEPCACHED_ROW | KEEPCACHED_MATRIX,
00638     KEEPCACHED_ALL     = KEEPCACHED_PROBLEM | KEEPCACHED_RESULTS,
00640     FREECACHED_COLUMN  = KEEPCACHED_PROBLEM & !KEEPCACHED_COLUMN,
00642     FREECACHED_ROW     = KEEPCACHED_PROBLEM & !KEEPCACHED_ROW,
00644     FREECACHED_MATRIX  = KEEPCACHED_PROBLEM & !KEEPCACHED_MATRIX,
00646     FREECACHED_RESULTS = KEEPCACHED_ALL & !KEEPCACHED_RESULTS
00647   };


Member Function Documentation

void OsiSpxSolverInterface::addCol const CoinPackedVectorBase vec,
const double  collb,
const double  colub,
const double  obj
[virtual]
 

Add a column (primal variable) to the problem.

Implements OsiSolverInterface.

Definition at line 981 of file OsiSpxSolverInterface.cpp.

References freeCachedData(), CoinPackedVectorBase::getElements(), CoinPackedVectorBase::getIndices(), CoinPackedVectorBase::getNumElements(), KEEPCACHED_ROW, and spxsolver_.

00984 {
00985   soplex::DSVector colvec;
00986 
00987   colvec.add( vec.getNumElements(), vec.getIndices(), vec.getElements() );
00988   spxsolver_.addCol( soplex::LPCol( obj, colvec, colub, collb ) );
00989   freeCachedData( OsiSpxSolverInterface::KEEPCACHED_ROW );
00990 }

void OsiSpxSolverInterface::addRow const CoinPackedVectorBase vec,
const double  rowlb,
const double  rowub
[virtual]
 

Add a row (constraint) to the problem.

Implements OsiSolverInterface.

Definition at line 1000 of file OsiSpxSolverInterface.cpp.

References freeCachedData(), CoinPackedVectorBase::getElements(), CoinPackedVectorBase::getIndices(), CoinPackedVectorBase::getNumElements(), KEEPCACHED_COLUMN, and spxsolver_.

Referenced by applyRowCut().

01002 {
01003   soplex::DSVector rowvec;
01004 
01005   rowvec.add( vec.getNumElements(), vec.getIndices(), vec.getElements() );
01006   spxsolver_.addRow( soplex::LPRow( rowlb, rowvec, rowub ) );
01007   freeCachedData( OsiSpxSolverInterface::KEEPCACHED_COLUMN );
01008 }

void OsiSpxSolverInterface::applyColCut const OsiColCut cc  )  [protected, virtual]
 

Apply a column cut (bound adjustment). Return true if cut was applied.

Implements OsiSolverInterface.

Definition at line 1456 of file OsiSpxSolverInterface.cpp.

References getColLower(), getColUpper(), CoinPackedVector::getElements(), CoinPackedVector::getIndices(), CoinPackedVector::getNumElements(), OsiColCut::lbs(), setColLower(), setColUpper(), and OsiColCut::ubs().

01457 {
01458   const double * soplexColLB = getColLower();
01459   const double * soplexColUB = getColUpper();
01460   const CoinPackedVector & lbs = cc.lbs();
01461   const CoinPackedVector & ubs = cc.ubs();
01462   int i;
01463 
01464   for( i = 0; i < lbs.getNumElements(); ++i ) 
01465     if ( lbs.getElements()[i] > soplexColLB[lbs.getIndices()[i]] )
01466       setColLower( lbs.getIndices()[i], lbs.getElements()[i] );
01467   for( i = 0; i < ubs.getNumElements(); ++i )
01468     if ( ubs.getElements()[i] < soplexColUB[ubs.getIndices()[i]] )
01469       setColUpper( ubs.getIndices()[i], ubs.getElements()[i] );
01470 }

void OsiSpxSolverInterface::assignProblem CoinPackedMatrix *&  matrix,
double *&  collb,
double *&  colub,
double *&  obj,
char *&  rowsen,
double *&  rowrhs,
double *&  rowrng
[virtual]
 

Load in an problem by assuming ownership of the arguments (the constraints on the rows are given by sense/rhs/range triplets). For default values see the previous method.
WARNING: The arguments passed to this method will be freed using the C++ delete and delete[] functions.

Implements OsiSolverInterface.

Definition at line 1232 of file OsiSpxSolverInterface.cpp.

References loadProblem().

01237 {
01238    loadProblem( *matrix, collb, colub, obj, rowsen, rowrhs, rowrng );
01239    delete matrix;   matrix = 0;
01240    delete[] collb;  collb = 0;
01241    delete[] colub;  colub = 0;
01242    delete[] obj;    obj = 0;
01243    delete[] rowsen; rowsen = 0;
01244    delete[] rowrhs; rowrhs = 0;
01245    delete[] rowrng; rowrng = 0;
01246 }

void OsiSpxSolverInterface::assignProblem CoinPackedMatrix *&  matrix,
double *&  collb,
double *&  colub,
double *&  obj,
double *&  rowlb,
double *&  rowub
[virtual]
 

Load in an problem by assuming ownership of the arguments (the constraints on the rows are given by lower and upper bounds). For default values see the previous method.
WARNING: The arguments passed to this method will be freed using the C++ delete and delete[] functions.

Implements OsiSolverInterface.

Definition at line 1161 of file OsiSpxSolverInterface.cpp.

References loadProblem().

01165 {
01166   loadProblem( *matrix, collb, colub, obj, rowlb, rowub );
01167   delete matrix;   matrix = 0;
01168   delete[] collb;  collb = 0;
01169   delete[] colub;  colub = 0;
01170   delete[] obj;    obj = 0;
01171   delete[] rowlb;  rowlb = 0;
01172   delete[] rowub;  rowub = 0;
01173 }

void OsiSpxSolverInterface::deleteCols const int  num,
const int *  colIndices
[virtual]
 

Remove a set of columns (primal variables) from the problem.

Implements OsiSolverInterface.

Definition at line 993 of file OsiSpxSolverInterface.cpp.

References freeCachedData(), KEEPCACHED_ROW, and spxsolver_.

00994 {
00995   spxsolver_.removeCols( const_cast<int*>(columnIndices), num );
00996   freeCachedData( OsiSpxSolverInterface::KEEPCACHED_ROW );
00997 }

void OsiSpxSolverInterface::deleteRows const int  num,
const int *  rowIndices
[virtual]
 

Delete a set of rows (constraints) from the problem.

Implements OsiSolverInterface.

Definition at line 1022 of file OsiSpxSolverInterface.cpp.

References freeCachedData(), KEEPCACHED_COLUMN, and spxsolver_.

01023 {
01024   spxsolver_.removeRows( const_cast<int*>(rowIndices), num );
01025   freeCachedData( OsiSpxSolverInterface::KEEPCACHED_COLUMN );
01026 }

std::vector< double * > OsiSpxSolverInterface::getDualRays int  maxNumRays  )  const [virtual]
 

Get as many dual rays as the solver can provide. (In case of proven primal infeasibility there should be at least one.)

NOTE for implementers of solver interfaces:
The double pointers in the vector should point to arrays of length getNumRows() and they should be allocated via new[].

NOTE for users of solver interfaces:
It is the user's responsibility to free the double pointers in the vector using delete[].

Implements OsiSolverInterface.

Definition at line 827 of file OsiSpxSolverInterface.cpp.

00828 {
00829   // *FIXME* : must write the method
00830   throw CoinError("method is not yet written", "getDualRays",
00831                   "OsiSpxSolverInterface");
00832   return std::vector<double*>();
00833 }

int OsiSpxSolverInterface::getIterationCount  )  const [virtual]
 

Get how many iterations it took to solve the problem (whatever "iteration" mean to the solver.

Implements OsiSolverInterface.

Definition at line 822 of file OsiSpxSolverInterface.cpp.

References spxsolver_.

00823 {
00824   return spxsolver_.iterations();
00825 }

std::vector< double * > OsiSpxSolverInterface::getPrimalRays int  maxNumRays  )  const [virtual]
 

Get as many primal rays as the solver can provide. (In case of proven dual infeasibility there should be at least one.)

NOTE for implementers of solver interfaces:
The double pointers in the vector should point to arrays of length getNumCols() and they should be allocated via new[].

NOTE for users of solver interfaces:
It is the user's responsibility to free the double pointers in the vector using delete[].

Implements OsiSolverInterface.

Definition at line 835 of file OsiSpxSolverInterface.cpp.

00836 {
00837   // *FIXME* : must write the method
00838   throw CoinError("method is not yet written", "getPrimalRays",
00839                   "OsiSpxSolverInterface");
00840   return std::vector<double*>();
00841 }

const double * OsiSpxSolverInterface::getRightHandSide  )  const [virtual]
 

Get pointer to array[getNumRows()] of rows right-hand sides

  • if rowsense()[i] == 'L' then rhs()[i] == rowupper()[i]
  • if rowsense()[i] == 'G' then rhs()[i] == rowlower()[i]
  • if rowsense()[i] == 'R' then rhs()[i] == rowupper()[i]
  • if rowsense()[i] == 'N' then rhs()[i] == 0.0

Implements OsiSolverInterface.

Definition at line 538 of file OsiSpxSolverInterface.cpp.

References OsiSolverInterface::convertBoundToSense(), getNumRows(), rhs_, rowrange_, rowsense_, and spxsolver_.

Referenced by getRowRange(), getRowSense(), and printBounds().

00539 {
00540   if ( rhs_ == NULL )
00541     {
00542       int nrows = getNumRows();
00543       if( nrows > 0 ) 
00544         {
00545           int    row;
00546 
00547           assert( rowrange_ == NULL );
00548           assert( rowsense_ == NULL );
00549 
00550           rhs_      = new double[nrows];
00551           rowrange_ = new double[nrows];
00552           rowsense_ = new char[nrows];
00553           
00554           for( row = 0; row < nrows; ++row )
00555             convertBoundToSense( spxsolver_.lhs( row ), spxsolver_.rhs( row ),
00556                                  rowsense_[row], rhs_[row], rowrange_[row] );
00557         }
00558     }
00559   return rhs_;
00560 }

const double * OsiSpxSolverInterface::getRowActivity  )  const [virtual]
 

Get pointer to array[getNumRows()] of row activity levels (constraint matrix times the solution vector

Implements OsiSolverInterface.

Definition at line 779 of file OsiSpxSolverInterface.cpp.

References getNumRows(), isProvenOptimal(), rowact_, and spxsolver_.

00780 {
00781   if( rowact_ == NULL )
00782     {
00783       int nrows = getNumRows();
00784       if( nrows > 0 )
00785         {
00786           rowact_ = new soplex::DVector( nrows );
00787           if( isProvenOptimal() )
00788             spxsolver_.getSlacks( *rowact_ );
00789           else
00790             rowact_->clear();
00791         }
00792       else
00793         return NULL;
00794     }
00795   return rowact_->get_const_ptr();
00796 }

const double * OsiSpxSolverInterface::getRowRange  )  const [virtual]
 

Get pointer to array[getNumRows()] of row ranges.

  • if rowsense()[i] == 'R' then rowrange()[i] == rowupper()[i] - rowlower()[i]
  • if rowsense()[i] != 'R' then rowrange()[i] is 0.0

Implements OsiSolverInterface.

Definition at line 562 of file OsiSpxSolverInterface.cpp.

References getNumRows(), getRightHandSide(), and rowrange_.

Referenced by printBounds().

00563 {
00564   if ( rowrange_==NULL ) 
00565     {
00566       // rowrange is determined with rhs, so invoke rhs
00567       getRightHandSide();
00568       assert( rowrange_ != NULL || getNumRows() == 0 );
00569     }
00570   return rowrange_;
00571 }

const char * OsiSpxSolverInterface::getRowSense  )  const [virtual]
 

Get pointer to array[getNumRows()] of row constraint senses.

  • 'L': <= constraint
  • 'E': = constraint
  • 'G': >= constraint
  • 'R': ranged constraint
  • 'N': free constraint

Implements OsiSolverInterface.

Definition at line 527 of file OsiSpxSolverInterface.cpp.

References getNumRows(), getRightHandSide(), and rowsense_.

Referenced by printBounds().

00528 {
00529   if ( rowsense_ == NULL )
00530     {
00531       // rowsense is determined with rhs, so invoke rhs
00532       getRightHandSide();
00533       assert( rowsense_ != NULL || getNumRows() == 0 );
00534     }
00535   return rowsense_;
00536 }

void OsiSpxSolverInterface::loadProblem const int  numcols,
const int  numrows,
const int *  start,
const int *  index,
const double *  value,
const double *  collb,
const double *  colub,
const double *  obj,
const char *  rowsen,
const double *  rowrhs,
const double *  rowrng
[virtual]
 

Just like the other loadProblem() methods except that the matrix is given in a standard column major ordered format (without gaps).

Implements OsiSolverInterface.

Definition at line 1281 of file OsiSpxSolverInterface.cpp.

References OsiSolverInterface::convertSenseToBound(), and loadProblem().

01288 {
01289   double* rowlb = new double[numrows];
01290   double* rowub = new double[numrows];
01291   int     row;
01292 
01293   for( row = 0; row < numrows; ++row )
01294     convertSenseToBound( rowsen[row], rowrhs[row], rowrng[row], rowlb[row], rowub[row] );
01295   
01296   loadProblem( numcols, numrows, start, index, value, collb, colub, obj, rowlb, rowub );
01297 
01298   delete[] rowlb;
01299   delete[] rowub;
01300 }

void OsiSpxSolverInterface::loadProblem const int  numcols,
const int  numrows,
const int *  start,
const int *  index,
const double *  value,
const double *  collb,
const double *  colub,
const double *  obj,
const double *  rowlb,
const double *  rowub
[virtual]
 

Just like the other loadProblem() methods except that the matrix is given in a standard column major ordered format (without gaps).

Implements OsiSolverInterface.

Definition at line 1251 of file OsiSpxSolverInterface.cpp.

References freeCachedData(), KEEPCACHED_NONE, spxintvars_, and spxsolver_.

01257 {
01258   int col, pos;
01259   soplex::LPColSet colset( numcols, start[numcols] );
01260   soplex::DSVector colvec;
01261   
01262   spxsolver_.clear();
01263   spxintvars_.clear();
01264   freeCachedData( OsiSpxSolverInterface::KEEPCACHED_NONE );
01265 
01266   for( col = 0; col < numcols; ++col )
01267     {
01268       pos = start[col];
01269       colvec.clear();
01270       colvec.add( start[col+1] - pos, &(index[pos]), &(value[pos]) );
01271       colset.add( obj[col], collb[col], colvec, colub[col] );
01272     }
01273   
01274   spxsolver_.addCols( colset );
01275   spxsolver_.changeRange( soplex::Vector( numrows, const_cast<double*>(rowlb) ), soplex::Vector( numrows, const_cast<double*>(rowub) ) );
01276 }

void OsiSpxSolverInterface::loadProblem const CoinPackedMatrix &  matrix,
const double *  collb,
const double *  colub,
const double *  obj,
const char *  rowsen,
const double *  rowrhs,
const double *  rowrng
[virtual]
 

Load in an problem by copying the arguments (the constraints on the rows are given by sense/rhs/range triplets). If a pointer is 0 then the following values are the default:

  • colub: all columns have upper bound infinity
  • collb: all columns have lower bound 0
  • obj: all variables have 0 objective coefficient
  • rowsen: all rows are >=
  • rowrhs: all right hand sides are 0
  • rowrng: 0 for the ranged rows

Implements OsiSolverInterface.

Definition at line 1178 of file OsiSpxSolverInterface.cpp.

References OsiSolverInterface::convertSenseToBound(), and loadProblem().

01183 {
01184   int     nrows = matrix.getNumRows();
01185   double* rowlb = new double[nrows];
01186   double* rowub = new double[nrows];
01187   int     row;
01188   char    *therowsen;
01189   double  *therowrhs, *therowrng;
01190   
01191   if( rowsen == NULL )
01192     {
01193       therowsen = new char[nrows];
01194       CoinFillN( therowsen, nrows, 'G' );
01195     }
01196   else
01197     therowsen = const_cast<char*>(rowsen);
01198   if( rowrhs == NULL )
01199     {
01200       therowrhs = new double[nrows];
01201       CoinFillN( therowrhs, nrows, 0.0 );
01202     }
01203   else
01204     therowrhs = const_cast<double*>(rowrhs);
01205   if( rowrng == NULL )
01206     {
01207       therowrng = new double[nrows];
01208       CoinFillN( therowrng, nrows, 0.0 );
01209     }
01210   else
01211     therowrng = const_cast<double*>(rowrng);
01212 
01213   for( row = 0; row < nrows; ++row )
01214     convertSenseToBound( therowsen[row], therowrhs[row], therowrng[row], rowlb[row], rowub[row] );
01215   
01216   loadProblem( matrix, collb, colub, obj, rowlb, rowub );
01217 
01218   if( rowsen == NULL )
01219     delete[] therowsen;
01220   if( rowrhs == NULL )
01221     delete[] therowrhs;
01222   if( rowrng == NULL )
01223     delete[] therowrng;
01224 
01225   delete[] rowlb;
01226   delete[] rowub;
01227 }

void OsiSpxSolverInterface::loadProblem const CoinPackedMatrix &  matrix,
const double *  collb,
const double *  colub,
const double *  obj,
const double *  rowlb,
const double *  rowub
[virtual]
 

Load in an problem by copying the arguments (the constraints on the rows are given by lower and upper bounds). If a pointer is 0 then the following values are the default:

  • colub: all columns have upper bound infinity
  • collb: all columns have lower bound 0
  • rowub: all rows have upper bound infinity
  • rowlb: all rows have lower bound -infinity
  • obj: all variables have 0 objective coefficient

Implements OsiSolverInterface.

Definition at line 1033 of file OsiSpxSolverInterface.cpp.

References freeCachedData(), getInfinity(), KEEPCACHED_NONE, spxintvars_, and spxsolver_.

Referenced by assignProblem(), and loadProblem().

01037 {
01038   int          ncols   = matrix.getNumCols();
01039   int          nrows   = matrix.getNumRows();
01040   const int    *length = matrix.getVectorLengths();
01041   const int    *start  = matrix.getVectorStarts();
01042   const double *elem   = matrix.getElements();
01043   const int    *index  = matrix.getIndices();
01044   double       *thecollb, *thecolub, *theobj, *therowlb, *therowub;
01045   
01046   // create defaults if parameter is NULL
01047   if( collb == NULL )
01048     {
01049       thecollb = new double[ncols];
01050       CoinFillN( thecollb, ncols, 0.0 );
01051     }
01052   else
01053     thecollb = const_cast<double*>(collb);
01054   if( colub == NULL )
01055     {
01056       thecolub = new double[ncols];
01057       CoinFillN( thecolub, ncols, getInfinity() );
01058     }
01059   else
01060     thecolub = const_cast<double*>(colub);
01061   if( obj == NULL )
01062     {
01063       theobj = new double[ncols];
01064       CoinFillN( theobj, ncols, 0.0 );
01065     }
01066   else
01067     theobj = const_cast<double*>(obj);
01068   if( rowlb == NULL )
01069     {
01070       therowlb = new double[nrows];
01071       CoinFillN( therowlb, nrows, -getInfinity() );
01072     }
01073   else
01074     therowlb = const_cast<double*>(rowlb);
01075   if( rowub == NULL )
01076     {
01077       therowub = new double[nrows];
01078       CoinFillN( therowub, nrows, +getInfinity() );
01079     }
01080   else
01081     therowub = const_cast<double*>(rowub);
01082 
01083   // copy problem into spxsolver_
01084   spxsolver_.clear();
01085   spxintvars_.clear();
01086   freeCachedData( OsiSpxSolverInterface::KEEPCACHED_NONE );
01087 
01088   if( matrix.isColOrdered() )
01089     {
01090       int row, col, pos;
01091       soplex::LPRowSet rowset( nrows, 0 );
01092       soplex::DSVector rowvec;
01093       soplex::LPColSet colset( ncols, matrix.getNumElements() );
01094       soplex::DSVector colvec;
01095 
01096       /* insert empty rows */
01097       rowvec.clear();
01098       for( row = 0; row < nrows; ++row )
01099          rowset.add( therowlb[row], rowvec, therowub[row] );
01100       spxsolver_.addRows( rowset );
01101 
01102       /* create columns */
01103       for( col = 0; col < ncols; ++col )
01104         {
01105           pos = start[col];
01106           colvec.clear();
01107           colvec.add( length[col], &(index[pos]), &(elem[pos]) );
01108           colset.add( theobj[col], thecollb[col], colvec, thecolub[col] );
01109         }
01110       
01111       spxsolver_.addCols( colset );
01112       // spxsolver_.changeRange( soplex::Vector( nrows, therowlb ), soplex::Vector( nrows, therowub ) );
01113     }
01114   else
01115     {
01116       int row, col, pos;
01117       soplex::LPRowSet rowset( nrows, matrix.getNumElements() );
01118       soplex::DSVector rowvec;
01119       soplex::LPColSet colset( ncols, 0 );
01120       soplex::DSVector colvec;
01121 
01122       /* insert empty columns */
01123       colvec.clear();
01124       for( col = 0; col < ncols; ++col )
01125          colset.add( theobj[col], thecollb[col], colvec, thecolub[col] );
01126       spxsolver_.addCols( colset );
01127 
01128       /* create rows */
01129       for( row = 0; row < nrows; ++row )
01130         {
01131           pos = start[row];
01132           rowvec.clear();
01133           rowvec.add( length[row], &(index[pos]), &(elem[pos]) );
01134           rowset.add( therowlb[row], rowvec, therowub[row] );
01135         }
01136       
01137       spxsolver_.addRows( rowset );
01138       // spxsolver_.changeObj( soplex::Vector( ncols, theobj ) );
01139       // spxsolver_.changeBounds( soplex::Vector( ncols, thecollb ), soplex::Vector( ncols, thecolub ) );
01140     }
01141 
01142   // switch sense to minimization problem
01143   spxsolver_.changeSense( soplex::SoPlex::MINIMIZE );
01144 
01145   // delete default arrays if neccessary
01146   if( collb == NULL )
01147     delete[] thecollb;
01148   if( colub == NULL )
01149     delete[] thecolub;
01150   if( obj == NULL )
01151     delete[] theobj;
01152   if( rowlb == NULL )
01153     delete[] therowlb;
01154   if( rowub == NULL )
01155     delete[] therowub;
01156 }

int OsiSpxSolverInterface::readMps const char *  filename,
const char *  extension = "mps"
[virtual]
 

Read an mps file from the given filename

Reimplemented from OsiSolverInterface.

Definition at line 1305 of file OsiSpxSolverInterface.cpp.

References OsiSolverInterface::readMps(), spxintvars_, and spxsolver_.

01307 {
01308 #if 0
01309   std::string f(filename);
01310   std::string e(extension);
01311   std::string fullname = f + "." + e;
01312 
01313   spxsolver_.clear();
01314   spxintvars_.clear();
01315   if( !spxsolver_.readFile( fullname.c_str(), NULL, NULL, &spxintvars_ ) )
01316     throwSPXerror( "error reading file <" + fullname + ">", "readMps" );
01317 #endif
01318   // just call base class method
01319   return OsiSolverInterface::readMps(filename,extension);
01320 }

void OsiSpxSolverInterface::setColBounds int  elementIndex,
double  lower,
double  upper
[virtual]
 

Set a single column lower and upper bound
The default implementation just invokes setColLower and setColUpper

Reimplemented from OsiSolverInterface.

Definition at line 865 of file OsiSpxSolverInterface.cpp.

References FREECACHED_COLUMN, freeCachedData(), and spxsolver_.

00866 {
00867   spxsolver_.changeBounds( elementIndex, lower, upper );
00868   freeCachedData( OsiSpxSolverInterface::FREECACHED_COLUMN );
00869 }

void OsiSpxSolverInterface::setColLower int  elementIndex,
double  elementValue
[virtual]
 

Set a single column lower bound
Use -DBL_MAX for -infinity.

Implements OsiSolverInterface.

Definition at line 853 of file OsiSpxSolverInterface.cpp.

References FREECACHED_COLUMN, freeCachedData(), and spxsolver_.

Referenced by applyColCut().

00854 {
00855   spxsolver_.changeLower( elementIndex, elementValue );
00856   freeCachedData( OsiSpxSolverInterface::FREECACHED_COLUMN );
00857 }

void OsiSpxSolverInterface::setColSolution const double *  colsol  )  [virtual]
 

Set the primal solution column values

colsol[numcols()] is an array of values of the problem column variables. These values are copied to memory owned by the solver object or the solver. They will be returned as the result of colsol() until changed by another call to setColsol() or by a call to any solver routine. Whether the solver makes use of the solution in any way is solver-dependent.

Implements OsiSolverInterface.

Definition at line 939 of file OsiSpxSolverInterface.cpp.

References colsol_, and getNumCols().

Referenced by operator=(), and OsiSpxSolverInterface().

00940 {
00941   int col;
00942   int ncols = getNumCols();
00943 
00944   if( colsol_ != NULL )
00945     delete colsol_;
00946 
00947   if( ncols > 0 && cs != NULL )
00948     {
00949       colsol_ = new soplex::DVector( ncols );
00950       for( col = 0; col < ncols; ++col )
00951         (*colsol_)[col] = cs[col];
00952     }
00953   else
00954     colsol_ = NULL;
00955 }

void OsiSpxSolverInterface::setColUpper int  elementIndex,
double  elementValue
[virtual]
 

Set a single column upper bound
Use DBL_MAX for infinity.

Implements OsiSolverInterface.

Definition at line 859 of file OsiSpxSolverInterface.cpp.

References FREECACHED_COLUMN, freeCachedData(), and spxsolver_.

Referenced by applyColCut().

00860 {  
00861   spxsolver_.changeUpper( elementIndex, elementValue );
00862   freeCachedData( OsiSpxSolverInterface::FREECACHED_COLUMN );
00863 } 

void OsiSpxSolverInterface::setContinuous int  index  )  [virtual]
 

Set the index-th variable to be a continuous variable

Implements OsiSolverInterface.

Definition at line 903 of file OsiSpxSolverInterface.cpp.

References FREECACHED_COLUMN, freeCachedData(), and spxintvars_.

00904 {
00905   int pos = spxintvars_.number( index );
00906   if( pos >= 0 )
00907     {
00908       spxintvars_.remove( pos );
00909       freeCachedData( OsiSpxSolverInterface::FREECACHED_COLUMN );
00910     }
00911 }

void OsiSpxSolverInterface::setInteger int  index  )  [virtual]
 

Set the index-th variable to be an integer variable

Implements OsiSolverInterface.

Definition at line 914 of file OsiSpxSolverInterface.cpp.

References FREECACHED_COLUMN, freeCachedData(), and spxintvars_.

00915 {
00916   int pos = spxintvars_.number( index );
00917   if( pos < 0 )
00918     {
00919       spxintvars_.addIdx( index );
00920       freeCachedData( OsiSpxSolverInterface::FREECACHED_COLUMN );
00921     }
00922 }

void OsiSpxSolverInterface::setObjCoeff int  elementIndex,
double  elementValue
[virtual]
 

Set an objective function coefficient

Implements OsiSolverInterface.

Definition at line 847 of file OsiSpxSolverInterface.cpp.

References FREECACHED_COLUMN, freeCachedData(), and spxsolver_.

00848 {
00849   spxsolver_.changeObj( elementIndex, elementValue );
00850   freeCachedData( OsiSpxSolverInterface::FREECACHED_COLUMN );
00851 }

void OsiSpxSolverInterface::setRowBounds int  elementIndex,
double  lower,
double  upper
[virtual]
 

Set a single row lower and upper bound
The default implementation just invokes setRowUower and setRowUpper

Reimplemented from OsiSolverInterface.

Definition at line 886 of file OsiSpxSolverInterface.cpp.

References FREECACHED_ROW, freeCachedData(), and spxsolver_.

Referenced by setRowType().

00887 {
00888   spxsolver_.changeRange( elementIndex, lower, upper );
00889   freeCachedData( OsiSpxSolverInterface::FREECACHED_ROW );
00890 }

void OsiSpxSolverInterface::setRowLower int  elementIndex,
double  elementValue
[virtual]
 

Set a single row lower bound
Use -DBL_MAX for -infinity.

Implements OsiSolverInterface.

Definition at line 872 of file OsiSpxSolverInterface.cpp.

References FREECACHED_ROW, freeCachedData(), and spxsolver_.

00873 {
00874   spxsolver_.changeLhs( i, elementValue );
00875   freeCachedData( OsiSpxSolverInterface::FREECACHED_ROW );
00876 }

void OsiSpxSolverInterface::setRowPrice const double *  rowprice  )  [virtual]
 

Set dual solution vector

rowprice[numrows()] is an array of values of the problem row dual variables. These values are copied to memory owned by the solver object or the solver. They will be returned as the result of rowprice() until changed by another call to setRowprice() or by a call to any solver routine. Whether the solver makes use of the solution in any way is solver-dependent.

Implements OsiSolverInterface.

Definition at line 959 of file OsiSpxSolverInterface.cpp.

References getNumRows(), and rowsol_.

Referenced by operator=(), and OsiSpxSolverInterface().

00960 {
00961   int row;
00962   int nrows = getNumRows();
00963 
00964   if( rowsol_ != NULL )
00965     delete rowsol_;
00966 
00967   if( nrows > 0 && rs != NULL )
00968     {
00969       rowsol_ = new soplex::DVector( nrows );
00970       for( row = 0; row < nrows; ++row )
00971         (*rowsol_)[row] = rs[row];
00972     }
00973   else
00974     rowsol_ = NULL;
00975 }

void OsiSpxSolverInterface::setRowType int  index,
char  sense,
double  rightHandSide,
double  range
[virtual]
 

Set the type of a single row

Implements OsiSolverInterface.

Definition at line 893 of file OsiSpxSolverInterface.cpp.

References OsiSolverInterface::convertSenseToBound(), and setRowBounds().

00895 {
00896   double lower, upper;
00897 
00898   convertSenseToBound( sense, rightHandSide, range, lower, upper );
00899   setRowBounds( i, lower, upper );
00900 }

void OsiSpxSolverInterface::setRowUpper int  elementIndex,
double  elementValue
[virtual]
 

Set a single row upper bound
Use DBL_MAX for infinity.

Implements OsiSolverInterface.

Definition at line 879 of file OsiSpxSolverInterface.cpp.

References FREECACHED_ROW, freeCachedData(), and spxsolver_.

00880 {
00881   spxsolver_.changeRhs( i, elementValue );
00882   freeCachedData( OsiSpxSolverInterface::FREECACHED_ROW );
00883 }

bool OsiSpxSolverInterface::setWarmStart const CoinWarmStart warmstart  )  [virtual]
 

Set warmstarting information. Return true/false depending on whether the warmstart information was accepted or not.

Implements OsiSolverInterface.

Definition at line 358 of file OsiSpxSolverInterface.cpp.

References CoinWarmStartBasis::getArtifStatus(), CoinWarmStartBasis::getNumArtificial(), getNumCols(), getNumRows(), CoinWarmStartBasis::getNumStructural(), CoinWarmStartBasis::getStructStatus(), and spxsolver_.

00359 {
00360   const CoinWarmStartBasis* ws = dynamic_cast<const CoinWarmStartBasis*>(warmstart);
00361   int numcols, numrows, i;
00362   soplex::SoPlex::VarStatus *cstat, *rstat;
00363   bool retval = false;
00364 
00365   if( !ws )
00366     return false;
00367 
00368   numcols = ws->getNumStructural();
00369   numrows = ws->getNumArtificial();
00370   
00371   if( numcols != getNumCols() || numrows != getNumRows() )
00372     return false;
00373 
00374   cstat = new soplex::SoPlex::VarStatus[numcols];
00375   rstat = new soplex::SoPlex::VarStatus[numrows];
00376 
00377   for( i = 0; i < numrows; ++i )
00378     {
00379       switch( ws->getArtifStatus( i ) )
00380         {
00381         case CoinWarmStartBasis::basic:
00382           rstat[i] = soplex::SoPlex::BASIC;
00383           break;
00384         case CoinWarmStartBasis::atLowerBound:
00385           rstat[i] = soplex::SoPlex::ON_LOWER;
00386           break;
00387         case CoinWarmStartBasis::atUpperBound:
00388           rstat[i] = soplex::SoPlex::ON_UPPER;
00389           break;
00390         case CoinWarmStartBasis::isFree:
00391           rstat[i] = soplex::SoPlex::ZERO;
00392           break;
00393         default:  // unknown row status
00394           retval = false;
00395           goto TERMINATE;
00396         }
00397     }
00398   for( i = 0; i < numcols; ++i )
00399     {
00400       switch( ws->getStructStatus( i ) )
00401         {
00402         case CoinWarmStartBasis::basic:
00403           cstat[i] = soplex::SoPlex::BASIC;
00404           break;
00405         case CoinWarmStartBasis::atLowerBound:
00406           cstat[i] = soplex::SoPlex::ON_LOWER;
00407           break;
00408         case CoinWarmStartBasis::atUpperBound:
00409           cstat[i] = soplex::SoPlex::ON_UPPER;
00410           break;
00411         case CoinWarmStartBasis::isFree:
00412           cstat[i] = soplex::SoPlex::ZERO;
00413           break;
00414         default:  // unknown column status
00415           retval = false;
00416           goto TERMINATE;
00417         }
00418     }
00419 
00420   spxsolver_.setBasis( rstat, cstat );
00421   retval = true;
00422 
00423  TERMINATE:
00424   delete[] cstat;
00425   delete[] rstat;
00426   return retval;
00427 }

void OsiSpxSolverInterface::writeMps const char *  filename,
const char *  extension = "mps",
double  objSense = 0.0
const [virtual]
 

Write the problem into an mps file of the given filename. If objSense is non zero then -1.0 forces the code to write a maximization objective and +1.0 to write a minimization one. If 0.0 then solver can do what it wants

Implements OsiSolverInterface.

Definition at line 1325 of file OsiSpxSolverInterface.cpp.

References spxsolver_.

01328 {
01329   std::string f(filename);
01330   std::string e(extension);
01331   std::string fullname = f + ".lp"; // SOPLEX cannot write MPS files yet! + "." + e;
01332   spxsolver_.dumpFile( fullname.c_str() );
01333   std::cout << "WARNING: LP file <" << fullname << "> created instead of "
01334             << "MPS file <" << f << "." << e << "> !" << std::endl;
01335 }


Friends And Related Function Documentation

void OsiSpxSolverInterfaceUnitTest const std::string &  mpsDir,
const std::string &  netlibDir
[friend]
 

A function that tests the methods in the OsiOslSolverInterface class. The only reason for it not to be a member method is that this way it doesn't have to be compiled into the library. And that's a gain, because the library should be compiled with optimization on, but this method should be compiled with debugging.

Definition at line 71 of file OsiSpxSolverInterfaceTest.cpp.

00072 {
00073   // Test default constructor
00074   {
00075     OsiSpxSolverInterface m;
00076     assert( m.rowsense_==NULL );
00077     assert( m.rhs_==NULL );
00078     assert( m.rowrange_==NULL );
00079     assert( m.colsol_==NULL );
00080     assert( m.rowsol_==NULL );
00081     assert( m.matrixByRow_==NULL );
00082     assert( m.matrixByCol_==NULL );
00083     assert( m.getApplicationData() == NULL );
00084     int i=2346;
00085     m.setApplicationData(&i);
00086     assert( *((int *)(m.getApplicationData())) == i );
00087   }
00088 
00089   {    
00090     CoinRelFltEq eq;
00091     OsiSpxSolverInterface m;
00092     std::string fn = mpsDir+"exmip1";
00093     m.readMps(fn.c_str(),"mps");
00094     int ad = 13579;
00095     m.setApplicationData(&ad);
00096     assert( *((int *)(m.getApplicationData())) == ad );
00097 
00098     {
00099       assert( m.getNumCols()==8 );
00100       const CoinPackedMatrix * colCopy = m.getMatrixByCol();
00101       assert( colCopy->getNumCols() == 8 );
00102       assert( colCopy->getMajorDim() == 8 );
00103       assert( colCopy->getNumRows() == 5 );
00104       assert( colCopy->getMinorDim() == 5 );
00105       assert (colCopy->getVectorLengths()[7] == 2 );
00106       CoinPackedMatrix revColCopy;
00107       revColCopy.reverseOrderedCopyOf(*colCopy);
00108       CoinPackedMatrix rev2ColCopy;      
00109       rev2ColCopy.reverseOrderedCopyOf(revColCopy);
00110       assert( rev2ColCopy.getNumCols() == 8 );
00111       assert( rev2ColCopy.getMajorDim() == 8 );
00112       assert( rev2ColCopy.getNumRows() == 5 );
00113       assert( rev2ColCopy.getMinorDim() == 5 );
00114       assert( rev2ColCopy.getVectorLengths()[7] == 2 );
00115     }
00116     
00117     {
00118       OsiSpxSolverInterface im;    
00119       assert( im.getNumCols() == 0 ); 
00120     }
00121     
00122     // Test copy constructor and assignment operator
00123     {
00124       OsiSpxSolverInterface lhs;
00125       {      
00126         assert( *((int *)(m.getApplicationData())) == ad );
00127         OsiSpxSolverInterface im(m);   
00128         assert( *((int *)(im.getApplicationData())) == ad );
00129 
00130         OsiSpxSolverInterface imC1(im);
00131         assert( imC1.getNumCols() == im.getNumCols() );
00132         assert( imC1.getNumRows() == im.getNumRows() );   
00133         assert( *((int *)(imC1.getApplicationData())) == ad ); 
00134         
00135         //im.setModelPtr(m);
00136         
00137         OsiSpxSolverInterface imC2(im);
00138         assert( imC2.getNumCols() == im.getNumCols() );
00139         assert( imC2.getNumRows() == im.getNumRows() );  
00140         assert( *((int *)(imC2.getApplicationData())) == ad ); 
00141         
00142         lhs=imC2;
00143       }
00144       // Test that lhs has correct values even though rhs has gone out of scope
00145 
00146       assert( lhs.getNumCols() == m.getNumCols() );
00147       assert( lhs.getNumRows() == m.getNumRows() );      
00148       assert( *((int *)(lhs.getApplicationData())) == ad );
00149     }
00150     
00151     // Test clone
00152     {
00153       OsiSpxSolverInterface soplexSi(m);
00154       OsiSolverInterface * siPtr = &soplexSi;
00155       OsiSolverInterface * siClone = siPtr->clone();
00156       OsiSpxSolverInterface * soplexClone = dynamic_cast<OsiSpxSolverInterface*>(siClone);
00157       assert( soplexClone != NULL );
00158       assert( soplexClone->getNumRows() == soplexSi.getNumRows() );
00159       assert( soplexClone->getNumCols() == m.getNumCols() );
00160       
00161       assert( *((int *)(soplexClone->getApplicationData())) == ad );
00162       delete siClone;
00163     }
00164    
00165     // test infinity
00166     {
00167       OsiSpxSolverInterface si;
00168       assert( eq( si.getInfinity(), soplex::infinity ) );
00169     }     
00170     
00171     // Test setting solution
00172     {
00173       OsiSpxSolverInterface m1(m);
00174       int i;
00175 
00176       double * cs = new double[m1.getNumCols()];
00177       for ( i = 0;  i < m1.getNumCols();  i++ ) 
00178         cs[i] = i + .5;
00179       m1.setColSolution(cs);
00180       for ( i = 0;  i < m1.getNumCols();  i++ ) 
00181         assert(m1.getColSolution()[i] == i + .5);
00182       
00183       double * rs = new double[m1.getNumRows()];
00184       for ( i = 0;  i < m1.getNumRows();  i++ ) 
00185         rs[i] = i - .5;
00186       m1.setRowPrice(rs);
00187       for ( i = 0;  i < m1.getNumRows();  i++ ) 
00188         assert(m1.getRowPrice()[i] == i - .5);
00189 
00190       delete [] cs;
00191       delete [] rs;
00192     }
00193     
00194     // Test fraction Indices
00195     {
00196       OsiSpxSolverInterface fim;
00197       std::string fn = mpsDir+"exmip1";
00198       fim.readMps(fn.c_str(),"mps");
00199       //fim.setModelPtr(m);
00200       // exmip1.mps has 2 integer variables with index 2 & 3
00201       assert(  fim.isContinuous(0) );
00202       assert(  fim.isContinuous(1) );
00203       assert( !fim.isContinuous(2) );
00204       assert( !fim.isContinuous(3) );
00205       assert(  fim.isContinuous(4) );
00206       
00207       assert( !fim.isInteger(0) );
00208       assert( !fim.isInteger(1) );
00209       assert(  fim.isInteger(2) );
00210       assert(  fim.isInteger(3) );
00211       assert( !fim.isInteger(4) );
00212       
00213       assert( !fim.isBinary(0) );
00214       assert( !fim.isBinary(1) );
00215       assert(  fim.isBinary(2) );
00216       assert(  fim.isBinary(3) );
00217       assert( !fim.isBinary(4) );
00218       
00219       assert( !fim.isIntegerNonBinary(0) );
00220       assert( !fim.isIntegerNonBinary(1) );
00221       assert( !fim.isIntegerNonBinary(2) );
00222       assert( !fim.isIntegerNonBinary(3) );
00223       assert( !fim.isIntegerNonBinary(4) );
00224 
00225       
00226       // Test fractionalIndices
00227       {
00228         // Set a solution vector
00229         double * cs = new double[fim.getNumCols()];
00230         for ( int i = 0;  i < fim.getNumCols();  cs[i++] = 0.0 );
00231         cs[2] = 2.9;
00232         cs[3] = 3.0;
00233         fim.setColSolution(cs);
00234 
00235         OsiVectorInt fi = fim.getFractionalIndices();
00236         assert( fi.size() == 1 );
00237         assert( fi[0]==2 );
00238         
00239         // Set integer variables very close to integer values
00240         cs[2] = 5 + .00001/2.;
00241         cs[3] = 8 - .00001/2.;
00242         fim.setColSolution(cs);
00243         fi = fim.getFractionalIndices(1e-5);
00244         assert( fi.size() == 0 );
00245         
00246         // Set integer variables close, but beyond tolerances
00247         cs[2] = 5 + .00001*2.;
00248         cs[3] = 8 - .00001*2.;
00249         fim.setColSolution(cs);
00250         fi = fim.getFractionalIndices(1e-5);
00251         assert( fi.size() == 2 );
00252         assert( fi[0]==2 );
00253         assert( fi[1]==3 );
00254 
00255         delete [] cs;
00256       }
00257      
00258       // Change data so column 2 & 3 are integerNonBinary
00259       fim.setColUpper(2, 5);
00260       fim.setColUpper(3, 6.0);
00261       assert( !fim.isBinary(0) );
00262       assert( !fim.isBinary(1) );
00263       assert( !fim.isBinary(2) );
00264       assert( !fim.isBinary(3) );
00265       assert( !fim.isBinary(4) );
00266       
00267       assert( !fim.isIntegerNonBinary(0) );
00268       assert( !fim.isIntegerNonBinary(1) );
00269       assert(  fim.isIntegerNonBinary(2) );
00270       assert(  fim.isIntegerNonBinary(3) );
00271       assert( !fim.isIntegerNonBinary(4) );
00272     }
00273     
00274     // Test apply cuts method
00275     {      
00276       OsiSpxSolverInterface im(m);
00277       OsiCuts cuts;
00278       
00279       // Generate some cuts 
00280       {
00281         // Get number of rows and columns in model
00282         int nr=im.getNumRows();
00283         int nc=im.getNumCols();
00284         assert( nr == 5 );
00285         assert( nc == 8 );
00286         
00287         // Generate a valid row cut from thin air
00288         int c;
00289         {
00290           int *inx = new int[nc];
00291           for (c=0;c<nc;c++) inx[c]=c;
00292           double *el = new double[nc];
00293           for (c=0;c<nc;c++) el[c]=((double)c)*((double)c);
00294           
00295           OsiRowCut rc;
00296           rc.setRow(nc,inx,el);
00297           rc.setLb(-100.);
00298           rc.setUb(100.);
00299           rc.setEffectiveness(22);
00300           
00301           cuts.insert(rc);
00302           delete[]el;
00303           delete[]inx;
00304         }
00305         
00306         // Generate valid col cut from thin air
00307         {
00308           const double * soplexColLB = im.getColLower();
00309           const double * soplexColUB = im.getColUpper();
00310           int *inx = new int[nc];
00311           for (c=0;c<nc;c++) inx[c]=c;
00312           double *lb = new double[nc];
00313           double *ub = new double[nc];
00314           for (c=0;c<nc;c++) lb[c]=soplexColLB[c]+0.001;
00315           for (c=0;c<nc;c++) ub[c]=soplexColUB[c]-0.001;
00316           
00317           OsiColCut cc;
00318           cc.setLbs(nc,inx,lb);
00319           cc.setUbs(nc,inx,ub);
00320           
00321           cuts.insert(cc);
00322           delete [] ub;
00323           delete [] lb;
00324           delete [] inx;
00325         }
00326         
00327         {
00328           // Generate a row and column cut which have are ineffective
00329           OsiRowCut * rcP= new OsiRowCut;
00330           rcP->setEffectiveness(-1.);
00331           cuts.insert(rcP);
00332           assert(rcP==NULL);
00333           
00334           OsiColCut * ccP= new OsiColCut;
00335           ccP->setEffectiveness(-12.);
00336           cuts.insert(ccP);
00337           assert(ccP==NULL);
00338         }
00339         {
00340           //Generate inconsistent Row cut
00341           OsiRowCut rc;
00342           const int ne=1;
00343           int inx[ne]={-10};
00344           double el[ne]={2.5};
00345           rc.setRow(ne,inx,el);
00346           rc.setLb(3.);
00347           rc.setUb(4.);
00348           assert(!rc.consistent());
00349           cuts.insert(rc);
00350         }
00351         {
00352           //Generate inconsistent col cut
00353           OsiColCut cc;
00354           const int ne=1;
00355           int inx[ne]={-10};
00356           double el[ne]={2.5};
00357           cc.setUbs(ne,inx,el);
00358           assert(!cc.consistent());
00359           cuts.insert(cc);
00360         }
00361         {
00362           // Generate row cut which is inconsistent for model m
00363           OsiRowCut rc;
00364           const int ne=1;
00365           int inx[ne]={10};
00366           double el[ne]={2.5};
00367           rc.setRow(ne,inx,el);
00368           assert(rc.consistent());
00369           assert(!rc.consistent(im));
00370           cuts.insert(rc);
00371         }
00372         {
00373           // Generate col cut which is inconsistent for model m
00374           OsiColCut cc;
00375           const int ne=1;
00376           int inx[ne]={30};
00377           double el[ne]={2.0};
00378           cc.setLbs(ne,inx,el);
00379           assert(cc.consistent());
00380           assert(!cc.consistent(im));
00381           cuts.insert(cc);
00382         }
00383         {
00384           // Generate col cut which is infeasible
00385           OsiColCut cc;
00386           const int ne=1;
00387           int inx[ne]={0};
00388           double el[ne]={2.0};
00389           cc.setUbs(ne,inx,el);
00390           cc.setEffectiveness(1000.);
00391           assert(cc.consistent());
00392           assert(cc.consistent(im));
00393           assert(cc.infeasible(im));
00394           cuts.insert(cc);
00395         }
00396       }
00397       assert(cuts.sizeRowCuts()==4);
00398       assert(cuts.sizeColCuts()==5);
00399       
00400       OsiSolverInterface::ApplyCutsReturnCode rc = im.applyCuts(cuts);
00401       assert( rc.getNumIneffective() == 2 );
00402       assert( rc.getNumApplied() == 2 );
00403       assert( rc.getNumInfeasible() == 1 );
00404       assert( rc.getNumInconsistentWrtIntegerModel() == 2 );
00405       assert( rc.getNumInconsistent() == 2 );
00406       assert( cuts.sizeCuts() == rc.getNumIneffective() +
00407         rc.getNumApplied() +
00408         rc.getNumInfeasible() +
00409         rc.getNumInconsistentWrtIntegerModel() +
00410         rc.getNumInconsistent() );
00411     }
00412     {    
00413       OsiSpxSolverInterface soplexSi(m);
00414       int nc = soplexSi.getNumCols();
00415       int nr = soplexSi.getNumRows();
00416       const double * cl = soplexSi.getColLower();
00417       const double * cu = soplexSi.getColUpper();
00418       const double * rl = soplexSi.getRowLower();
00419       const double * ru = soplexSi.getRowUpper();
00420 
00421       assert( nc == 8 );
00422       assert( nr == 5 );
00423       assert( eq(cl[0],2.5) );
00424       assert( eq(cl[1],0.0) );
00425       assert( eq(cu[1],4.1) );
00426       assert( eq(cu[2],1.0) );
00427 
00428       assert( eq(rl[0],2.5) );
00429       assert( eq(rl[4],3.0) );
00430       assert( eq(ru[1],2.1) );
00431       assert( eq(ru[4],15.0) );
00432       
00433       double newCs[8] = {1., 2., 3., 4., 5., 6., 7., 8.};
00434       soplexSi.setColSolution(newCs);
00435       const double * cs = soplexSi.getColSolution();
00436       assert( eq(cs[0],1.0) );
00437       assert( eq(cs[7],8.0) );
00438       {
00439         OsiSpxSolverInterface solnSi(soplexSi);
00440         const double * cs = solnSi.getColSolution();
00441         assert( eq(cs[0],1.0) );
00442         assert( eq(cs[7],8.0) );
00443       }
00444 
00445       assert( !eq(cl[3],1.2345) );
00446       soplexSi.setColLower( 3, 1.2345 );
00447       assert( eq(soplexSi.getColLower()[3],1.2345) );
00448       
00449       assert( !eq(cu[4],10.2345) );
00450       soplexSi.setColUpper( 4, 10.2345 );
00451       assert( eq(soplexSi.getColUpper()[4],10.2345) );
00452 
00453       assert( eq(soplexSi.getObjValue(),0.0) );
00454 
00455       assert( eq( soplexSi.getObjCoefficients()[0],  1.0) );
00456       assert( eq( soplexSi.getObjCoefficients()[1],  0.0) );
00457       assert( eq( soplexSi.getObjCoefficients()[2],  0.0) );
00458       assert( eq( soplexSi.getObjCoefficients()[3],  0.0) );
00459       assert( eq( soplexSi.getObjCoefficients()[4],  2.0) );
00460       assert( eq( soplexSi.getObjCoefficients()[5],  0.0) );
00461       assert( eq( soplexSi.getObjCoefficients()[6],  0.0) );
00462       assert( eq( soplexSi.getObjCoefficients()[7], -1.0) );
00463     }
00464     
00465     // Test getMatrixByRow method
00466     { 
00467       const OsiSpxSolverInterface si(m);
00468       const CoinPackedMatrix * smP = si.getMatrixByRow();
00469       //const CoinPackedMatrix * osmP = dynamic_cast(const OsiSpxPackedMatrix*)(smP);
00470       //assert( osmP!=NULL );
00471       
00472       CoinRelFltEq eq;
00473       const double * ev = smP->getElements();
00474       assert( eq(ev[0],   3.0) );
00475       assert( eq(ev[1],   1.0) );
00476       assert( eq(ev[2],  -2.0) );
00477       assert( eq(ev[3],  -1.0) );
00478       assert( eq(ev[4],  -1.0) );
00479       assert( eq(ev[5],   2.0) );
00480       assert( eq(ev[6],   1.1) );
00481       assert( eq(ev[7],   1.0) );
00482       assert( eq(ev[8],   1.0) );
00483       assert( eq(ev[9],   2.8) );
00484       assert( eq(ev[10], -1.2) );
00485       assert( eq(ev[11],  5.6) );
00486       assert( eq(ev[12],  1.0) );
00487       assert( eq(ev[13],  1.9) );
00488       
00489       const int * mi = smP->getVectorStarts();
00490       assert( mi[0]==0 );
00491       assert( mi[1]==5 );
00492       assert( mi[2]==7 );
00493       assert( mi[3]==9 );
00494       assert( mi[4]==11 );
00495       assert( mi[5]==14 );
00496       
00497       const int * ei = smP->getIndices();
00498       assert( ei[0]  ==  0 );
00499       assert( ei[1]  ==  1 );
00500       assert( ei[2]  ==  3 );
00501       assert( ei[3]  ==  4 );
00502       assert( ei[4]  ==  7 );
00503       assert( ei[5]  ==  1 );
00504       assert( ei[6]  ==  2 );
00505       assert( ei[7]  ==  2 );
00506       assert( ei[8]  ==  5 );
00507       assert( ei[9]  ==  3 );
00508       assert( ei[10] ==  6 );
00509       assert( ei[11] ==  0 );
00510       assert( ei[12] ==  4 );
00511       assert( ei[13] ==  7 );    
00512       
00513       assert( smP->getMajorDim() == 5 ); 
00514       assert( smP->getNumElements() == 14 );
00515       
00516     }
00517     //--------------
00518     // Test rowsense, rhs, rowrange, getMatrixByRow
00519     {
00520       OsiSpxSolverInterface lhs;
00521       {     
00522         OsiSpxSolverInterface siC1(m);     
00523         assert( siC1.rowrange_==NULL );
00524         assert( siC1.rowsense_==NULL );
00525         assert( siC1.rhs_==NULL );
00526         assert( siC1.colsol_!=NULL );
00527         assert( siC1.rowsol_!=NULL );
00528         assert( siC1.matrixByRow_==NULL );
00529 
00530         const char   * siC1rs  = siC1.getRowSense();
00531         assert( siC1rs[0]=='G' );
00532         assert( siC1rs[1]=='L' );
00533         assert( siC1rs[2]=='E' );
00534         assert( siC1rs[3]=='R' );
00535         assert( siC1rs[4]=='R' );
00536         
00537         const double * siC1rhs = siC1.getRightHandSide();
00538         assert( eq(siC1rhs[0],2.5) );
00539         assert( eq(siC1rhs[1],2.1) );
00540         assert( eq(siC1rhs[2],4.0) );
00541         assert( eq(siC1rhs[3],5.0) );
00542         assert( eq(siC1rhs[4],15.) ); 
00543         
00544         const double * siC1rr  = siC1.getRowRange();
00545         assert( eq(siC1rr[0],0.0) );
00546         assert( eq(siC1rr[1],0.0) );
00547         assert( eq(siC1rr[2],0.0) );
00548         assert( eq(siC1rr[3],5.0-1.8) );
00549         assert( eq(siC1rr[4],15.0-3.0) );
00550         
00551         const CoinPackedMatrix * siC1mbr = siC1.getMatrixByRow();
00552         assert( siC1mbr != NULL );
00553         
00554         const double * ev = siC1mbr->getElements();
00555         assert( eq(ev[0],   3.0) );
00556         assert( eq(ev[1],   1.0) );
00557         assert( eq(ev[2],  -2.0) );
00558         assert( eq(ev[3],  -1.0) );
00559         assert( eq(ev[4],  -1.0) );
00560         assert( eq(ev[5],   2.0) );
00561         assert( eq(ev[6],   1.1) );
00562         assert( eq(ev[7],   1.0) );
00563         assert( eq(ev[8],   1.0) );
00564         assert( eq(ev[9],   2.8) );
00565         assert( eq(ev[10], -1.2) );
00566         assert( eq(ev[11],  5.6) );
00567         assert( eq(ev[12],  1.0) );
00568         assert( eq(ev[13],  1.9) );
00569         
00570         const int * mi = siC1mbr->getVectorStarts();
00571         assert( mi[0]==0 );
00572         assert( mi[1]==5 );
00573         assert( mi[2]==7 );
00574         assert( mi[3]==9 );
00575         assert( mi[4]==11 );
00576         assert( mi[5]==14 );
00577         
00578         const int * ei = siC1mbr->getIndices();
00579         assert( ei[0]  ==  0 );
00580         assert( ei[1]  ==  1 );
00581         assert( ei[2]  ==  3 );
00582         assert( ei[3]  ==  4 );
00583         assert( ei[4]  ==  7 );
00584         assert( ei[5]  ==  1 );
00585         assert( ei[6]  ==  2 );
00586         assert( ei[7]  ==  2 );
00587         assert( ei[8]  ==  5 );
00588         assert( ei[9]  ==  3 );
00589         assert( ei[10] ==  6 );
00590         assert( ei[11] ==  0 );
00591         assert( ei[12] ==  4 );
00592         assert( ei[13] ==  7 );    
00593         
00594         assert( siC1mbr->getMajorDim() == 5 ); 
00595         assert( siC1mbr->getNumElements() == 14 );
00596         
00597 
00598         assert( siC1rs  == siC1.getRowSense() );
00599         assert( siC1rhs == siC1.getRightHandSide() );
00600         assert( siC1rr  == siC1.getRowRange() );
00601 
00602         // Change SOPLEX Model by adding free row
00603         OsiRowCut rc;
00604         rc.setLb(-DBL_MAX);
00605         rc.setUb( DBL_MAX);
00606         OsiCuts cuts;
00607         cuts.insert(rc);
00608         siC1.applyCuts(cuts);
00609              
00610         // Since model was changed, test that cached
00611         // data is now freed.
00612         assert( siC1.rowrange_==NULL );
00613         assert( siC1.rowsense_==NULL );
00614         assert( siC1.rhs_==NULL );
00615         assert( siC1.colsol_==NULL );
00616         assert( siC1.rowsol_==NULL );
00617         assert( siC1.matrixByRow_==NULL );
00618         assert( siC1.matrixByCol_==NULL );
00619         
00620         siC1rs  = siC1.getRowSense();
00621         siC1rhs = siC1.getRightHandSide();
00622         siC1rr  = siC1.getRowRange();
00623 
00624         assert( siC1rs[0]=='G' );
00625         assert( siC1rs[1]=='L' );
00626         assert( siC1rs[2]=='E' );
00627         assert( siC1rs[3]=='R' );
00628         assert( siC1rs[4]=='R' );
00629         assert( siC1rs[5]=='N' );
00630 
00631         assert( eq(siC1rhs[0],2.5) );
00632         assert( eq(siC1rhs[1],2.1) );
00633         assert( eq(siC1rhs[2],4.0) );
00634         assert( eq(siC1rhs[3],5.0) );
00635         assert( eq(siC1rhs[4],15.) ); 
00636         assert( eq(siC1rhs[5],0.0) ); 
00637 
00638         assert( eq(siC1rr[0],0.0) );
00639         assert( eq(siC1rr[1],0.0) );
00640         assert( eq(siC1rr[2],0.0) );
00641         assert( eq(siC1rr[3],5.0-1.8) );
00642         assert( eq(siC1rr[4],15.0-3.0) );
00643         assert( eq(siC1rr[5],0.0) );
00644     
00645         lhs=siC1;
00646       }
00647       // Test that lhs has correct values even though siC1 has gone out of scope    
00648       assert( lhs.rowrange_==NULL );
00649       assert( lhs.rowsense_==NULL );
00650       assert( lhs.rhs_==NULL ); 
00651       assert( lhs.colsol_!=NULL );
00652       assert( lhs.rowsol_!=NULL );
00653       assert( lhs.matrixByRow_==NULL ); 
00654       assert( lhs.matrixByCol_==NULL ); 
00655       
00656       const char * lhsrs  = lhs.getRowSense();
00657       assert( lhsrs[0]=='G' );
00658       assert( lhsrs[1]=='L' );
00659       assert( lhsrs[2]=='E' );
00660       assert( lhsrs[3]=='R' );
00661       assert( lhsrs[4]=='R' );
00662       assert( lhsrs[5]=='N' );
00663       
00664       const double * lhsrhs = lhs.getRightHandSide();
00665       assert( eq(lhsrhs[0],2.5) );
00666       assert( eq(lhsrhs[1],2.1) );
00667       assert( eq(lhsrhs[2],4.0) );
00668       assert( eq(lhsrhs[3],5.0) );
00669       assert( eq(lhsrhs[4],15.) ); 
00670       assert( eq(lhsrhs[5],0.0) ); 
00671       
00672       const double *lhsrr  = lhs.getRowRange();
00673       assert( eq(lhsrr[0],0.0) );
00674       assert( eq(lhsrr[1],0.0) );
00675       assert( eq(lhsrr[2],0.0) );
00676       assert( eq(lhsrr[3],5.0-1.8) );
00677       assert( eq(lhsrr[4],15.0-3.0) );
00678       assert( eq(lhsrr[5],0.0) );      
00679       
00680       const CoinPackedMatrix * lhsmbr = lhs.getMatrixByRow();
00681       assert( lhsmbr != NULL );       
00682       const double * ev = lhsmbr->getElements();
00683       assert( eq(ev[0],   3.0) );
00684       assert( eq(ev[1],   1.0) );
00685       assert( eq(ev[2],  -2.0) );
00686       assert( eq(ev[3],  -1.0) );
00687       assert( eq(ev[4],  -1.0) );
00688       assert( eq(ev[5],   2.0) );
00689       assert( eq(ev[6],   1.1) );
00690       assert( eq(ev[7],   1.0) );
00691       assert( eq(ev[8],   1.0) );
00692       assert( eq(ev[9],   2.8) );
00693       assert( eq(ev[10], -1.2) );
00694       assert( eq(ev[11],  5.6) );
00695       assert( eq(ev[12],  1.0) );
00696       assert( eq(ev[13],  1.9) );
00697       
00698       const int * mi = lhsmbr->getVectorStarts();
00699       assert( mi[0]==0 );
00700       assert( mi[1]==5 );
00701       assert( mi[2]==7 );
00702       assert( mi[3]==9 );
00703       assert( mi[4]==11 );
00704       assert( mi[5]==14 );
00705       
00706       const int * ei = lhsmbr->getIndices();
00707       assert( ei[0]  ==  0 );
00708       assert( ei[1]  ==  1 );
00709       assert( ei[2]  ==  3 );
00710       assert( ei[3]  ==  4 );
00711       assert( ei[4]  ==  7 );
00712       assert( ei[5]  ==  1 );
00713       assert( ei[6]  ==  2 );
00714       assert( ei[7]  ==  2 );
00715       assert( ei[8]  ==  5 );
00716       assert( ei[9]  ==  3 );
00717       assert( ei[10] ==  6 );
00718       assert( ei[11] ==  0 );
00719       assert( ei[12] ==  4 );
00720       assert( ei[13] ==  7 );    
00721       
00722       int md = lhsmbr->getMajorDim();
00723       assert(  md == 6 ); 
00724       assert( lhsmbr->getNumElements() == 14 );
00725     }
00726     
00727     //--------------    
00728   }
00729 
00730     
00731   // Do common solverInterface testing by calling the
00732   // base class testing method.
00733   {
00734     OsiSpxSolverInterface m;
00735     OsiSolverInterfaceCommonUnitTest(&m, mpsDir,netlibDir);
00736   }
00737 }


The documentation for this class was generated from the following files:
Generated on Wed Dec 3 14:35:46 2003 for Osi by doxygen 1.3.5