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

CoinMpsIO Class Reference

#include <CoinMpsIO.hpp>

List of all members.

Public Member Functions

Methods to retrieve problem information
These methods return information about the problem held by the CoinMpsIO object.

Querying an object that has no data associated with it result in zeros for the number of rows and columns, and NULL pointers from the methods that return vectors. Const pointers returned from any data-query method are always valid

int getNumCols () const
 Get number of columns.

int getNumRows () const
 Get number of rows.

int getNumElements () const
 Get number of nonzero elements.

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

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

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

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

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

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

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

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

bool isInteger (int columnNumber) const
const char * integerColumns () const
const char * rowName (int index) const
const char * columnName (int index) const
int rowIndex (const char *name) const
int columnIndex (const char *name) const
double objectiveOffset () const
const char * getProblemName () const
 Return the problem name.

const char * getObjectiveName () const
 Return the objective name.

const char * getRhsName () const
 Return the RHS vector name.

const char * getRangeName () const
 Return the range vector name.

const char * getBoundName () const
 Return the bound vector name.

Methods to set problem information
Methods to load a problem into the CoinMpsIO object.

void setMpsData (const CoinPackedMatrix &m, const double infinity, const double *collb, const double *colub, const double *obj, const char *integrality, const double *rowlb, const double *rowub, char const *const *const colnames, char const *const *const rownames)
 Set the problem data.

void setMpsData (const CoinPackedMatrix &m, const double infinity, const double *collb, const double *colub, const double *obj, const char *integrality, const double *rowlb, const double *rowub, const std::vector< std::string > &colnames, const std::vector< std::string > &rownames)
void setMpsData (const CoinPackedMatrix &m, const double infinity, const double *collb, const double *colub, const double *obj, const char *integrality, const char *rowsen, const double *rowrhs, const double *rowrng, char const *const *const colnames, char const *const *const rownames)
void setMpsData (const CoinPackedMatrix &m, const double infinity, const double *collb, const double *colub, const double *obj, const char *integrality, const char *rowsen, const double *rowrhs, const double *rowrng, const std::vector< std::string > &colnames, const std::vector< std::string > &rownames)
void copyInIntegerInformation (const char *integerInformation)
Parameter set/get methods
Methods to set and retrieve MPS IO parameters.

void setInfinity (double value)
 Set infinity.

double getInfinity () const
 Get infinity.

void setDefaultBound (int value)
 Set default upper bound for integer variables.

int getDefaultBound () const
 Get default upper bound for integer variables.

Methods for problem input and output
Methods to read and write MPS format problem files.

The read and write methods return the number of errors that occurred during the IO operation, or -1 if no file is opened.

Note:
If the CoinMpsIO class was compiled with support for libz then readMps will automatically try to append .gz to the file name and open it as a compressed file if the specified file name cannot be opened. (Automatic append of the .bz2 suffix when libbz is used is on the TODO list.)

Todo:
Allow for file pointers and positioning


void setFileName (const char *name)
 Set the current file name for the CoinMpsIO object.

const char * getFileName () const
 Get the current file name for the CoinMpsIO object.

const bool fileReadable () const
 Test if a file with the currrent file name exists and is readable.

int readMps (const char *filename, const char *extension="mps")
int readMps ()
int writeMps (const char *filename, int compression=0, int formatType=0, int numberAcross=2) const
int readQuadraticMps (const char *filename, int *&columnStart, int *&column, double *&elements, int checkSymmetry)
int readConicMps (const char *filename, int *&columnStart, int *&column, int &numberCones)
Constructors and destructors
 CoinMpsIO ()
 Default Constructor.

 CoinMpsIO (const CoinMpsIO &)
 Copy constructor.

CoinMpsIOoperator= (const CoinMpsIO &rhs)
 Assignment operator.

 ~CoinMpsIO ()
 Destructor.

Message handling
void passInMessageHandler (CoinMessageHandler *handler)
void newLanguage (CoinMessages::Language language)
 Set the language for messages.

void setLanguage (CoinMessages::Language language)
 Set the language for messages.

CoinMessageHandlermessageHandler () const
 Return the message handler.

CoinMessages messages ()
 Return the messages.

Methods to release storage
These methods allow the client to reduce the storage used by the CoinMpsIO object be selectively releasing unneeded problem information.

void releaseRedundantInformation ()
void releaseRowInformation ()
 Release all row information (lower, upper).

void releaseColumnInformation ()
 Release all column information (lower, upper, objective).

void releaseIntegerInformation ()
 Release integer information.

void releaseRowNames ()
 Release row names.

void releaseColumnNames ()
 Release column names.

void releaseMatrixInformation ()
 Release matrix information.


Protected Member Functions

Miscellaneous helper functions
void setMpsDataWithoutRowAndColNames (const CoinPackedMatrix &m, const double infinity, const double *collb, const double *colub, const double *obj, const char *integrality, const double *rowlb, const double *rowub)
 Utility method used several times to implement public methods.

void setMpsDataColAndRowNames (const std::vector< std::string > &colnames, const std::vector< std::string > &rownames)
void setMpsDataColAndRowNames (char const *const *const colnames, char const *const *const rownames)
void gutsOfDestructor ()
 Does the heavy lifting for destruct and assignment.

void gutsOfCopy (const CoinMpsIO &)
 Does the heavy lifting for copy and assignment.

void freeAll ()
 Clears problem data from the CoinMpsIO object.

void convertBoundToSense (const double lower, const double upper, char &sense, double &right, double &range) const
void convertSenseToBound (const char sense, const double right, const double range, double &lower, double &upper) const
int dealWithFileName (const char *filename, const char *extension, FILE *&fp, gzFile &gzfp)
Hash table methods
void startHash (char **names, const int number, int section)
 Creates hash list for names (section = 0 for rows, 1 columns).

void startHash (int section) const
 This one does it when names are already in.

void stopHash (int section)
 Deletes hash storage.

int findHash (const char *name, int section) const
 Finds match using hash, -1 not found.


Protected Attributes

Cached problem information
char * problemName_
 Problem name.

char * objectiveName_
 Objective row name.

char * rhsName_
 Right-hand side vector name.

char * rangeName_
 Range vector name.

char * boundName_
 Bounds vector name.

int numberRows_
 Number of rows.

int numberColumns_
 Number of columns.

CoinBigIndex numberElements_
 Number of coefficients.

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

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

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

CoinPackedMatrix * matrixByColumn_
 Pointer to column-wise copy of problem matrix coefficients.

double * rowlower_
 Pointer to dense vector of row lower bounds.

double * rowupper_
 Pointer to dense vector of row upper bounds.

double * collower_
 Pointer to dense vector of column lower bounds.

double * colupper_
 Pointer to dense vector of column upper bounds.

double * objective_
 Pointer to dense vector of objective coefficients.

double objectiveOffset_
 Constant offset for objective value (i.e., RHS value for OBJ row).

char * integerType_
char ** names_ [2]
Hash tables
char * fileName_
 Current file name.

int numberHash_ [2]
 Number of entries in a hash table section.

CoinHashLink * hash_ [2]
 Hash tables (two sections, 0 - row names, 1 - column names).

CoinMpsIO object parameters
int defaultBound_
 Upper bound when no bounds for integers.

double infinity_
 Value to use for infinity.

CoinMessageHandlerhandler_
 Message handler.

bool defaultHandler_
CoinMessages messages_
 Messages.

CoinMpsCardReadercardReader_
 Card reader.


Friends

void CoinMpsIOUnitTest (const std::string &mpsDir)


Detailed Description

MPS IO Interface

This class can be used to read in mps files without a solver. After reading the file, the CoinMpsIO object contains all relevant data, which may be more than a particular OsiSolverInterface allows for. Items may be deleted to allow for flexibility of data storage.

The implementation makes the CoinMpsIO object look very like a dummy solver, as the same conventions are used.

Definition at line 163 of file CoinMpsIO.hpp.


Member Function Documentation

int CoinMpsIO::columnIndex const char *  name  )  const
 

Returns the index for the specified column name

Returns -1 if the name is not found.

Definition at line 2942 of file CoinMpsIO.cpp.

References findHash(), hash_, and startHash().

02943 {
02944   if (!hash_[1]) {
02945     if (numberColumns_) {
02946       startHash(1);
02947     } else {
02948       return -1;
02949     }
02950   }
02951   return findHash ( name , 1 );
02952 }

const char * CoinMpsIO::columnName int  index  )  const
 

Returns the column name for the specified index.

Returns 0 if the index is out of range.

Definition at line 2922 of file CoinMpsIO.cpp.

Referenced by readMps().

02923 {
02924   if (index>=0&&index<numberColumns_) {
02925     return names_[1][index];
02926   } else {
02927     return NULL;
02928   }
02929 }

void CoinMpsIO::convertBoundToSense const double  lower,
const double  upper,
char &  sense,
double &  right,
double &  range
const [inline, protected]
 

A quick inlined function to convert from lb/ub style constraint definition to sense/rhs/range style

Definition at line 2538 of file CoinMpsIO.cpp.

References infinity_.

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

02541 {
02542   range = 0.0;
02543   if (lower > -infinity_) {
02544     if (upper < infinity_) {
02545       right = upper;
02546       if (upper==lower) {
02547         sense = 'E';
02548       } else {
02549         sense = 'R';
02550         range = upper - lower;
02551       }
02552     } else {
02553       sense = 'G';
02554       right = lower;
02555     }
02556   } else {
02557     if (upper < infinity_) {
02558       sense = 'L';
02559       right = upper;
02560     } else {
02561       sense = 'N';
02562       right = 0.0;
02563     }
02564   }
02565 }

void CoinMpsIO::convertSenseToBound const char  sense,
const double  right,
const double  range,
double &  lower,
double &  upper
const [inline, protected]
 

A quick inlined function to convert from sense/rhs/range stryle constraint definition to lb/ub style

Definition at line 2571 of file CoinMpsIO.cpp.

References infinity_.

02574 {
02575   switch (sense) {
02576   case 'E':
02577     lower = upper = right;
02578     break;
02579   case 'L':
02580     lower = -infinity_;
02581     upper = right;
02582     break;
02583   case 'G':
02584     lower = right;
02585     upper = infinity_;
02586     break;
02587   case 'R':
02588     lower = right - range;
02589     upper = right;
02590     break;
02591   case 'N':
02592     lower = -infinity_;
02593     upper = infinity_;
02594     break;
02595   }
02596 }

void CoinMpsIO::copyInIntegerInformation const char *  integerInformation  ) 
 

Pass in an array[getNumCols()] specifying if a variable is integer.

At present, simply coded as zero (continuous) and non-zero (integer) May be extended at a later date.

Definition at line 2902 of file CoinMpsIO.cpp.

References integerType_.

02903 {
02904   if (integerType) {
02905     if (!integerType_)
02906       integerType_ = new char [numberColumns_];
02907     memcpy(integerType_,integerType,numberColumns_);
02908   } else {
02909     delete [] integerType_;
02910     integerType_=NULL;
02911   }
02912 }

int CoinMpsIO::dealWithFileName const char *  filename,
const char *  extension,
FILE *&  fp,
gzFile &  gzfp
[protected]
 

Deal with a filename

As the name says. Returns +1 if the file name is new, 0 if it's the same as before (i.e., matches fileName_), and -1 if there's an error and the file can't be opened. Handles automatic append of .gz suffix when compiled with libz.

Todo:
Add automatic append of .bz2 suffix when compiled with libbz.

Definition at line 930 of file CoinMpsIO.cpp.

References fileName_, handler_, CoinMessageHandler::message(), and messages_.

Referenced by readConicMps(), readMps(), and readQuadraticMps().

00932 {
00933   fp=NULL;
00934   int goodFile=0;
00935   gzfp=NULL;
00936   if (!fileName_||(filename!=NULL&&strcmp(filename,fileName_))) {
00937     if (filename==NULL) {
00938       handler_->message(COIN_MPS_FILE,messages_)<<"NULL"
00939                                                 <<CoinMessageEol;
00940       return -1;
00941     }
00942     goodFile=-1;
00943     // looks new name
00944     char newName[400];
00945     if (strcmp(filename,"stdin")&&strcmp(filename,"-")) {
00946       if (extension&&strlen(extension)) {
00947         // There was an extension - but see if user gave .xxx
00948         int i = strlen(filename)-1;
00949         strcpy(newName,filename);
00950         bool foundDot=false; 
00951         for (;i>=0;i--) {
00952           char character = filename[i];
00953           if (character=='/'||character=='\\') {
00954             break;
00955           } else if (character=='.') {
00956             foundDot=true;
00957             break;
00958           }
00959         }
00960         if (!foundDot) {
00961           strcat(newName,".");
00962           strcat(newName,extension);
00963         }
00964       } else {
00965         // no extension
00966         strcpy(newName,filename);
00967       }
00968     } else {
00969       strcpy(newName,"stdin");    
00970     }
00971     // See if new name
00972     if (fileName_&&!strcmp(newName,fileName_)) {
00973       // old name
00974       return 0;
00975     } else {
00976       // new file
00977       free(fileName_);
00978       fileName_=strdup(newName);    
00979       if (strcmp(fileName_,"stdin")) {
00980 #ifdef COIN_USE_ZLIB
00981         int length=strlen(fileName_);
00982         if (!strcmp(fileName_+length-3,".gz")) {
00983           gzfp = gzopen(fileName_,"rb");
00984           fp = NULL;
00985           goodFile = (gzfp!=NULL);
00986         } else {
00987 #endif
00988           fp = fopen ( fileName_, "r" );
00989           if (fp!=NULL)
00990             goodFile=1;
00991 #ifdef COIN_USE_ZLIB
00992           if (goodFile<0) {
00993             std::string fname(fileName_);
00994             fname += ".gz";
00995             gzfp = gzopen(fname.c_str(),"rb");
00996             printf("%s\n", fname.c_str());
00997             if (gzfp!=NULL)
00998               goodFile=1;
00999           }
01000         }
01001 #endif
01002       } else {
01003         fp = stdin;
01004         goodFile = 1;
01005       }
01006     }
01007   } else {
01008     // same as before
01009     // reset section ?
01010     goodFile=0;
01011   }
01012   if (goodFile<0) 
01013     handler_->message(COIN_MPS_FILE,messages_)<<fileName_
01014                                               <<CoinMessageEol;
01015   return goodFile;
01016 }

const double * CoinMpsIO::getRightHandSide  )  const
 

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

Given constraints with upper (rowupper) and/or lower (rowlower) bounds, the constraint right-hand side (rhs) is set as

  • 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

Definition at line 2620 of file CoinMpsIO.cpp.

References convertBoundToSense(), numberRows_, rhs_, rowlower_, and rowupper_.

02621 {
02622   if ( rhs_==NULL ) {
02623 
02624     int nr=numberRows_;
02625     rhs_ = (double *) malloc(nr*sizeof(double));
02626 
02627 
02628     char dum1;
02629     double dum2;
02630     int i;
02631     for ( i=0; i<nr; i++ ) {
02632       convertBoundToSense(rowlower_[i],rowupper_[i],dum1,rhs_[i],dum2);
02633     }
02634   }
02635   return rhs_;
02636 }

const double * CoinMpsIO::getRowRange  )  const
 

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

Given constraints with upper (rowupper) and/or lower (rowlower) bounds, the constraint range (rowrange) is set as

  • if rowsense()[i] == 'R' then rowrange()[i] == rowupper()[i] - rowlower()[i]
  • if rowsense()[i] != 'R' then rowrange()[i] is 0.0
Put another way, only range constraints have a nontrivial value for rowrange.

Definition at line 2642 of file CoinMpsIO.cpp.

References convertBoundToSense(), numberRows_, rowlower_, rowrange_, and rowupper_.

02643 {
02644   if ( rowrange_==NULL ) {
02645 
02646     int nr=numberRows_;
02647     rowrange_ = (double *) malloc(nr*sizeof(double));
02648     std::fill(rowrange_,rowrange_+nr,0.0);
02649 
02650     char dum1;
02651     double dum2;
02652     int i;
02653     for ( i=0; i<nr; i++ ) {
02654       convertBoundToSense(rowlower_[i],rowupper_[i],dum1,dum2,rowrange_[i]);
02655     }
02656   }
02657   return rowrange_;
02658 }

const char * CoinMpsIO::getRowSense  )  const
 

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

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

Definition at line 2600 of file CoinMpsIO.cpp.

References convertBoundToSense(), numberRows_, rowlower_, rowsense_, and rowupper_.

Referenced by writeMps().

02601 {
02602   if ( rowsense_==NULL ) {
02603 
02604     int nr=numberRows_;
02605     rowsense_ = (char *) malloc(nr*sizeof(char));
02606 
02607 
02608     double dum1,dum2;
02609     int i;
02610     for ( i=0; i<nr; i++ ) {
02611       convertBoundToSense(rowlower_[i],rowupper_[i],rowsense_[i],dum1,dum2);
02612     }
02613   }
02614   return rowsense_;
02615 }

const char * CoinMpsIO::integerColumns  )  const
 

Returns array[getNumCols()] specifying if a variable is integer.

At present, simply coded as zero (continuous) and non-zero (integer) May be extended at a later date.

Definition at line 2896 of file CoinMpsIO.cpp.

References integerType_.

02897 {
02898   return integerType_;
02899 }

bool CoinMpsIO::isInteger int  columnNumber  )  const
 

Return true if a column is an integer variable

Note: This function returns true if the the column is a binary or general integer variable.

Definition at line 2887 of file CoinMpsIO.cpp.

References integerType_.

Referenced by writeMps().

02888 {
02889   const char * intType = integerType_;
02890   if ( intType==NULL ) return false;
02891   assert (columnNumber>=0 && columnNumber < numberColumns_);
02892   if ( intType[columnNumber]!=0 ) return true;
02893   return false;
02894 }

double CoinMpsIO::objectiveOffset  )  const
 

Returns the (constant) objective offset

This is the RHS entry for the objective row

Definition at line 1018 of file CoinMpsIO.cpp.

References objectiveOffset_.

01019 {
01020   return objectiveOffset_;
01021 }

void CoinMpsIO::passInMessageHandler CoinMessageHandler handler  ) 
 

Pass in Message handler

Supply a custom message handler. It will not be destroyed when the CoinMpsIO object is destroyed.

Definition at line 3258 of file CoinMpsIO.cpp.

References defaultHandler_, and handler_.

03259 {
03260   if (defaultHandler_) 
03261     delete handler_;
03262   defaultHandler_=false;
03263   handler_=handler;
03264 }

int CoinMpsIO::readConicMps const char *  filename,
int *&  columnStart,
int *&  column,
int &  numberCones
 

Read in a list of cones from the given filename.

If filename is NULL (or the same as the currently open file) then reading continues from the current file. If not, the file is closed and the specified file is opened.

Code should be added to general MPS reader to read this if CSECTION No checking is done that in unique cone

Arrays should be deleted by delete []

Returns number of errors, -1 bad file, -2 no conic section, -3 empty section

columnStart is numberCones+1 long, other number of columns in matrix

Definition at line 3503 of file CoinMpsIO.cpp.

References CoinMpsCardReader::card(), CoinMpsCardReader::cardNumber(), cardReader_, CoinMpsCardReader::columnName(), dealWithFileName(), fileName_, findHash(), handler_, CoinMessageHandler::message(), messages_, CoinMpsCardReader::mpsType(), CoinMpsCardReader::nextField(), CoinMpsCardReader::readToNextSection(), startHash(), stopHash(), and CoinMpsCardReader::whichSection().

03505 {
03506   // Deal with filename - +1 if new, 0 if same as before, -1 if error
03507   FILE *fp=NULL;
03508   gzFile gzfp=NULL;
03509   int returnCode = dealWithFileName(filename,"",fp,gzfp);
03510   if (returnCode<0) {
03511     return -1;
03512   } else if (returnCode>0) {
03513     delete cardReader_;
03514     cardReader_ = new CoinMpsCardReader ( fp , gzfp, this);
03515   }
03516 
03517   cardReader_->readToNextSection();
03518 
03519   // Skip NAME
03520   if ( cardReader_->whichSection (  ) == COIN_NAME_SECTION ) 
03521     cardReader_->readToNextSection();
03522   numberCones=0;
03523 
03524   // Get arrays
03525   columnStart = new int [numberColumns_+1];
03526   column = new int [numberColumns_];
03527   int numberErrors = 0;
03528   columnStart[0]=0;
03529   int numberElements=0;
03530   startHash(1);
03531   
03532   //if (cardReader_->whichSection()==COIN_CONIC_SECTION) 
03533   //cardReader_->cleanCard(); // skip doing last
03534   while ( cardReader_->nextField (  ) == COIN_CONIC_SECTION ) {
03535     // should check QUAD
03536     // Have to check by hand
03537     if (!strncmp(cardReader_->card(),"CSECTION",8)) {
03538       if (numberElements==columnStart[numberCones]) {
03539         printf("Cone must have at least one column\n");
03540         abort();
03541       }
03542       columnStart[++numberCones]=numberElements;
03543       continue;
03544     }
03545     COINColumnIndex iColumn1;
03546     switch ( cardReader_->mpsType (  ) ) {
03547     case COIN_BLANK_COLUMN:
03548       // get index
03549       iColumn1 = findHash ( cardReader_->columnName (  ) , 1 );
03550       
03551       if ( iColumn1 >= 0 ) {
03552         column[numberElements++]=iColumn1;
03553       } else {
03554         numberErrors++;
03555         if ( numberErrors < 100 ) {
03556           handler_->message(COIN_MPS_NOMATCHCOL,messages_)
03557             <<cardReader_->columnName()<<cardReader_->cardNumber()<<cardReader_->card()
03558             <<CoinMessageEol;
03559         } else if (numberErrors > 100000) {
03560           handler_->message(COIN_MPS_RETURNING,messages_)<<CoinMessageEol;
03561           return numberErrors;
03562         }
03563       }
03564       break;
03565     default:
03566       numberErrors++;
03567       if ( numberErrors < 100 ) {
03568         handler_->message(COIN_MPS_BADIMAGE,messages_)<<cardReader_->cardNumber()
03569                                                       <<cardReader_->card()
03570                                                       <<CoinMessageEol;
03571       } else if (numberErrors > 100000) {
03572         handler_->message(COIN_MPS_RETURNING,messages_)<<CoinMessageEol;
03573         return numberErrors;
03574       }
03575     }
03576   }
03577   if ( cardReader_->whichSection (  ) == COIN_ENDATA_SECTION ) {
03578     // Error if no cones
03579     if (!numberElements) {
03580       handler_->message(COIN_MPS_EOF,messages_)<<fileName_
03581                                                <<CoinMessageEol;
03582       delete [] columnStart;
03583       delete [] column;
03584       columnStart = NULL;
03585       column = NULL;
03586       return -3;
03587     } else {
03588       columnStart[++numberCones]=numberElements;
03589     }
03590   } else {
03591     handler_->message(COIN_MPS_BADFILE1,messages_)<<cardReader_->card()
03592                                                   <<cardReader_->cardNumber()
03593                                                  <<fileName_
03594                                                   <<CoinMessageEol;
03595     delete [] columnStart;
03596     delete [] column;
03597     columnStart = NULL;
03598     column = NULL;
03599     numberCones=0;
03600     return -2;
03601   }
03602 
03603   stopHash(1);
03604   return numberErrors;
03605 }

int CoinMpsIO::readMps  ) 
 

Read a problem in MPS format from a previously opened file

More precisely, read a problem using a CoinMpsCardReader object already associated with this CoinMpsIO object.

Todo:
Provide an interface that will allow a client to associate a CoinMpsCardReader object with a CoinMpsIO object by setting the cardReader_ field.

Definition at line 1056 of file CoinMpsIO.cpp.

References boundName_, CoinMpsCardReader::card(), CoinMpsCardReader::cardNumber(), cardReader_, collower_, columnName(), CoinMpsCardReader::columnName(), colupper_, defaultBound_, fileName_, CoinMpsCardReader::filePointer(), findHash(), handler_, infinity_, integerType_, matrixByColumn_, CoinMessageHandler::message(), messages_, CoinMpsCardReader::mpsType(), CoinMpsCardReader::nextField(), numberColumns_, numberElements_, numberRows_, objective_, objectiveName_, objectiveOffset_, problemName_, rangeName_, CoinMpsCardReader::readToNextSection(), rhsName_, rowlower_, CoinMpsCardReader::rowName(), rowName(), rowupper_, startHash(), stopHash(), CoinMpsCardReader::value(), and CoinMpsCardReader::whichSection().

Referenced by readMps().

01057 {
01058   bool ifmps;
01059 
01060   cardReader_->readToNextSection();
01061 
01062   if ( cardReader_->whichSection (  ) == COIN_NAME_SECTION ) {
01063     ifmps = true;
01064     // save name of section
01065     free(problemName_);
01066     problemName_=strdup(cardReader_->columnName());
01067   } else if ( cardReader_->whichSection (  ) == COIN_UNKNOWN_SECTION ) {
01068     handler_->message(COIN_MPS_BADFILE1,messages_)<<cardReader_->card()
01069                                                   <<1
01070                                                  <<fileName_
01071                                                  <<CoinMessageEol;
01072 #ifdef COIN_USE_ZLIB
01073     if (!cardReader_->filePointer()) 
01074       handler_->message(COIN_MPS_BADFILE2,messages_)<<CoinMessageEol;
01075 
01076 #endif
01077     return -2;
01078   } else if ( cardReader_->whichSection (  ) != COIN_EOF_SECTION ) {
01079     // save name of section
01080     free(problemName_);
01081     problemName_=strdup(cardReader_->card());
01082     ifmps = false;
01083   } else {
01084     handler_->message(COIN_MPS_EOF,messages_)<<fileName_
01085                                             <<CoinMessageEol;
01086     return -3;
01087   }
01088   CoinBigIndex *start;
01089   COINRowIndex *row;
01090   double *element;
01091   objectiveOffset_ = 0.0;
01092 
01093   int numberErrors = 0;
01094   int i;
01095 
01096   if ( ifmps ) {
01097     // mps file - always read in free format
01098     bool gotNrow = false;
01099 
01100     //get ROWS
01101     cardReader_->nextField (  ) ;
01102     // Fudge for what ever code has OBJSENSE
01103     if (!strncmp(cardReader_->card(),"OBJSENSE",8)) {
01104       cardReader_->nextField();
01105       int i;
01106       const char * thisCard = cardReader_->card();
01107       int direction = 0;
01108       for (i=0;i<20;i++) {
01109         if (thisCard[i]!=' ') {
01110           if (!strncmp(thisCard+i,"MAX",3))
01111             direction=-1;
01112           else if (!strncmp(thisCard+i,"MIN",3))
01113             direction=1;
01114           break;
01115         }
01116       }
01117       if (!direction)
01118         printf("No MAX/MIN found after OBJSENSE\n");
01119       else 
01120         printf("%s found after OBJSENSE - Coin ignores\n",
01121                (direction>0 ? "MIN" : "MAX"));
01122       cardReader_->nextField();
01123     }
01124     if ( cardReader_->whichSection (  ) != COIN_ROW_SECTION ) {
01125       handler_->message(COIN_MPS_BADIMAGE,messages_)<<cardReader_->cardNumber()
01126                                                     <<cardReader_->card()
01127                                                     <<CoinMessageEol;
01128       handler_->message(COIN_MPS_RETURNING,messages_)<<CoinMessageEol;
01129       return numberErrors;
01130     }
01131     //use malloc etc as I don't know how to do realloc in C++
01132     numberRows_ = 0;
01133     numberColumns_ = 0;
01134     numberElements_ = 0;
01135     COINRowIndex maxRows = 1000;
01136     COINMpsType *rowType =
01137 
01138       ( COINMpsType * ) malloc ( maxRows * sizeof ( COINMpsType ) );
01139     char **rowName = ( char ** ) malloc ( maxRows * sizeof ( char * ) );
01140 
01141     // for discarded free rows
01142     COINRowIndex maxFreeRows = 100;
01143     COINRowIndex numberOtherFreeRows = 0;
01144     char **freeRowName =
01145 
01146       ( char ** ) malloc ( maxFreeRows * sizeof ( char * ) );
01147     while ( cardReader_->nextField (  ) == COIN_ROW_SECTION ) {
01148       switch ( cardReader_->mpsType (  ) ) {
01149       case COIN_N_ROW:
01150         if ( !gotNrow ) {
01151           gotNrow = true;
01152           // save name of section
01153           free(objectiveName_);
01154           objectiveName_=strdup(cardReader_->columnName());
01155         } else {
01156           // add to discard list
01157           if ( numberOtherFreeRows == maxFreeRows ) {
01158             maxFreeRows = ( 3 * maxFreeRows ) / 2 + 100;
01159             freeRowName =
01160               ( char ** ) realloc ( freeRowName,
01161 
01162                                     maxFreeRows * sizeof ( char * ) );
01163           }
01164           freeRowName[numberOtherFreeRows] =
01165             strdup ( cardReader_->columnName (  ) );
01166           numberOtherFreeRows++;
01167         }
01168         break;
01169       case COIN_E_ROW:
01170       case COIN_L_ROW:
01171       case COIN_G_ROW:
01172         if ( numberRows_ == maxRows ) {
01173           maxRows = ( 3 * maxRows ) / 2 + 1000;
01174           rowType =
01175             ( COINMpsType * ) realloc ( rowType,
01176                                        maxRows * sizeof ( COINMpsType ) );
01177           rowName =
01178 
01179             ( char ** ) realloc ( rowName, maxRows * sizeof ( char * ) );
01180         }
01181         rowType[numberRows_] = cardReader_->mpsType (  );
01182         rowName[numberRows_] = strdup ( cardReader_->columnName (  ) );
01183         numberRows_++;
01184         break;
01185       default:
01186         numberErrors++;
01187         if ( numberErrors < 100 ) {
01188           handler_->message(COIN_MPS_BADIMAGE,messages_)<<cardReader_->cardNumber()
01189                                                        <<cardReader_->card()
01190                                                        <<CoinMessageEol;
01191         } else if (numberErrors > 100000) {
01192           handler_->message(COIN_MPS_RETURNING,messages_)<<CoinMessageEol;
01193           return numberErrors;
01194         }
01195       }
01196     }
01197     if ( cardReader_->whichSection (  ) != COIN_COLUMN_SECTION ) {
01198       handler_->message(COIN_MPS_BADIMAGE,messages_)<<cardReader_->cardNumber()
01199                                                     <<cardReader_->card()
01200                                                     <<CoinMessageEol;
01201       handler_->message(COIN_MPS_RETURNING,messages_)<<CoinMessageEol;
01202       return numberErrors;
01203     }
01204     assert ( gotNrow );
01205     rowType =
01206       ( COINMpsType * ) realloc ( rowType,
01207                                  numberRows_ * sizeof ( COINMpsType ) );
01208     // put objective and other free rows at end
01209     rowName =
01210       ( char ** ) realloc ( rowName,
01211                             ( numberRows_ + 1 +
01212 
01213                               numberOtherFreeRows ) * sizeof ( char * ) );
01214     rowName[numberRows_] = strdup(objectiveName_);
01215     memcpy ( rowName + numberRows_ + 1, freeRowName,
01216              numberOtherFreeRows * sizeof ( char * ) );
01217     // now we can get rid of this array
01218     free(freeRowName);
01219 
01220     startHash ( rowName, numberRows_ + 1 + numberOtherFreeRows , 0 );
01221     COINColumnIndex maxColumns = 1000 + numberRows_ / 5;
01222     CoinBigIndex maxElements = 5000 + numberRows_ / 2;
01223     COINMpsType *columnType = ( COINMpsType * )
01224       malloc ( maxColumns * sizeof ( COINMpsType ) );
01225     char **columnName = ( char ** ) malloc ( maxColumns * sizeof ( char * ) );
01226 
01227     objective_ = ( double * ) malloc ( maxColumns * sizeof ( double ) );
01228     start = ( CoinBigIndex * )
01229       malloc ( ( maxColumns + 1 ) * sizeof ( CoinBigIndex ) );
01230     row = ( COINRowIndex * )
01231       malloc ( maxElements * sizeof ( COINRowIndex ) );
01232     element =
01233       ( double * ) malloc ( maxElements * sizeof ( double ) );
01234     // for duplicates
01235     CoinBigIndex *rowUsed = new CoinBigIndex[numberRows_];
01236 
01237     for (i=0;i<numberRows_;i++) {
01238       rowUsed[i]=-1;
01239     }
01240     bool objUsed = false;
01241 
01242     numberElements_ = 0;
01243     char lastColumn[200];
01244 
01245     memset ( lastColumn, '\0', 200 );
01246     COINColumnIndex column = -1;
01247     bool inIntegerSet = false;
01248     COINColumnIndex numberIntegers = 0;
01249     const double tinyElement = 1.0e-14;
01250 
01251     while ( cardReader_->nextField (  ) == COIN_COLUMN_SECTION ) {
01252       switch ( cardReader_->mpsType (  ) ) {
01253       case COIN_BLANK_COLUMN:
01254         if ( strcmp ( lastColumn, cardReader_->columnName (  ) ) ) {
01255           // new column
01256 
01257           // reset old column and take out tiny
01258           if ( numberColumns_ ) {
01259             objUsed = false;
01260             CoinBigIndex i;
01261             CoinBigIndex k = start[column];
01262 
01263             for ( i = k; i < numberElements_; i++ ) {
01264               COINRowIndex irow = row[i];
01265 #if 0
01266               if ( fabs ( element[i] ) > tinyElement ) {
01267                 element[k++] = element[i];
01268               }
01269 #endif
01270               rowUsed[irow] = -1;
01271             }
01272             //numberElements_ = k;
01273           }
01274           column = numberColumns_;
01275           if ( numberColumns_ == maxColumns ) {
01276             maxColumns = ( 3 * maxColumns ) / 2 + 1000;
01277             columnType = ( COINMpsType * )
01278               realloc ( columnType, maxColumns * sizeof ( COINMpsType ) );
01279             columnName = ( char ** )
01280               realloc ( columnName, maxColumns * sizeof ( char * ) );
01281 
01282             objective_ = ( double * )
01283               realloc ( objective_, maxColumns * sizeof ( double ) );
01284             start = ( CoinBigIndex * )
01285               realloc ( start,
01286                         ( maxColumns + 1 ) * sizeof ( CoinBigIndex ) );
01287           }
01288           if ( !inIntegerSet ) {
01289             columnType[column] = COIN_UNSET_BOUND;
01290           } else {
01291             columnType[column] = COIN_INTORG;
01292             numberIntegers++;
01293           }
01294           columnName[column] = strdup ( cardReader_->columnName (  ) );
01295           strcpy ( lastColumn, cardReader_->columnName (  ) );
01296           objective_[column] = 0.0;
01297           start[column] = numberElements_;
01298           numberColumns_++;
01299         }
01300         if ( fabs ( cardReader_->value (  ) ) > tinyElement ) {
01301           if ( numberElements_ == maxElements ) {
01302             maxElements = ( 3 * maxElements ) / 2 + 1000;
01303             row = ( COINRowIndex * )
01304               realloc ( row, maxElements * sizeof ( COINRowIndex ) );
01305             element = ( double * )
01306               realloc ( element, maxElements * sizeof ( double ) );
01307           }
01308           // get row number
01309           COINRowIndex irow = findHash ( cardReader_->rowName (  ) , 0 );
01310 
01311           if ( irow >= 0 ) {
01312             double value = cardReader_->value (  );
01313 
01314             // check for duplicates
01315             if ( irow == numberRows_ ) {
01316               // objective
01317               if ( objUsed ) {
01318                 numberErrors++;
01319                 if ( numberErrors < 100 ) {
01320                   handler_->message(COIN_MPS_DUPOBJ,messages_)
01321                     <<cardReader_->cardNumber()<<cardReader_->card()
01322                     <<CoinMessageEol;
01323                 } else if (numberErrors > 100000) {
01324                   handler_->message(COIN_MPS_RETURNING,messages_)
01325                     <<CoinMessageEol;
01326                   return numberErrors;
01327                 }
01328               } else {
01329                 objUsed = true;
01330               }
01331               value += objective_[column];
01332               if ( fabs ( value ) <= tinyElement )
01333                 value = 0.0;
01334               objective_[column] = value;
01335             } else if ( irow < numberRows_ ) {
01336               // other free rows will just be discarded so won't get here
01337               if ( rowUsed[irow] >= 0 ) {
01338                 element[rowUsed[irow]] += value;
01339                 numberErrors++;
01340                 if ( numberErrors < 100 ) {
01341                   handler_->message(COIN_MPS_DUPROW,messages_)
01342                     <<cardReader_->rowName()<<cardReader_->cardNumber()
01343                     <<cardReader_->card()
01344                     <<CoinMessageEol;
01345                 } else if (numberErrors > 100000) {
01346                   handler_->message(COIN_MPS_RETURNING,messages_)
01347                     <<CoinMessageEol;
01348                   return numberErrors;
01349                 }
01350               } else {
01351                 row[numberElements_] = irow;
01352                 element[numberElements_] = value;
01353                 rowUsed[irow] = numberElements_;
01354                 numberElements_++;
01355               }
01356             }
01357           } else {
01358             numberErrors++;
01359             if ( numberErrors < 100 ) {
01360                   handler_->message(COIN_MPS_NOMATCHROW,messages_)
01361                     <<cardReader_->rowName()<<cardReader_->cardNumber()<<cardReader_->card()
01362                     <<CoinMessageEol;
01363             } else if (numberErrors > 100000) {
01364               handler_->message(COIN_MPS_RETURNING,messages_)<<CoinMessageEol;
01365               return numberErrors;
01366             }
01367           }
01368         }
01369         break;
01370       case COIN_INTORG:
01371         inIntegerSet = true;
01372         break;
01373       case COIN_INTEND:
01374         inIntegerSet = false;
01375         break;
01376       case COIN_S1_COLUMN:
01377       case COIN_S2_COLUMN:
01378       case COIN_S3_COLUMN:
01379       case COIN_SOSEND:
01380         std::cout << "** code sos etc later" << std::endl;
01381         abort (  );
01382         break;
01383       default:
01384         numberErrors++;
01385         if ( numberErrors < 100 ) {
01386           handler_->message(COIN_MPS_BADIMAGE,messages_)<<cardReader_->cardNumber()
01387                                                        <<cardReader_->card()
01388                                                        <<CoinMessageEol;
01389         } else if (numberErrors > 100000) {
01390           handler_->message(COIN_MPS_RETURNING,messages_)<<CoinMessageEol;
01391           return numberErrors;
01392         }
01393       }
01394     }
01395     start[numberColumns_] = numberElements_;
01396     delete[]rowUsed;
01397     if ( cardReader_->whichSection (  ) != COIN_RHS_SECTION ) {
01398       handler_->message(COIN_MPS_BADIMAGE,messages_)<<cardReader_->cardNumber()
01399                                                     <<cardReader_->card()
01400                                                     <<CoinMessageEol;
01401       handler_->message(COIN_MPS_RETURNING,messages_)<<CoinMessageEol;
01402       return numberErrors;
01403     }
01404     columnType =
01405       ( COINMpsType * ) realloc ( columnType,
01406                                  numberColumns_ * sizeof ( COINMpsType ) );
01407     columnName =
01408 
01409       ( char ** ) realloc ( columnName, numberColumns_ * sizeof ( char * ) );
01410     objective_ = ( double * )
01411       realloc ( objective_, numberColumns_ * sizeof ( double ) );
01412     start = ( CoinBigIndex * )
01413       realloc ( start, ( numberColumns_ + 1 ) * sizeof ( CoinBigIndex ) );
01414     row = ( COINRowIndex * )
01415       realloc ( row, numberElements_ * sizeof ( COINRowIndex ) );
01416     element = ( double * )
01417       realloc ( element, numberElements_ * sizeof ( double ) );
01418 
01419     rowlower_ = ( double * ) malloc ( numberRows_ * sizeof ( double ) );
01420     rowupper_ = ( double * ) malloc ( numberRows_ * sizeof ( double ) );
01421     for (i=0;i<numberRows_;i++) {
01422       rowlower_[i]=-infinity_;
01423       rowupper_[i]=infinity_;
01424     }
01425     objUsed = false;
01426     memset ( lastColumn, '\0', 200 );
01427     bool gotRhs = false;
01428 
01429     // need coding for blank rhs
01430     while ( cardReader_->nextField (  ) == COIN_RHS_SECTION ) {
01431       COINRowIndex irow;
01432 
01433       switch ( cardReader_->mpsType (  ) ) {
01434       case COIN_BLANK_COLUMN:
01435         if ( strcmp ( lastColumn, cardReader_->columnName (  ) ) ) {
01436 
01437           // skip rest if got a rhs
01438           if ( gotRhs ) {
01439             while ( cardReader_->nextField (  ) == COIN_RHS_SECTION ) {
01440             }
01441             break;
01442           } else {
01443             gotRhs = true;
01444             strcpy ( lastColumn, cardReader_->columnName (  ) );
01445             // save name of section
01446             free(rhsName_);
01447             rhsName_=strdup(cardReader_->columnName());
01448           }
01449         }
01450         // get row number
01451         irow = findHash ( cardReader_->rowName (  ) , 0 );
01452         if ( irow >= 0 ) {
01453           double value = cardReader_->value (  );
01454 
01455           // check for duplicates
01456           if ( irow == numberRows_ ) {
01457             // objective
01458             if ( objUsed ) {
01459               numberErrors++;
01460               if ( numberErrors < 100 ) {
01461                   handler_->message(COIN_MPS_DUPOBJ,messages_)
01462                     <<cardReader_->cardNumber()<<cardReader_->card()
01463                     <<CoinMessageEol;
01464               } else if (numberErrors > 100000) {
01465                 handler_->message(COIN_MPS_RETURNING,messages_)<<CoinMessageEol;
01466                 return numberErrors;
01467               }
01468             } else {
01469               objUsed = true;
01470             }
01471             objectiveOffset_ += value;
01472           } else if ( irow < numberRows_ ) {
01473             if ( rowlower_[irow] != -infinity_ ) {
01474               numberErrors++;
01475               if ( numberErrors < 100 ) {
01476                 handler_->message(COIN_MPS_DUPROW,messages_)
01477                   <<cardReader_->rowName()<<cardReader_->cardNumber()<<cardReader_->card()
01478                   <<CoinMessageEol;
01479               } else if (numberErrors > 100000) {
01480                 handler_->message(COIN_MPS_RETURNING,messages_)<<CoinMessageEol;
01481                 return numberErrors;
01482               }
01483             } else {
01484               rowlower_[irow] = value;
01485             }
01486           }
01487         } else {
01488           numberErrors++;
01489           if ( numberErrors < 100 ) {
01490             handler_->message(COIN_MPS_NOMATCHROW,messages_)
01491               <<cardReader_->rowName()<<cardReader_->cardNumber()<<cardReader_->card()
01492               <<CoinMessageEol;
01493           } else if (numberErrors > 100000) {
01494             handler_->message(COIN_MPS_RETURNING,messages_)<<CoinMessageEol;
01495             return numberErrors;
01496           }
01497         }
01498         break;
01499       default:
01500         numberErrors++;
01501         if ( numberErrors < 100 ) {
01502           handler_->message(COIN_MPS_BADIMAGE,messages_)<<cardReader_->cardNumber()
01503                                                        <<cardReader_->card()
01504                                                        <<CoinMessageEol;
01505         } else if (numberErrors > 100000) {
01506           handler_->message(COIN_MPS_RETURNING,messages_)<<CoinMessageEol;
01507           return numberErrors;
01508         }
01509       }
01510     }
01511     if ( cardReader_->whichSection (  ) == COIN_RANGES_SECTION ) {
01512       memset ( lastColumn, '\0', 200 );
01513       bool gotRange = false;
01514       COINRowIndex irow;
01515 
01516       // need coding for blank range
01517       while ( cardReader_->nextField (  ) == COIN_RANGES_SECTION ) {
01518         switch ( cardReader_->mpsType (  ) ) {
01519         case COIN_BLANK_COLUMN:
01520           if ( strcmp ( lastColumn, cardReader_->columnName (  ) ) ) {
01521 
01522             // skip rest if got a range
01523             if ( gotRange ) {
01524               while ( cardReader_->nextField (  ) == COIN_RANGES_SECTION ) {
01525               }
01526               break;
01527             } else {
01528               gotRange = true;
01529               strcpy ( lastColumn, cardReader_->columnName (  ) );
01530               // save name of section
01531               free(rangeName_);
01532               rangeName_=strdup(cardReader_->columnName());
01533             }
01534           }
01535           // get row number
01536           irow = findHash ( cardReader_->rowName (  ) , 0 );
01537           if ( irow >= 0 ) {
01538             double value = cardReader_->value (  );
01539 
01540             // check for duplicates
01541             if ( irow == numberRows_ ) {
01542               // objective
01543               numberErrors++;
01544               if ( numberErrors < 100 ) {
01545                   handler_->message(COIN_MPS_DUPOBJ,messages_)
01546                     <<cardReader_->cardNumber()<<cardReader_->card()
01547                     <<CoinMessageEol;
01548               } else if (numberErrors > 100000) {
01549                 handler_->message(COIN_MPS_RETURNING,messages_)<<CoinMessageEol;
01550                 return numberErrors;
01551               }
01552             } else {
01553               if ( rowupper_[irow] != infinity_ ) {
01554                 numberErrors++;
01555                 if ( numberErrors < 100 ) {
01556                   handler_->message(COIN_MPS_DUPROW,messages_)
01557                     <<cardReader_->rowName()<<cardReader_->cardNumber()<<cardReader_->card()
01558                     <<CoinMessageEol;
01559                 } else if (numberErrors > 100000) {
01560                   handler_->message(COIN_MPS_RETURNING,messages_)
01561                     <<CoinMessageEol;
01562                   return numberErrors;
01563                 }
01564               } else {
01565                 rowupper_[irow] = value;
01566               }
01567             }
01568           } else {
01569             numberErrors++;
01570             if ( numberErrors < 100 ) {
01571               handler_->message(COIN_MPS_NOMATCHROW,messages_)
01572                 <<cardReader_->rowName()<<cardReader_->cardNumber()<<cardReader_->card()
01573                 <<CoinMessageEol;
01574             } else if (numberErrors > 100000) {
01575               handler_->message(COIN_MPS_RETURNING,messages_)<<CoinMessageEol;
01576               return numberErrors;
01577             }
01578           }
01579           break;
01580         default:
01581           numberErrors++;
01582           if ( numberErrors < 100 ) {
01583           handler_->message(COIN_MPS_BADIMAGE,messages_)<<cardReader_->cardNumber()
01584                                                        <<cardReader_->card()
01585                                                        <<CoinMessageEol;
01586           } else if (numberErrors > 100000) {
01587             handler_->message(COIN_MPS_RETURNING,messages_)<<CoinMessageEol;
01588             return numberErrors;
01589           }
01590         }
01591       }
01592     }
01593     stopHash ( 0 );
01594     // massage ranges
01595     {
01596       COINRowIndex irow;
01597 
01598       for ( irow = 0; irow < numberRows_; irow++ ) {
01599         double lo = rowlower_[irow];
01600         double up = rowupper_[irow];
01601         double up2 = rowupper_[irow];   //range
01602 
01603         switch ( rowType[irow] ) {
01604         case COIN_E_ROW:
01605           if ( lo == -infinity_ )
01606             lo = 0.0;
01607           if ( up == infinity_ ) {
01608             up = lo;
01609           } else if ( up > 0.0 ) {
01610             up += lo;
01611           } else {
01612             up = lo;
01613             lo += up2;
01614           }
01615           break;
01616         case COIN_L_ROW:
01617           if ( lo == -infinity_ ) {
01618             up = 0.0;
01619           } else {
01620             up = lo;
01621             lo = -infinity_;
01622           }
01623           if ( up2 != infinity_ ) {
01624             lo = up - fabs ( up2 );
01625           }
01626           break;
01627         case COIN_G_ROW:
01628           if ( lo == -infinity_ ) {
01629             lo = 0.0;
01630             up = infinity_;
01631           } else {
01632             up = infinity_;
01633           }
01634           if ( up2 != infinity_ ) {
01635             up = lo + fabs ( up2 );
01636           }
01637           break;
01638         default:
01639           abort();
01640         }
01641         rowlower_[irow] = lo;
01642         rowupper_[irow] = up;
01643       }
01644     }
01645     free ( rowType );
01646     // default bounds
01647     collower_ = ( double * ) malloc ( numberColumns_ * sizeof ( double ) );
01648     colupper_ = ( double * ) malloc ( numberColumns_ * sizeof ( double ) );
01649     for (i=0;i<numberColumns_;i++) {
01650       collower_[i]=0.0;
01651       colupper_[i]=infinity_;
01652     }
01653     // set up integer region just in case
01654     integerType_ = (char *) malloc (numberColumns_*sizeof(char));
01655 
01656     for ( column = 0; column < numberColumns_; column++ ) {
01657       if ( columnType[column] == COIN_INTORG ) {
01658         columnType[column] = COIN_UNSET_BOUND;
01659         integerType_[column] = 1;
01660       } else {
01661         integerType_[column] = 0;
01662       }
01663     }
01664     // start hash even if no bound section - to make sure names survive
01665     startHash ( columnName, numberColumns_ , 1 );
01666     if ( cardReader_->whichSection (  ) == COIN_BOUNDS_SECTION ) {
01667       memset ( lastColumn, '\0', 200 );
01668       bool gotBound = false;
01669 
01670       while ( cardReader_->nextField (  ) == COIN_BOUNDS_SECTION ) {
01671         if ( strcmp ( lastColumn, cardReader_->columnName (  ) ) ) {
01672 
01673           // skip rest if got a bound
01674           if ( gotBound ) {
01675             while ( cardReader_->nextField (  ) == COIN_BOUNDS_SECTION ) {
01676             }
01677             break;
01678           } else {
01679             gotBound = true;;
01680             strcpy ( lastColumn, cardReader_->columnName (  ) );
01681             // save name of section
01682             free(boundName_);
01683             boundName_=strdup(cardReader_->columnName());
01684           }
01685         }
01686         // get column number
01687         COINColumnIndex icolumn = findHash ( cardReader_->rowName (  ) , 1 );
01688 
01689         if ( icolumn >= 0 ) {
01690           double value = cardReader_->value (  );
01691           bool ifError = false;
01692 
01693           switch ( cardReader_->mpsType (  ) ) {
01694           case COIN_UP_BOUND:
01695             if ( value == -1.0e100 )
01696               ifError = true;
01697             if ( columnType[icolumn] == COIN_UNSET_BOUND ) {
01698               if ( value < 0.0 ) {
01699                 collower_[icolumn] = -infinity_;
01700               }
01701             } else if ( columnType[icolumn] == COIN_LO_BOUND ) {
01702               if ( value < collower_[icolumn] ) {
01703                 ifError = true;
01704               } else if ( value < collower_[icolumn] + tinyElement ) {
01705                 value = collower_[icolumn];
01706               }
01707             } else if ( columnType[icolumn] == COIN_MI_BOUND ) {
01708             } else {
01709               ifError = true;
01710             }
01711             colupper_[icolumn] = value;
01712             columnType[icolumn] = COIN_UP_BOUND;
01713             break;
01714           case COIN_LO_BOUND:
01715             if ( value == -1.0e100 )
01716               ifError = true;
01717             if ( columnType[icolumn] == COIN_UNSET_BOUND ) {
01718             } else if ( columnType[icolumn] == COIN_UP_BOUND ||
01719                         columnType[icolumn] == COIN_UI_BOUND ) {
01720               if ( value > colupper_[icolumn] ) {
01721                 ifError = true;
01722               } else if ( value > colupper_[icolumn] - tinyElement ) {
01723                 value = colupper_[icolumn];
01724               }
01725             } else {
01726               ifError = true;
01727             }
01728             collower_[icolumn] = value;
01729             columnType[icolumn] = COIN_LO_BOUND;
01730             break;
01731           case COIN_FX_BOUND:
01732             if ( value == -1.0e100 )
01733               ifError = true;
01734             if ( columnType[icolumn] == COIN_UNSET_BOUND ) {
01735             } else if ( columnType[icolumn] == COIN_UI_BOUND ||
01736                         columnType[icolumn] == COIN_BV_BOUND) {
01737               // Allow so people can easily put FX's at end
01738               double value2 = floor(value);
01739               if (fabs(value2-value)>1.0e-12||
01740                   value2<collower_[icolumn]||
01741                   value2>colupper_[icolumn]) {
01742                 ifError=true;
01743               } else {
01744                 // take off integer list
01745                 assert(integerType_[icolumn] );
01746                 numberIntegers--;
01747                 integerType_[icolumn] = 0;
01748               }
01749             } else {
01750               ifError = true;
01751             }
01752             collower_[icolumn] = value;
01753             colupper_[icolumn] = value;
01754             columnType[icolumn] = COIN_FX_BOUND;
01755             break;
01756           case COIN_FR_BOUND:
01757             if ( columnType[icolumn] == COIN_UNSET_BOUND ) {
01758             } else {
01759               ifError = true;
01760             }
01761             collower_[icolumn] = -infinity_;
01762             colupper_[icolumn] = infinity_;
01763             columnType[icolumn] = COIN_FR_BOUND;
01764             break;
01765           case COIN_MI_BOUND:
01766             if ( columnType[icolumn] == COIN_UNSET_BOUND ) {
01767               colupper_[icolumn] = COIN_DBL_MAX;
01768             } else if ( columnType[icolumn] == COIN_UP_BOUND ) {
01769             } else {
01770               ifError = true;
01771             }
01772             collower_[icolumn] = -infinity_;
01773             columnType[icolumn] = COIN_MI_BOUND;
01774             break;
01775           case COIN_PL_BOUND:
01776             if ( columnType[icolumn] == COIN_UNSET_BOUND ) {
01777             } else {
01778               ifError = true;
01779             }
01780             columnType[icolumn] = COIN_PL_BOUND;
01781             break;
01782           case COIN_UI_BOUND:
01783 #if 0
01784             if ( value == -1.0e100 ) 
01785               ifError = true;
01786             if ( columnType[icolumn] == COIN_UNSET_BOUND ) {
01787             } else if ( columnType[icolumn] == COIN_LO_BOUND ) {
01788               if ( value < collower_[icolumn] ) {
01789                 ifError = true;
01790               } else if ( value < collower_[icolumn] + tinyElement ) {
01791                 value = collower_[icolumn];
01792               }
01793             } else {
01794               ifError = true;
01795             }
01796 #else
01797             if ( value == -1.0e100 ) {
01798                value = infinity_;
01799                if (columnType[icolumn] != COIN_UNSET_BOUND &&
01800                    columnType[icolumn] != COIN_LO_BOUND) {
01801                   ifError = true;
01802                }
01803             } else {
01804                if ( columnType[icolumn] == COIN_UNSET_BOUND ) {
01805                } else if ( columnType[icolumn] == COIN_LO_BOUND ) {
01806                   if ( value < collower_[icolumn] ) {
01807                      ifError = true;
01808                   } else if ( value < collower_[icolumn] + tinyElement ) {
01809                      value = collower_[icolumn];
01810                   }
01811                } else {
01812                   ifError = true;
01813                }
01814             }
01815 #endif
01816             colupper_[icolumn] = value;
01817             columnType[icolumn] = COIN_UI_BOUND;
01818             if ( !integerType_[icolumn] ) {
01819               numberIntegers++;
01820               integerType_[icolumn] = 1;
01821             }
01822             break;
01823           case COIN_BV_BOUND:
01824             if ( columnType[icolumn] == COIN_UNSET_BOUND ) {
01825             } else {
01826               ifError = true;
01827             }
01828             collower_[icolumn] = 0.0;
01829             colupper_[icolumn] = 1.0;
01830             columnType[icolumn] = COIN_BV_BOUND;
01831             if ( !integerType_[icolumn] ) {
01832               numberIntegers++;
01833               integerType_[icolumn] = 1;
01834             }
01835             break;
01836           default:
01837             ifError = true;
01838             break;
01839           }
01840           if ( ifError ) {
01841             numberErrors++;
01842             if ( numberErrors < 100 ) {
01843               handler_->message(COIN_MPS_BADIMAGE,messages_)
01844                 <<cardReader_->cardNumber()
01845                 <<cardReader_->card()
01846                 <<CoinMessageEol;
01847             } else if (numberErrors > 100000) {
01848               handler_->message(COIN_MPS_RETURNING,messages_)<<CoinMessageEol;
01849               return numberErrors;
01850             }
01851           }
01852         } else {
01853           numberErrors++;
01854           if ( numberErrors < 100 ) {
01855             handler_->message(COIN_MPS_NOMATCHCOL,messages_)
01856               <<cardReader_->rowName()<<cardReader_->cardNumber()<<cardReader_->card()
01857               <<CoinMessageEol;
01858           } else if (numberErrors > 100000) {
01859             handler_->message(COIN_MPS_RETURNING,messages_)<<CoinMessageEol;
01860             return numberErrors;
01861           }
01862         }
01863       }
01864     }
01865     stopHash ( 1 );
01866     // clean up integers
01867     if ( !numberIntegers ) {
01868       free(integerType_);
01869       integerType_ = NULL;
01870     } else {
01871       COINColumnIndex icolumn;
01872 
01873       for ( icolumn = 0; icolumn < numberColumns_; icolumn++ ) {
01874         if ( integerType_[icolumn] ) {
01875           assert ( collower_[icolumn] >= -MAX_INTEGER );
01876           // if 0 infinity make 0-1 ???
01877           if ( columnType[icolumn] == COIN_UNSET_BOUND ) 
01878             colupper_[icolumn] = defaultBound_;
01879           if ( colupper_[icolumn] > MAX_INTEGER ) 
01880             colupper_[icolumn] = MAX_INTEGER;
01881         }
01882       }
01883     }
01884     free ( columnType );
01885     if ( cardReader_->whichSection (  ) != COIN_ENDATA_SECTION ) {
01886       handler_->message(COIN_MPS_BADIMAGE,messages_)<<cardReader_->cardNumber()
01887                                                     <<cardReader_->card()
01888                                                     <<CoinMessageEol;
01889       handler_->message(COIN_MPS_RETURNING,messages_)<<CoinMessageEol;
01890       return numberErrors;
01891     }
01892   } else {
01893     // This is very simple format - what should we use?
01894     COINColumnIndex i;
01895     FILE * fp = cardReader_->filePointer();
01896     fscanf ( fp, "%d %d %d\n", &numberRows_, &numberColumns_, &i);
01897     numberElements_  = i; // done this way in case numberElements_ long
01898 
01899     rowlower_ = ( double * ) malloc ( numberRows_ * sizeof ( double ) );
01900     rowupper_ = ( double * ) malloc ( numberRows_ * sizeof ( double ) );
01901     for ( i = 0; i < numberRows_; i++ ) {
01902       int j;
01903 
01904       fscanf ( fp, "%d %lg %lg\n", &j, &rowlower_[i], &rowupper_[i] );
01905       assert ( i == j );
01906     }
01907     collower_ = ( double * ) malloc ( numberColumns_ * sizeof ( double ) );
01908     colupper_ = ( double * ) malloc ( numberColumns_ * sizeof ( double ) );
01909     objective_= ( double * ) malloc ( numberColumns_ * sizeof ( double ) );
01910     start = ( CoinBigIndex *) malloc ((numberColumns_ + 1) *
01911                                         sizeof (CoinBigIndex) );
01912     row = ( COINRowIndex * ) malloc (numberElements_ * sizeof (COINRowIndex));
01913     element = ( double * ) malloc (numberElements_ * sizeof (double) );
01914 
01915     start[0] = 0;
01916     numberElements_ = 0;
01917     for ( i = 0; i < numberColumns_; i++ ) {
01918       int j;
01919       int n;
01920 
01921       fscanf ( fp, "%d %d %lg %lg %lg\n", &j, &n, &collower_[i], &colupper_[i],
01922                &objective_[i] );
01923       assert ( i == j );
01924       for ( j = 0; j < n; j++ ) {
01925         fscanf ( fp, "       %d %lg\n", &row[numberElements_],
01926                  &element[numberElements_] );
01927         numberElements_++;
01928       }
01929       start[i + 1] = numberElements_;
01930     }
01931   }
01932   // construct packed matrix
01933   matrixByColumn_ = 
01934     new CoinPackedMatrix(true,
01935                         numberRows_,numberColumns_,numberElements_,
01936                         element,row,start,NULL);
01937   free ( row );
01938   free ( start );
01939   free ( element );
01940 
01941   handler_->message(COIN_MPS_STATS,messages_)<<problemName_
01942                                             <<numberRows_
01943                                             <<numberColumns_
01944                                             <<numberElements_
01945                                             <<CoinMessageEol;
01946   return numberErrors;
01947 }

int CoinMpsIO::readMps const char *  filename,
const char *  extension = "mps"
 

Read a problem in MPS format from the given filename.

Use "stdin" or "-" to read from stdin.

Definition at line 1042 of file CoinMpsIO.cpp.

References cardReader_, dealWithFileName(), and readMps().

01043 {
01044   // Deal with filename - +1 if new, 0 if same as before, -1 if error
01045   FILE *fp=NULL;
01046   gzFile gzfp=NULL;
01047   int returnCode = dealWithFileName(filename,extension,fp,gzfp);
01048   if (returnCode<0) {
01049     return -1;
01050   } else if (returnCode>0) {
01051     delete cardReader_;
01052     cardReader_ = new CoinMpsCardReader ( fp , gzfp, this);
01053   }
01054   return readMps();
01055 }

int CoinMpsIO::readQuadraticMps const char *  filename,
int *&  columnStart,
int *&  column,
double *&  elements,
int  checkSymmetry
 

Read in a quadratic objective from the given filename.

If filename is NULL (or the same as the currently open file) then reading continues from the current file. If not, the file is closed and the specified file is opened.

Code should be added to general MPS reader to read this if QSECTION Data is assumed to be Q and objective is c + 1/2 xT Q x No assumption is made for symmetry, positive definite, etc. No check is made for duplicates or non-triangular if checkSymmetry==0. If 1 checks lower triangular (so off diagonal should be 2*Q) if 2 makes lower triangular and assumes full Q (but adds off diagonals)

Arrays should be deleted by delete []

Returns number of errors:

  • -1: bad file
  • -2: no Quadratic section
  • -3: an empty section
  • +n: then matching errors etc (symmetry forced)
  • -4: no matching errors but fails triangular test (triangularity forced)
columnStart is numberColumns+1 long, others numberNonZeros

Definition at line 3282 of file CoinMpsIO.cpp.

References CoinMpsCardReader::card(), CoinMpsCardReader::cardNumber(), cardReader_, CoinMpsCardReader::columnName(), dealWithFileName(), fileName_, findHash(), handler_, CoinMessageHandler::message(), messages_, CoinMpsCardReader::mpsType(), CoinMpsCardReader::nextField(), problemName_, CoinMpsCardReader::readToNextSection(), CoinMpsCardReader::rowName(), startHash(), stopHash(), CoinMpsCardReader::value(), and CoinMpsCardReader::whichSection().

03285 {
03286   // Deal with filename - +1 if new, 0 if same as before, -1 if error
03287   FILE *fp=NULL;
03288   gzFile gzfp=NULL;
03289   int returnCode = dealWithFileName(filename,"",fp,gzfp);
03290   if (returnCode<0) {
03291     return -1;
03292   } else if (returnCode>0) {
03293     delete cardReader_;
03294     cardReader_ = new CoinMpsCardReader ( fp , gzfp, this);
03295   }
03296 
03297   cardReader_->readToNextSection();
03298 
03299   // Skip NAME
03300   if ( cardReader_->whichSection (  ) == COIN_NAME_SECTION ) 
03301     cardReader_->readToNextSection();
03302   if ( cardReader_->whichSection (  ) == COIN_QUADRATIC_SECTION ) {
03303     // save name of section
03304     free(problemName_);
03305     problemName_=strdup(cardReader_->columnName());
03306   } else if ( cardReader_->whichSection (  ) == COIN_EOF_SECTION ) {
03307     handler_->message(COIN_MPS_EOF,messages_)<<fileName_
03308                                             <<CoinMessageEol;
03309     return -3;
03310   } else {
03311     handler_->message(COIN_MPS_BADFILE1,messages_)<<cardReader_->card()
03312                                                   <<cardReader_->cardNumber()
03313                                                  <<fileName_
03314                                                   <<CoinMessageEol;
03315     return -2;
03316   }
03317 
03318   int numberErrors = 0;
03319 
03320   // Guess at size of data
03321   int maximumNonZeros = 5 *numberColumns_;
03322   // Use malloc so can use realloc
03323   int * column = (int *) malloc(maximumNonZeros*sizeof(int));
03324   int * column2Temp = (int *) malloc(maximumNonZeros*sizeof(int));
03325   double * elementTemp = (double *) malloc(maximumNonZeros*sizeof(double));
03326 
03327   startHash(1);
03328   int numberElements=0;
03329 
03330   const double tinyElement = 1.0e-14;
03331   
03332   while ( cardReader_->nextField (  ) == COIN_QUADRATIC_SECTION ) {
03333     switch ( cardReader_->mpsType (  ) ) {
03334     case COIN_BLANK_COLUMN:
03335       if ( fabs ( cardReader_->value (  ) ) > tinyElement ) {
03336         if ( numberElements == maximumNonZeros ) {
03337           maximumNonZeros = ( 3 * maximumNonZeros ) / 2 + 1000;
03338           column = ( COINColumnIndex * )
03339             realloc ( column, maximumNonZeros * sizeof ( COINColumnIndex ) );
03340           column2Temp = ( COINColumnIndex * )
03341             realloc ( column2Temp, maximumNonZeros * sizeof ( COINColumnIndex ) );
03342           elementTemp = ( double * )
03343             realloc ( elementTemp, maximumNonZeros * sizeof ( double ) );
03344         }
03345         // get indices
03346         COINColumnIndex iColumn1 = findHash ( cardReader_->columnName (  ) , 1 );
03347         COINColumnIndex iColumn2 = findHash ( cardReader_->rowName (  ) , 1 );
03348 
03349         if ( iColumn1 >= 0 ) {
03350           if (iColumn2 >=0) {
03351             double value = cardReader_->value (  );
03352             column[numberElements]=iColumn1;
03353             column2Temp[numberElements]=iColumn2;
03354             elementTemp[numberElements++]=value;
03355           } else {
03356             numberErrors++;
03357             if ( numberErrors < 100 ) {
03358                   handler_->message(COIN_MPS_NOMATCHROW,messages_)
03359                     <<cardReader_->rowName()<<cardReader_->cardNumber()<<cardReader_->card()
03360                     <<CoinMessageEol;
03361             } else if (numberErrors > 100000) {
03362               handler_->message(COIN_MPS_RETURNING,messages_)<<CoinMessageEol;
03363               return numberErrors;
03364             }
03365           }
03366         } else {
03367           numberErrors++;
03368           if ( numberErrors < 100 ) {
03369             handler_->message(COIN_MPS_NOMATCHCOL,messages_)
03370               <<cardReader_->columnName()<<cardReader_->cardNumber()<<cardReader_->card()
03371               <<CoinMessageEol;
03372           } else if (numberErrors > 100000) {
03373             handler_->message(COIN_MPS_RETURNING,messages_)<<CoinMessageEol;
03374             return numberErrors;
03375           }
03376         }
03377       }
03378       break;
03379     default:
03380       numberErrors++;
03381       if ( numberErrors < 100 ) {
03382         handler_->message(COIN_MPS_BADIMAGE,messages_)<<cardReader_->cardNumber()
03383                                                       <<cardReader_->card()
03384                                                       <<CoinMessageEol;
03385       } else if (numberErrors > 100000) {
03386         handler_->message(COIN_MPS_RETURNING,messages_)<<CoinMessageEol;
03387         return numberErrors;
03388       }
03389     }
03390   }
03391   stopHash(1);
03392   // Do arrays as new [] and make column ordered
03393   columnStart = new int [numberColumns_+1];
03394   // for counts
03395   int * count = new int[numberColumns_];
03396   memset(count,0,numberColumns_*sizeof(int));
03397   CoinBigIndex i;
03398   // See about lower triangular
03399   if (checkSymmetry&&numberErrors) 
03400     checkSymmetry=2; // force corrections
03401   if (checkSymmetry) {
03402     if (checkSymmetry==1) {
03403       // just check lower triangular
03404       for ( i = 0; i < numberElements; i++ ) {
03405         int iColumn = column[i];
03406         int iColumn2 = column2Temp[i];
03407         if (iColumn2<iColumn) {
03408           numberErrors=-4;
03409           column[i]=iColumn2;
03410           column2Temp[i]=iColumn;
03411         }
03412       }
03413     } else {
03414       // make lower triangular
03415       for ( i = 0; i < numberElements; i++ ) {
03416         int iColumn = column[i];
03417         int iColumn2 = column2Temp[i];
03418         if (iColumn2<iColumn) {
03419           column[i]=iColumn2;
03420           column2Temp[i]=iColumn;
03421         }
03422       }
03423     }
03424   }
03425   for ( i = 0; i < numberElements; i++ ) {
03426     int iColumn = column[i];
03427     count[iColumn]++;
03428   }
03429   // Do starts
03430   int number = 0;
03431   columnStart[0]=0;
03432   for (i=0;i<numberColumns_;i++) {
03433     number += count[i];
03434     count[i]= columnStart[i];
03435     columnStart[i+1]=number;
03436   }
03437   column2 = new int[numberElements];
03438   elements = new double[numberElements];
03439 
03440   // Get column ordering
03441   for ( i = 0; i < numberElements; i++ ) {
03442     int iColumn = column[i];
03443     int iColumn2 = column2Temp[i];
03444     int put = count[iColumn];
03445     elements[put]=elementTemp[i];
03446     column2[put++]=iColumn2;
03447     count[iColumn]=put;
03448   }
03449   free(column);
03450   free(column2Temp);
03451   free(elementTemp);
03452 
03453   // Now in column order - deal with duplicates
03454   for (i=0;i<numberColumns_;i++) 
03455     count[i] = -1;
03456 
03457   int start = 0;
03458   number=0;
03459   for (i=0;i<numberColumns_;i++) {
03460     int j;
03461     for (j=start;j<columnStart[i+1];j++) {
03462       int iColumn2 = column2[j];
03463       if (count[iColumn2]<0) {
03464         count[iColumn2]=j;
03465       } else {
03466         // duplicate
03467         int iOther = count[iColumn2];
03468         double value = elements[iOther]+elements[j];
03469         elements[iOther]=value;
03470         elements[j]=0.0;
03471       }
03472     }
03473     for (j=start;j<columnStart[i+1];j++) {
03474       int iColumn2 = column2[j];
03475       count[iColumn2]=-1;
03476       double value = elements[j];
03477       if (value) {
03478         column2[number]=iColumn2;
03479         elements[number++]=value;
03480       }
03481     }
03482     start = columnStart[i+1];
03483     columnStart[i+1]=number;
03484   }
03485 
03486   delete [] count;
03487   return numberErrors;
03488 }

void CoinMpsIO::releaseRedundantInformation  ) 
 

Release all information which can be re-calculated.

E.g., row sense, copies of rows, hash tables for names.

Definition at line 3241 of file CoinMpsIO.cpp.

References hash_, matrixByRow_, rhs_, rowrange_, and rowsense_.

Referenced by freeAll(), releaseColumnNames(), releaseMatrixInformation(), and releaseRowNames().

03242 {  
03243   free( rowsense_);
03244   free( rhs_);
03245   free( rowrange_);
03246   rowsense_=NULL;
03247   rhs_=NULL;
03248   rowrange_=NULL;
03249   free (hash_[0]);
03250   free (hash_[1]);
03251   hash_[0]=0;
03252   hash_[1]=0;
03253   delete matrixByRow_;
03254   matrixByRow_=NULL;
03255 }

int CoinMpsIO::rowIndex const char *  name  )  const
 

Returns the index for the specified row name

Returns -1 if the name is not found. Returns numberRows for the objective row and > numberRows for dropped free rows.

Definition at line 2931 of file CoinMpsIO.cpp.

References findHash(), hash_, and startHash().

02932 {
02933   if (!hash_[0]) {
02934     if (numberRows_) {
02935       startHash(0);
02936     } else {
02937       return -1;
02938     }
02939   }
02940   return findHash ( name , 0 );
02941 }

const char * CoinMpsIO::rowName int  index  )  const
 

Returns the row name for the specified index.

Returns 0 if the index is out of range.

Definition at line 2914 of file CoinMpsIO.cpp.

Referenced by readMps().

02915 {
02916   if (index>=0&&index<numberRows_) {
02917     return names_[0][index];
02918   } else {
02919     return NULL;
02920   }
02921 }

int CoinMpsIO::writeMps const char *  filename,
int  compression = 0,
int  formatType = 0,
int  numberAcross = 2
const
 

Write the problem in MPS format to a file with the given filename.

Parameters:
compression can be set to three values to indicate what kind of file should be written
  • 0: plain text (default)
  • 1: gzip compressed (.gz is appended to filename)
  • 2: bzip2 compressed (.bz2 is appended to filename) (TODO)
If the library was not compiled with the requested compression then writeMps falls back to writing a plain text file.
formatType specifies the precision to used for values in the MPS file
  • 0: normal precision (default)
  • 1: extra accuracy
  • 2: IEEE hex (TODO)
numberAcross specifies whether 1 or 2 (default) values should be specified on every data line in the MPS file.

Definition at line 2104 of file CoinMpsIO.cpp.

References getColLower(), getColUpper(), getMatrixByCol(), getObjCoefficients(), getRowLower(), getRowSense(), getRowUpper(), infinity_, isInteger(), names_, numberColumns_, numberRows_, and problemName_.

02106 {
02107    std::string line = filename;
02108    FILE * fp = NULL;
02109    gzFile gzfp = NULL;
02110    switch (compression) {
02111    case 1:
02112 #ifdef COIN_USE_ZLIB
02113       {
02114          if (strcmp(line.c_str() +(line.size()-3), ".gz") != 0) {
02115             line += ".gz";
02116          }
02117          gzfp = gzopen(line.c_str(), "wb");
02118          if (gzfp) {
02119             break;
02120          }
02121       }
02122 #endif
02123       fp = fopen(filename,"w");
02124       if (!fp)
02125          return -1;
02126       break;
02127 
02128    case 2: /* bzip2: to be implemented */
02129    case 0:
02130       fp = fopen(filename,"w");
02131       if (!fp)
02132          return -1;
02133       break;
02134    }
02135 
02136    const char * const * const rowNames = names_[0];
02137    const char * const * const columnNames = names_[1];
02138    int i;
02139    unsigned int length = 8;
02140    bool freeFormat = (formatType!=0);
02141    for (i = 0 ; i < numberRows_; ++i) {
02142       if (strlen(rowNames[i]) > length) {
02143          length = strlen(rowNames[i]);
02144          break;
02145       }
02146    }
02147    if (length <= 8) {
02148       for (i = 0 ; i < numberColumns_; ++i) {
02149          if (strlen(columnNames[i]) > length) {
02150             length = strlen(columnNames[i]);
02151             break;
02152          }
02153       }
02154    }
02155    if (length > 8 && !freeFormat) {
02156       freeFormat = true;
02157       formatType = 4;
02158    }
02159    
02160    // NAME card
02161 
02162    line = "NAME          ";
02163    if (strcmp(problemName_,"")==0) {
02164       line.append("BLANK   ");
02165    } else {
02166       if (strlen(problemName_) >= 8) {
02167          line.append(problemName_, 8);
02168       } else {
02169          line.append(problemName_);
02170          line.append(8-strlen(problemName_), ' ');
02171       }
02172    }
02173    if (freeFormat)
02174       line.append("  FREE");
02175    // finish off name and do ROWS card and objective 
02176    line.append("\nROWS\n N  OBJROW\n");
02177    writeString(fp, gzfp, line.c_str());
02178 
02179    // Rows section
02180    // Sense array
02181    // But massage if looks odd
02182    char * sense = new char [numberRows_];
02183    memcpy( sense , getRowSense(), numberRows_);
02184    const double * rowLower = getRowLower();
02185    const double * rowUpper = getRowUpper();
02186   
02187    for (i=0;i<numberRows_;i++) {
02188       line = " ";
02189       if (sense[i]!='R') {
02190          line.append(1,sense[i]);
02191       } else {
02192         if (rowLower[i]>-1.0e30) {
02193           if(rowUpper[i]<1.0e30) {
02194          line.append("L");
02195           } else {
02196             sense[i]='G';
02197             line.append(1,sense[i]);
02198       }
02199         } else {
02200           sense[i]='L';
02201           line.append(1,sense[i]);
02202         }
02203       }
02204       line.append("  ");
02205       line.append(rowNames[i]);
02206       line.append("\n");
02207       writeString(fp, gzfp, line.c_str());
02208    }
02209 
02210    // COLUMNS card
02211    writeString(fp, gzfp, "COLUMNS\n");
02212 
02213    bool ifBounds=false;
02214    double largeValue = infinity_;
02215 
02216    const double * columnLower = getColLower();
02217    const double * columnUpper = getColUpper();
02218    const double * objective = getObjCoefficients();
02219    const CoinPackedMatrix * matrix = getMatrixByCol();
02220    const double * elements = matrix->getElements();
02221    const int * rows = matrix->getIndices();
02222    const CoinBigIndex * starts = matrix->getVectorStarts();
02223    const int * lengths = matrix->getVectorLengths();
02224 
02225    char outputValue[2][20];
02226    char outputRow[2][100];
02227 
02228    // Through columns (only put out if elements or objective value)
02229    for (i=0;i<numberColumns_;i++) {
02230       if (objective[i]||lengths[i]) {
02231          // see if bound will be needed
02232          if (columnLower[i]||columnUpper[i]<largeValue||isInteger(i))
02233             ifBounds=true;
02234          int numberFields=0;
02235          if (objective[i]) {
02236             convertDouble(formatType,objective[i],outputValue[0],
02237                           "OBJROW",outputRow[0]);
02238             numberFields=1;
02239          }
02240          if (numberFields==numberAcross) {
02241             // put out card
02242             outputCard(formatType, numberFields,
02243                        fp, gzfp, "    ",
02244                        columnNames[i],
02245                        outputValue,
02246                        outputRow);
02247             numberFields=0;
02248          }
02249          int j;
02250          for (j=0;j<lengths[i];j++) {
02251             convertDouble(formatType,elements[starts[i]+j],
02252                           outputValue[numberFields],
02253                           rowNames[rows[starts[i]+j]],
02254                           outputRow[numberFields]);
02255             numberFields++;
02256             if (numberFields==numberAcross) {
02257                // put out card
02258                outputCard(formatType, numberFields,
02259                           fp, gzfp, "    ",
02260                           columnNames[i],
02261                           outputValue,
02262                           outputRow);
02263                numberFields=0;
02264             }
02265          }
02266          if (numberFields) {
02267             // put out card
02268             outputCard(formatType, numberFields,
02269                        fp, gzfp, "    ",
02270                        columnNames[i],
02271                        outputValue,
02272                        outputRow);
02273          }
02274       }
02275    }
02276 
02277    bool ifRange=false;
02278    // RHS
02279    writeString(fp, gzfp, "RHS\n");
02280 
02281    int numberFields = 0;
02282    for (i=0;i<numberRows_;i++) {
02283       double value;
02284       switch (sense[i]) {
02285       case 'E':
02286          value=rowLower[i];
02287          break;
02288       case 'R':
02289          value=rowUpper[i];
02290            ifRange=true;
02291          break;
02292       case 'L':
02293          value=rowUpper[i];
02294          break;
02295       case 'G':
02296          value=rowLower[i];
02297          break;
02298       default:
02299          value=0.0;
02300          break;
02301       }
02302       if (value != 0.0) {
02303          convertDouble(formatType,value,
02304                        outputValue[numberFields],
02305                        rowNames[i],
02306                        outputRow[numberFields]);
02307          numberFields++;
02308          if (numberFields==numberAcross) {
02309             // put out card
02310             outputCard(formatType, numberFields,
02311                        fp, gzfp, "    ",
02312                        "RHS",
02313                        outputValue,
02314                        outputRow);
02315             numberFields=0;
02316          }
02317       }
02318    }
02319    if (numberFields) {
02320       // put out card
02321       outputCard(formatType, numberFields,
02322                  fp, gzfp, "    ",
02323                  "RHS",
02324                  outputValue,
02325                  outputRow);
02326    }
02327 
02328    if (ifRange) {
02329       // RANGES
02330       writeString(fp, gzfp, "RANGES\n");
02331 
02332       numberFields = 0;
02333       for (i=0;i<numberRows_;i++) {
02334          if (sense[i]=='R') {
02335             double value =rowUpper[i]-rowLower[i];
02336             if (value<1.0e30) {
02337               convertDouble(formatType,value,
02338                             outputValue[numberFields],
02339                             rowNames[i],
02340                             outputRow[numberFields]);
02341               numberFields++;
02342               if (numberFields==numberAcross) {
02343                 // put out card
02344                 outputCard(formatType, numberFields,
02345                            fp, gzfp, "    ",
02346                            "RANGE",
02347                            outputValue,
02348                            outputRow);
02349                 numberFields=0;
02350               }
02351             }
02352          }
02353       }
02354       if (numberFields) {
02355          // put out card
02356          outputCard(formatType, numberFields,
02357                     fp, gzfp, "    ",
02358                     "RANGE",
02359                     outputValue,
02360                     outputRow);
02361       }
02362    }
02363    delete [] sense;
02364    if (ifBounds) {
02365       // BOUNDS
02366       writeString(fp, gzfp, "BOUNDS\n");
02367 
02368       for (i=0;i<numberColumns_;i++) {
02369          if (objective[i]||lengths[i]) {
02370             // see if bound will be needed
02371             if (columnLower[i]||columnUpper[i]<largeValue||isInteger(i)) {
02372               double lowerValue = columnLower[i];
02373               double upperValue = columnUpper[i];
02374               if (isInteger(i)) {
02375                 // Old argument - what are correct ranges for integer variables
02376                 lowerValue = max(lowerValue,(double) -INT_MAX);
02377                 upperValue = min(upperValue,(double) INT_MAX);
02378               }
02379                int numberFields=1;
02380                std::string header[2];
02381                double value[2];
02382                if (lowerValue<=-largeValue) {
02383                   // FR or MI
02384                   if (upperValue>=largeValue) {
02385                      header[0]=" FR ";
02386                      value[0] = largeValue;
02387                   } else {
02388                      header[0]=" MI ";
02389                      value[0] = largeValue;
02390                      header[1]=" UP ";
02391                      value[1] = upperValue;
02392                      numberFields=2;
02393                   }
02394                } else if (fabs(upperValue-lowerValue)<1.0e-8) {
02395                   header[0]=" FX ";
02396                   value[0] = lowerValue;
02397                } else {
02398                   // do LO if needed
02399                   if (lowerValue) {
02400                      // LO
02401                      header[0]=" LO ";
02402                      value[0] = lowerValue;
02403                      if (isInteger(i)) {
02404                         // Integer variable so UI
02405                         header[1]=" UI ";
02406                         value[1] = upperValue;
02407                         numberFields=2;
02408                      } else if (upperValue<largeValue) {
02409                         // UP
02410                         header[1]=" UP ";
02411                         value[1] = upperValue;
02412                         numberFields=2;
02413                      }
02414                   } else {
02415                      if (isInteger(i)) {
02416                         // Integer variable so BV or UI
02417                         if (fabs(upperValue-1.0)<1.0e-8) {
02418                            // BV
02419                            header[0]=" BV ";
02420                            value[0] = largeValue;
02421                         } else {
02422                            // UI
02423                            header[0]=" UI ";
02424                            value[0] = upperValue;
02425                         }
02426                      } else {
02427                         // UP
02428                         header[0]=" UP ";
02429                         value[0] = upperValue;
02430                      }
02431                   }
02432                }
02433                // put out fields
02434                int j;
02435                for (j=0;j<numberFields;j++) {
02436                   convertDouble(formatType,value[j],
02437                                 outputValue[0],
02438                                 columnNames[i],
02439                                 outputRow[0]);
02440                   // put out card
02441                   outputCard(formatType, 1,
02442                              fp, gzfp, header[j],
02443                              "BOUND",
02444                              outputValue,
02445                              outputRow);
02446                }
02447             }
02448          }
02449       }
02450    }
02451 
02452    // and finish
02453 
02454    writeString(fp, gzfp, "ENDATA\n");
02455 
02456    if (fp) {
02457       fclose(fp);
02458    }
02459 #ifdef COIN_USE_ZLIB
02460    if (gzfp) {
02461       gzclose(gzfp);
02462    }
02463 #endif
02464 
02465    return 0;
02466 }


Friends And Related Function Documentation

void CoinMpsIOUnitTest const std::string &  mpsDir  )  [friend]
 

A function that tests the methods in the CoinMpsIO 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. Also, if this method is compiled with optimization, the compilation takes 10-15 minutes and the machine pages (has 256M core memory!)...

Definition at line 21 of file CoinMpsIOTest.cpp.

00022 {
00023   
00024   // Test default constructor
00025   {
00026     CoinMpsIO m;
00027     assert( m.rowsense_==NULL );
00028     assert( m.rhs_==NULL );
00029     assert( m.rowrange_==NULL );
00030     assert( m.matrixByRow_==NULL );
00031     assert( m.matrixByColumn_==NULL );
00032     assert( m.integerType_==NULL);
00033     assert( !strcmp( m.getFileName() , "stdin"));
00034     assert( !strcmp( m.getProblemName() , ""));
00035     assert( !strcmp( m.objectiveName_ , ""));
00036     assert( !strcmp( m.rhsName_ , ""));
00037     assert( !strcmp( m.rangeName_ , ""));
00038     assert( !strcmp( m.boundName_ , ""));
00039   }
00040   
00041   
00042   {    
00043     CoinRelFltEq eq;
00044     CoinMpsIO m;
00045     std::string fn = mpsDir+"exmip1";
00046     int numErr = m.readMps(fn.c_str(),"mps");
00047     assert( numErr== 0 );
00048 
00049     assert( !strcmp( m.problemName_ , "EXAMPLE"));
00050     assert( !strcmp( m.objectiveName_ , "OBJ"));
00051     assert( !strcmp( m.rhsName_ , "RHS1"));
00052     assert( !strcmp( m.rangeName_ , "RNG1"));
00053     assert( !strcmp( m.boundName_ , "BND1"));
00054     
00055      // Test language and re-use
00056     m.newLanguage(CoinMessages::it);
00057     m.messageHandler()->setPrefix(false);
00058 
00059     // This call should return an error indicating that the 
00060     // end-of-file was reached.
00061     // This is because the file remains open to possibly read
00062     // a quad. section.
00063     numErr = m.readMps(fn.c_str(),"mps");
00064     assert( numErr < 0 );
00065 
00066     // Test copy constructor and assignment operator
00067     {
00068       CoinMpsIO lhs;
00069       {      
00070         CoinMpsIO im(m);        
00071         
00072         CoinMpsIO imC1(im);
00073         assert( imC1.getNumCols() == im.getNumCols() );
00074         assert( imC1.getNumRows() == im.getNumRows() );   
00075         
00076         CoinMpsIO imC2(im);
00077         assert( imC2.getNumCols() == im.getNumCols() );
00078         assert( imC2.getNumRows() == im.getNumRows() );  
00079         
00080         lhs=imC2;
00081       }
00082       // Test that lhs has correct values even though rhs has gone out of scope
00083       
00084       assert( lhs.getNumCols() == m.getNumCols() );
00085       assert( lhs.getNumRows() == m.getNumRows() );      
00086     }
00087     
00088     
00089     {    
00090       CoinMpsIO dumSi(m);
00091       int nc = dumSi.getNumCols();
00092       int nr = dumSi.getNumRows();
00093       const double * cl = dumSi.getColLower();
00094       const double * cu = dumSi.getColUpper();
00095       const double * rl = dumSi.getRowLower();
00096       const double * ru = dumSi.getRowUpper();
00097       assert( nc == 8 );
00098       assert( nr == 5 );
00099       assert( eq(cl[0],2.5) );
00100       assert( eq(cl[1],0.0) );
00101       assert( eq(cu[1],4.1) );
00102       assert( eq(cu[2],1.0) );
00103       assert( eq(rl[0],2.5) );
00104       assert( eq(rl[4],3.0) );
00105       assert( eq(ru[1],2.1) );
00106       assert( eq(ru[4],15.0) );
00107       
00108       assert( !eq(cl[3],1.2345) );
00109       
00110       assert( !eq(cu[4],10.2345) );
00111       
00112       assert( eq( dumSi.getObjCoefficients()[0],  1.0) );
00113       assert( eq( dumSi.getObjCoefficients()[1],  0.0) );
00114       assert( eq( dumSi.getObjCoefficients()[2],  0.0) );
00115       assert( eq( dumSi.getObjCoefficients()[3],  0.0) );
00116       assert( eq( dumSi.getObjCoefficients()[4],  2.0) );
00117       assert( eq( dumSi.getObjCoefficients()[5],  0.0) );
00118       assert( eq( dumSi.getObjCoefficients()[6],  0.0) );
00119       assert( eq( dumSi.getObjCoefficients()[7], -1.0) );
00120 
00121       dumSi.writeMps("CoinMpsIoTest.mps");//,0,0,1);
00122     }
00123 
00124     // Read just written file
00125     {    
00126       CoinMpsIO dumSi;
00127       dumSi.readMps("CoinMpsIoTest");
00128       int nc = dumSi.getNumCols();
00129       int nr = dumSi.getNumRows();
00130       const double * cl = dumSi.getColLower();
00131       const double * cu = dumSi.getColUpper();
00132       const double * rl = dumSi.getRowLower();
00133       const double * ru = dumSi.getRowUpper();
00134       assert( nc == 8 );
00135       assert( nr == 5 );
00136       assert( eq(cl[0],2.5) );
00137       assert( eq(cl[1],0.0) );
00138       assert( eq(cu[1],4.1) );
00139       assert( eq(cu[2],1.0) );
00140       assert( eq(rl[0],2.5) );
00141       assert( eq(rl[4],3.0) );
00142       assert( eq(ru[1],2.1) );
00143       assert( eq(ru[4],15.0) );
00144       
00145       assert( !eq(cl[3],1.2345) );
00146       
00147       assert( !eq(cu[4],10.2345) );
00148       
00149       assert( eq( dumSi.getObjCoefficients()[0],  1.0) );
00150       assert( eq( dumSi.getObjCoefficients()[1],  0.0) );
00151       assert( eq( dumSi.getObjCoefficients()[2],  0.0) );
00152       assert( eq( dumSi.getObjCoefficients()[3],  0.0) );
00153       assert( eq( dumSi.getObjCoefficients()[4],  2.0) );
00154       assert( eq( dumSi.getObjCoefficients()[5],  0.0) );
00155       assert( eq( dumSi.getObjCoefficients()[6],  0.0) );
00156       assert( eq( dumSi.getObjCoefficients()[7], -1.0) );
00157     }
00158     
00159     // Test matrixByRow method
00160     { 
00161       const CoinMpsIO si(m);
00162       const CoinPackedMatrix * smP = si.getMatrixByRow();
00163       // LL:      const CoinDumPackedMatrix * osmP = dynamic_cast<const CoinDumPackedMatrix*>(smP);
00164       // LL: assert( osmP!=NULL );
00165       
00166       CoinRelFltEq eq;
00167       const double * ev = smP->getElements();
00168       assert( eq(ev[0],   3.0) );
00169       assert( eq(ev[1],   1.0) );
00170       assert( eq(ev[2],  -2.0) );
00171       assert( eq(ev[3],  -1.0) );
00172       assert( eq(ev[4],  -1.0) );
00173       assert( eq(ev[5],   2.0) );
00174       assert( eq(ev[6],   1.1) );
00175       assert( eq(ev[7],   1.0) );
00176       assert( eq(ev[8],   1.0) );
00177       assert( eq(ev[9],   2.8) );
00178       assert( eq(ev[10], -1.2) );
00179       assert( eq(ev[11],  5.6) );
00180       assert( eq(ev[12],  1.0) );
00181       assert( eq(ev[13],  1.9) );
00182       
00183       const CoinBigIndex * mi = smP->getVectorStarts();
00184       assert( mi[0]==0 );
00185       assert( mi[1]==5 );
00186       assert( mi[2]==7 );
00187       assert( mi[3]==9 );
00188       assert( mi[4]==11 );
00189       assert( mi[5]==14 );
00190       
00191       const int * ei = smP->getIndices();
00192       assert( ei[0]  ==  0 );
00193       assert( ei[1]  ==  1 );
00194       assert( ei[2]  ==  3 );
00195       assert( ei[3]  ==  4 );
00196       assert( ei[4]  ==  7 );
00197       assert( ei[5]  ==  1 );
00198       assert( ei[6]  ==  2 );
00199       assert( ei[7]  ==  2 );
00200       assert( ei[8]  ==  5 );
00201       assert( ei[9]  ==  3 );
00202       assert( ei[10] ==  6 );
00203       assert( ei[11] ==  0 );
00204       assert( ei[12] ==  4 );
00205       assert( ei[13] ==  7 );    
00206       
00207       assert( smP->getMajorDim() == 5 ); 
00208       assert( smP->getNumElements() == 14 );
00209       
00210     }
00211         // Test matrixByCol method
00212     {
00213       
00214       const CoinMpsIO si(m);
00215       const CoinPackedMatrix * smP = si.getMatrixByCol();
00216       // LL:      const CoinDumPackedMatrix * osmP = dynamic_cast<const CoinDumPackedMatrix*>(smP);
00217       // LL: assert( osmP!=NULL );
00218       
00219       CoinRelFltEq eq;
00220       const double * ev = smP->getElements();
00221       assert( eq(ev[0],   3.0) );
00222       assert( eq(ev[1],   5.6) );
00223       assert( eq(ev[2],   1.0) );
00224       assert( eq(ev[3],   2.0) );
00225       assert( eq(ev[4],   1.1) );
00226       assert( eq(ev[5],   1.0) );
00227       assert( eq(ev[6],  -2.0) );
00228       assert( eq(ev[7],   2.8) );
00229       assert( eq(ev[8],  -1.0) );
00230       assert( eq(ev[9],   1.0) );
00231       assert( eq(ev[10],  1.0) );
00232       assert( eq(ev[11], -1.2) );
00233       assert( eq(ev[12], -1.0) );
00234       assert( eq(ev[13],  1.9) );
00235       
00236       const CoinBigIndex * mi = smP->getVectorStarts();
00237       assert( mi[0]==0 );
00238       assert( mi[1]==2 );
00239       assert( mi[2]==4 );
00240       assert( mi[3]==6 );
00241       assert( mi[4]==8 );
00242       assert( mi[5]==10 );
00243       assert( mi[6]==11 );
00244       assert( mi[7]==12 );
00245       assert( mi[8]==14 );
00246       
00247       const int * ei = smP->getIndices();
00248       assert( ei[0]  ==  0 );
00249       assert( ei[1]  ==  4 );
00250       assert( ei[2]  ==  0 );
00251       assert( ei[3]  ==  1 );
00252       assert( ei[4]  ==  1 );
00253       assert( ei[5]  ==  2 );
00254       assert( ei[6]  ==  0 );
00255       assert( ei[7]  ==  3 );
00256       assert( ei[8]  ==  0 );
00257       assert( ei[9]  ==  4 );
00258       assert( ei[10] ==  2 );
00259       assert( ei[11] ==  3 );
00260       assert( ei[12] ==  0 );
00261       assert( ei[13] ==  4 );    
00262       
00263       assert( smP->getMajorDim() == 8 ); 
00264       assert( smP->getNumElements() == 14 );
00265 
00266       assert( smP->getSizeVectorStarts()==9 );
00267       assert( smP->getMinorDim() == 5 );
00268       
00269     }
00270     //--------------
00271     // Test rowsense, rhs, rowrange, matrixByRow
00272     {
00273       CoinMpsIO lhs;
00274       {      
00275         assert( m.rowrange_==NULL );
00276         assert( m.rowsense_==NULL );
00277         assert( m.rhs_==NULL );
00278         assert( m.matrixByRow_==NULL );
00279         
00280         CoinMpsIO siC1(m);     
00281         assert( siC1.rowrange_==NULL );
00282         assert( siC1.rowsense_==NULL );
00283         assert( siC1.rhs_==NULL );
00284         assert( siC1.matrixByRow_==NULL );
00285 
00286         const char   * siC1rs  = siC1.getRowSense();
00287         assert( siC1rs[0]=='G' );
00288         assert( siC1rs[1]=='L' );
00289         assert( siC1rs[2]=='E' );
00290         assert( siC1rs[3]=='R' );
00291         assert( siC1rs[4]=='R' );
00292         
00293         const double * siC1rhs = siC1.getRightHandSide();
00294         assert( eq(siC1rhs[0],2.5) );
00295         assert( eq(siC1rhs[1],2.1) );
00296         assert( eq(siC1rhs[2],4.0) );
00297         assert( eq(siC1rhs[3],5.0) );
00298         assert( eq(siC1rhs[4],15.) ); 
00299         
00300         const double * siC1rr  = siC1.getRowRange();
00301         assert( eq(siC1rr[0],0.0) );
00302         assert( eq(siC1rr[1],0.0) );
00303         assert( eq(siC1rr[2],0.0) );
00304         assert( eq(siC1rr[3],5.0-1.8) );
00305         assert( eq(siC1rr[4],15.0-3.0) );
00306         
00307         const CoinPackedMatrix * siC1mbr = siC1.getMatrixByRow();
00308         assert( siC1mbr != NULL );
00309         
00310         const double * ev = siC1mbr->getElements();
00311         assert( eq(ev[0],   3.0) );
00312         assert( eq(ev[1],   1.0) );
00313         assert( eq(ev[2],  -2.0) );
00314         assert( eq(ev[3],  -1.0) );
00315         assert( eq(ev[4],  -1.0) );
00316         assert( eq(ev[5],   2.0) );
00317         assert( eq(ev[6],   1.1) );
00318         assert( eq(ev[7],   1.0) );
00319         assert( eq(ev[8],   1.0) );
00320         assert( eq(ev[9],   2.8) );
00321         assert( eq(ev[10], -1.2) );
00322         assert( eq(ev[11],  5.6) );
00323         assert( eq(ev[12],  1.0) );
00324         assert( eq(ev[13],  1.9) );
00325         
00326         const CoinBigIndex * mi = siC1mbr->getVectorStarts();
00327         assert( mi[0]==0 );
00328         assert( mi[1]==5 );
00329         assert( mi[2]==7 );
00330         assert( mi[3]==9 );
00331         assert( mi[4]==11 );
00332         assert( mi[5]==14 );
00333         
00334         const int * ei = siC1mbr->getIndices();
00335         assert( ei[0]  ==  0 );
00336         assert( ei[1]  ==  1 );
00337         assert( ei[2]  ==  3 );
00338         assert( ei[3]  ==  4 );
00339         assert( ei[4]  ==  7 );
00340         assert( ei[5]  ==  1 );
00341         assert( ei[6]  ==  2 );
00342         assert( ei[7]  ==  2 );
00343         assert( ei[8]  ==  5 );
00344         assert( ei[9]  ==  3 );
00345         assert( ei[10] ==  6 );
00346         assert( ei[11] ==  0 );
00347         assert( ei[12] ==  4 );
00348         assert( ei[13] ==  7 );    
00349         
00350         assert( siC1mbr->getMajorDim() == 5 ); 
00351         assert( siC1mbr->getNumElements() == 14 );
00352         
00353 
00354         assert( siC1rs  == siC1.getRowSense() );
00355         assert( siC1rhs == siC1.getRightHandSide() );
00356         assert( siC1rr  == siC1.getRowRange() );
00357       }
00358     }
00359   }
00360   
00361 }


Member Data Documentation

bool CoinMpsIO::defaultHandler_ [protected]
 

Flag to say if the message handler is the default handler.

If true, the handler will be destroyed when the CoinMpsIO object is destroyed; if false, it will not be destroyed.

Definition at line 746 of file CoinMpsIO.hpp.

Referenced by CoinMpsIO(), gutsOfCopy(), gutsOfDestructor(), operator=(), and passInMessageHandler().

char* CoinMpsIO::integerType_ [protected]
 

Pointer to dense vector specifying if a variable is continuous (0) or integer (1).

Definition at line 711 of file CoinMpsIO.hpp.

Referenced by copyInIntegerInformation(), freeAll(), gutsOfCopy(), integerColumns(), isContinuous(), isInteger(), readMps(), releaseIntegerInformation(), and setMpsDataWithoutRowAndColNames().

char** CoinMpsIO::names_[2] [protected]
 

Row and column names Linked to hash table sections (0 - row names, 1 column names)

Definition at line 716 of file CoinMpsIO.hpp.

Referenced by findHash(), gutsOfCopy(), startHash(), and writeMps().

double* CoinMpsIO::rowrange_ [mutable, protected]
 

Pointer to dense vector of slack variable upper bounds for range constraints (undefined for non-range rows)

Definition at line 681 of file CoinMpsIO.hpp.

Referenced by getRowRange(), and releaseRedundantInformation().


The documentation for this class was generated from the following files:
Generated on Wed Dec 3 14:34:28 2003 for Coin by doxygen 1.3.5