1/* $Id: CoinMpsIO.hpp 1448 2011-06-19 15:34:41Z stefan $ */
2// Copyright (C) 2000, International Business Machines
3// Corporation and others. All Rights Reserved.
4// This code is licensed under the terms of the Eclipse Public License (EPL).
5
6#ifndef CoinMpsIO_H
7#define CoinMpsIO_H
8
9#if defined(_MSC_VER)
10// Turn off compiler warning about long names
11# pragma warning(disable:4786)
12#endif
13
14#include <vector>
15#include <string>
16
17#include "CoinUtilsConfig.h"
18#include "CoinPackedMatrix.hpp"
19#include "CoinMessageHandler.hpp"
20#include "CoinFileIO.hpp"
21class CoinModel;
22
23/// The following lengths are in decreasing order (for 64 bit etc)
24/// Large enough to contain element index
25/// This is already defined as CoinBigIndex
26/// Large enough to contain column index
27typedef int COINColumnIndex;
28
29/// Large enough to contain row index (or basis)
30typedef int COINRowIndex;
31
32// We are allowing free format - but there is a limit!
33// User can override by using CXXFLAGS += -DCOIN_MAX_FIELD_LENGTH=nnn
34#ifndef COIN_MAX_FIELD_LENGTH
35#define COIN_MAX_FIELD_LENGTH 160
36#endif
37#define MAX_CARD_LENGTH 5*COIN_MAX_FIELD_LENGTH+80
38
39enum COINSectionType { COIN_NO_SECTION, COIN_NAME_SECTION, COIN_ROW_SECTION,
40 COIN_COLUMN_SECTION,
41 COIN_RHS_SECTION, COIN_RANGES_SECTION, COIN_BOUNDS_SECTION,
42 COIN_ENDATA_SECTION, COIN_EOF_SECTION, COIN_QUADRATIC_SECTION,
43 COIN_CONIC_SECTION,COIN_QUAD_SECTION,COIN_SOS_SECTION,
44 COIN_BASIS_SECTION,COIN_UNKNOWN_SECTION
45};
46
47enum COINMpsType { COIN_N_ROW, COIN_E_ROW, COIN_L_ROW, COIN_G_ROW,
48 COIN_BLANK_COLUMN, COIN_S1_COLUMN, COIN_S2_COLUMN, COIN_S3_COLUMN,
49 COIN_INTORG, COIN_INTEND, COIN_SOSEND, COIN_UNSET_BOUND,
50 COIN_UP_BOUND, COIN_FX_BOUND, COIN_LO_BOUND, COIN_FR_BOUND,
51 COIN_MI_BOUND, COIN_PL_BOUND, COIN_BV_BOUND, COIN_UI_BOUND, COIN_LI_BOUND,
52 COIN_SC_BOUND, COIN_S1_BOUND, COIN_S2_BOUND,
53 COIN_BS_BASIS, COIN_XL_BASIS, COIN_XU_BASIS,
54 COIN_LL_BASIS, COIN_UL_BASIS, COIN_UNKNOWN_MPS_TYPE
55};
56class CoinMpsIO;
57/// Very simple code for reading MPS data
58class CoinMpsCardReader {
59
60public:
61
62 /**@name Constructor and destructor */
63 //@{
64 /// Constructor expects file to be open
65 /// This one takes gzFile if fp null
66 CoinMpsCardReader ( CoinFileInput *input, CoinMpsIO * reader );
67
68 /// Destructor
69 ~CoinMpsCardReader ( );
70 //@}
71
72
73 /**@name card stuff */
74 //@{
75 /// Read to next section
76 COINSectionType readToNextSection ( );
77 /// Gets next field and returns section type e.g. COIN_COLUMN_SECTION
78 COINSectionType nextField ( );
79 /** Gets next field for .gms file and returns type.
80 -1 - EOF
81 0 - what we expected (and processed so pointer moves past)
82 1 - not what we expected
83 leading blanks always ignored
84 input types
85 0 - anything - stops on non blank card
86 1 - name (in columnname)
87 2 - value
88 3 - value name pair
89 4 - equation type
90 5 - ;
91 */
92 int nextGmsField ( int expectedType );
93 /// Returns current section type
94 inline COINSectionType whichSection ( ) const {
95 return section_;
96 }
97 /// Sets current section type
98 inline void setWhichSection(COINSectionType section ) {
99 section_=section;
100 }
101 /// Sees if free format.
102 inline bool freeFormat() const
103 { return freeFormat_;}
104 /// Sets whether free format. Mainly for blank RHS etc
105 inline void setFreeFormat(bool yesNo)
106 { freeFormat_=yesNo;}
107 /// Only for first field on card otherwise BLANK_COLUMN
108 /// e.g. COIN_E_ROW
109 inline COINMpsType mpsType ( ) const {
110 return mpsType_;
111 }
112 /// Reads and cleans card - taking out trailing blanks - return 1 if EOF
113 int cleanCard();
114 /// Returns row name of current field
115 inline const char *rowName ( ) const {
116 return rowName_;
117 }
118 /// Returns column name of current field
119 inline const char *columnName ( ) const {
120 return columnName_;
121 }
122 /// Returns value in current field
123 inline double value ( ) const {
124 return value_;
125 }
126 /// Returns value as string in current field
127 inline const char *valueString ( ) const {
128 return valueString_;
129 }
130 /// Whole card (for printing)
131 inline const char *card ( ) const {
132 return card_;
133 }
134 /// Whole card - so we look at it (not const so nextBlankOr will work for gms reader)
135 inline char *mutableCard ( ) {
136 return card_;
137 }
138 /// set position (again so gms reader will work)
139 inline void setPosition(char * position)
140 { position_=position;}
141 /// get position (again so gms reader will work)
142 inline char * getPosition() const
143 { return position_;}
144 /// Returns card number
145 inline CoinBigIndex cardNumber ( ) const {
146 return cardNumber_;
147 }
148 /// Returns file input
149 inline CoinFileInput * fileInput ( ) const {
150 return input_;
151 }
152 /// Sets whether strings allowed
153 inline void setStringsAllowed()
154 { stringsAllowed_=true;}
155 //@}
156
157////////////////// data //////////////////
158protected:
159
160 /**@name data */
161 //@{
162 /// Current value
163 double value_;
164 /// Current card image
165 char card_[MAX_CARD_LENGTH];
166 /// Current position within card image
167 char *position_;
168 /// End of card
169 char *eol_;
170 /// Current COINMpsType
171 COINMpsType mpsType_;
172 /// Current row name
173 char rowName_[COIN_MAX_FIELD_LENGTH];
174 /// Current column name
175 char columnName_[COIN_MAX_FIELD_LENGTH];
176 /// File input
177 CoinFileInput *input_;
178 /// Which section we think we are in
179 COINSectionType section_;
180 /// Card number
181 CoinBigIndex cardNumber_;
182 /// Whether free format. Just for blank RHS etc
183 bool freeFormat_;
184 /// Whether IEEE - 0 no, 1 INTEL, 2 not INTEL
185 int ieeeFormat_;
186 /// If all names <= 8 characters then allow embedded blanks
187 bool eightChar_;
188 /// MpsIO
189 CoinMpsIO * reader_;
190 /// Message handler
191 CoinMessageHandler * handler_;
192 /// Messages
193 CoinMessages messages_;
194 /// Current element as characters (only if strings allowed)
195 char valueString_[COIN_MAX_FIELD_LENGTH];
196 /// Whether strings allowed
197 bool stringsAllowed_;
198 //@}
199public:
200 /**@name methods */
201 //@{
202 /// type - 0 normal, 1 INTEL IEEE, 2 other IEEE
203 double osi_strtod(char * ptr, char ** output, int type);
204 /// remove blanks
205 static void strcpyAndCompress ( char *to, const char *from );
206 ///
207 static char * nextBlankOr ( char *image );
208 /// For strings
209 double osi_strtod(char * ptr, char ** output);
210 //@}
211
212};
213
214//#############################################################################
215#ifdef USE_SBB
216class SbbObject;
217class SbbModel;
218#endif
219/// Very simple class for containing data on set
220class CoinSet {
221
222public:
223
224 /**@name Constructor and destructor */
225 //@{
226 /// Default constructor
227 CoinSet ( );
228 /// Constructor
229 CoinSet ( int numberEntries, const int * which);
230
231 /// Copy constructor
232 CoinSet (const CoinSet &);
233
234 /// Assignment operator
235 CoinSet & operator=(const CoinSet& rhs);
236
237 /// Destructor
238 virtual ~CoinSet ( );
239 //@}
240
241
242 /**@name gets */
243 //@{
244 /// Returns number of entries
245 inline int numberEntries ( ) const
246 { return numberEntries_; }
247 /// Returns type of set - 1 =SOS1, 2 =SOS2
248 inline int setType ( ) const
249 { return setType_; }
250 /// Returns list of variables
251 inline const int * which ( ) const
252 { return which_; }
253 /// Returns weights
254 inline const double * weights ( ) const
255 { return weights_; }
256 //@}
257
258#ifdef USE_SBB
259 /**@name Use in sbb */
260 //@{
261 /// returns an object of type SbbObject
262 virtual SbbObject * sbbObject(SbbModel * model) const
263 { return NULL;}
264 //@}
265#endif
266
267////////////////// data //////////////////
268protected:
269
270 /**@name data */
271 //@{
272 /// Number of entries
273 int numberEntries_;
274 /// type of set
275 int setType_;
276 /// Which variables are in set
277 int * which_;
278 /// Weights
279 double * weights_;
280 //@}
281};
282
283//#############################################################################
284/// Very simple class for containing SOS set
285class CoinSosSet : public CoinSet{
286
287public:
288
289 /**@name Constructor and destructor */
290 //@{
291 /// Constructor
292 CoinSosSet ( int numberEntries, const int * which, const double * weights, int type);
293
294 /// Destructor
295 virtual ~CoinSosSet ( );
296 //@}
297
298
299#ifdef USE_SBB
300 /**@name Use in sbb */
301 //@{
302 /// returns an object of type SbbObject
303 virtual SbbObject * sbbObject(SbbModel * model) const ;
304 //@}
305#endif
306
307////////////////// data //////////////////
308protected:
309
310 /**@name data */
311 //@{
312 //@}
313};
314
315//#############################################################################
316
317/** MPS IO Interface
318
319 This class can be used to read in mps files without a solver. After
320 reading the file, the CoinMpsIO object contains all relevant data, which
321 may be more than a particular OsiSolverInterface allows for. Items may
322 be deleted to allow for flexibility of data storage.
323
324 The implementation makes the CoinMpsIO object look very like a dummy solver,
325 as the same conventions are used.
326*/
327
328class CoinMpsIO {
329 friend void CoinMpsIOUnitTest(const std::string & mpsDir);
330
331public:
332
333/** @name Methods to retrieve problem information
334
335 These methods return information about the problem held by the CoinMpsIO
336 object.
337
338 Querying an object that has no data associated with it result in zeros for
339 the number of rows and columns, and NULL pointers from the methods that
340 return vectors. Const pointers returned from any data-query method are
341 always valid
342*/
343//@{
344 /// Get number of columns
345 int getNumCols() const;
346
347 /// Get number of rows
348 int getNumRows() const;
349
350 /// Get number of nonzero elements
351 int getNumElements() const;
352
353 /// Get pointer to array[getNumCols()] of column lower bounds
354 const double * getColLower() const;
355
356 /// Get pointer to array[getNumCols()] of column upper bounds
357 const double * getColUpper() const;
358
359 /** Get pointer to array[getNumRows()] of constraint senses.
360 <ul>
361 <li>'L': <= constraint
362 <li>'E': = constraint
363 <li>'G': >= constraint
364 <li>'R': ranged constraint
365 <li>'N': free constraint
366 </ul>
367 */
368 const char * getRowSense() const;
369
370 /** Get pointer to array[getNumRows()] of constraint right-hand sides.
371
372 Given constraints with upper (rowupper) and/or lower (rowlower) bounds,
373 the constraint right-hand side (rhs) is set as
374 <ul>
375 <li> if rowsense()[i] == 'L' then rhs()[i] == rowupper()[i]
376 <li> if rowsense()[i] == 'G' then rhs()[i] == rowlower()[i]
377 <li> if rowsense()[i] == 'R' then rhs()[i] == rowupper()[i]
378 <li> if rowsense()[i] == 'N' then rhs()[i] == 0.0
379 </ul>
380 */
381 const double * getRightHandSide() const;
382
383 /** Get pointer to array[getNumRows()] of row ranges.
384
385 Given constraints with upper (rowupper) and/or lower (rowlower) bounds,
386 the constraint range (rowrange) is set as
387 <ul>
388 <li> if rowsense()[i] == 'R' then
389 rowrange()[i] == rowupper()[i] - rowlower()[i]
390 <li> if rowsense()[i] != 'R' then
391 rowrange()[i] is 0.0
392 </ul>
393 Put another way, only range constraints have a nontrivial value for
394 rowrange.
395 */
396 const double * getRowRange() const;
397
398 /// Get pointer to array[getNumRows()] of row lower bounds
399 const double * getRowLower() const;
400
401 /// Get pointer to array[getNumRows()] of row upper bounds
402 const double * getRowUpper() const;
403
404 /// Get pointer to array[getNumCols()] of objective function coefficients
405 const double * getObjCoefficients() const;
406
407 /// Get pointer to row-wise copy of the coefficient matrix
408 const CoinPackedMatrix * getMatrixByRow() const;
409
410 /// Get pointer to column-wise copy of the coefficient matrix
411 const CoinPackedMatrix * getMatrixByCol() const;
412
413 /// Return true if column is a continuous variable
414 bool isContinuous(int colNumber) const;
415
416 /** Return true if a column is an integer variable
417
418 Note: This function returns true if the the column
419 is a binary or general integer variable.
420 */
421 bool isInteger(int columnNumber) const;
422
423 /** Returns array[getNumCols()] specifying if a variable is integer.
424
425 At present, simply coded as zero (continuous) and non-zero (integer)
426 May be extended at a later date.
427 */
428 const char * integerColumns() const;
429
430 /** Returns the row name for the specified index.
431
432 Returns 0 if the index is out of range.
433 */
434 const char * rowName(int index) const;
435
436 /** Returns the column name for the specified index.
437
438 Returns 0 if the index is out of range.
439 */
440 const char * columnName(int index) const;
441
442 /** Returns the index for the specified row name
443
444 Returns -1 if the name is not found.
445 Returns numberRows for the objective row and > numberRows for
446 dropped free rows.
447 */
448 int rowIndex(const char * name) const;
449
450 /** Returns the index for the specified column name
451
452 Returns -1 if the name is not found.
453 */
454 int columnIndex(const char * name) const;
455
456 /** Returns the (constant) objective offset
457
458 This is the RHS entry for the objective row
459 */
460 double objectiveOffset() const;
461 /// Set objective offset
462 inline void setObjectiveOffset(double value)
463 { objectiveOffset_=value;}
464
465 /// Return the problem name
466 const char * getProblemName() const;
467
468 /// Return the objective name
469 const char * getObjectiveName() const;
470
471 /// Return the RHS vector name
472 const char * getRhsName() const;
473
474 /// Return the range vector name
475 const char * getRangeName() const;
476
477 /// Return the bound vector name
478 const char * getBoundName() const;
479 /// Number of string elements
480 inline int numberStringElements() const
481 { return numberStringElements_;}
482 /// String element
483 inline const char * stringElement(int i) const
484 { return stringElements_[i];}
485//@}
486
487
488/** @name Methods to set problem information
489
490 Methods to load a problem into the CoinMpsIO object.
491*/
492//@{
493
494 /// Set the problem data
495 void setMpsData(const CoinPackedMatrix& m, const double infinity,
496 const double* collb, const double* colub,
497 const double* obj, const char* integrality,
498 const double* rowlb, const double* rowub,
499 char const * const * const colnames,
500 char const * const * const rownames);
501 void setMpsData(const CoinPackedMatrix& m, const double infinity,
502 const double* collb, const double* colub,
503 const double* obj, const char* integrality,
504 const double* rowlb, const double* rowub,
505 const std::vector<std::string> & colnames,
506 const std::vector<std::string> & rownames);
507 void setMpsData(const CoinPackedMatrix& m, const double infinity,
508 const double* collb, const double* colub,
509 const double* obj, const char* integrality,
510 const char* rowsen, const double* rowrhs,
511 const double* rowrng,
512 char const * const * const colnames,
513 char const * const * const rownames);
514 void setMpsData(const CoinPackedMatrix& m, const double infinity,
515 const double* collb, const double* colub,
516 const double* obj, const char* integrality,
517 const char* rowsen, const double* rowrhs,
518 const double* rowrng,
519 const std::vector<std::string> & colnames,
520 const std::vector<std::string> & rownames);
521
522 /** Pass in an array[getNumCols()] specifying if a variable is integer.
523
524 At present, simply coded as zero (continuous) and non-zero (integer)
525 May be extended at a later date.
526 */
527 void copyInIntegerInformation(const char * integerInformation);
528
529 /// Set problem name
530 void setProblemName(const char *name) ;
531
532 /// Set objective name
533 void setObjectiveName(const char *name) ;
534
535//@}
536
537/** @name Parameter set/get methods
538
539 Methods to set and retrieve MPS IO parameters.
540*/
541
542//@{
543 /// Set infinity
544 void setInfinity(double value);
545
546 /// Get infinity
547 double getInfinity() const;
548
549 /// Set default upper bound for integer variables
550 void setDefaultBound(int value);
551
552 /// Get default upper bound for integer variables
553 int getDefaultBound() const;
554 /// Whether to allow string elements
555 inline int allowStringElements() const
556 { return allowStringElements_;}
557 /// Whether to allow string elements (0 no, 1 yes, 2 yes and try flip)
558 inline void setAllowStringElements(int yesNo)
559 { allowStringElements_ = yesNo;}
560 /** Small element value - elements less than this set to zero on input
561 default is 1.0e-14 */
562 inline double getSmallElementValue() const
563 { return smallElement_;}
564 inline void setSmallElementValue(double value)
565 { smallElement_=value;}
566//@}
567
568
569/** @name Methods for problem input and output
570
571 Methods to read and write MPS format problem files.
572
573 The read and write methods return the number of errors that occurred during
574 the IO operation, or -1 if no file is opened.
575
576 \note
577 If the CoinMpsIO class was compiled with support for libz then
578 readMps will automatically try to append .gz to the file name and open it as
579 a compressed file if the specified file name cannot be opened.
580 (Automatic append of the .bz2 suffix when libbz is used is on the TODO list.)
581
582 \todo
583 Allow for file pointers and positioning
584*/
585
586//@{
587 /// Set the current file name for the CoinMpsIO object
588 void setFileName(const char * name);
589
590 /// Get the current file name for the CoinMpsIO object
591 const char * getFileName() const;
592
593 /** Read a problem in MPS format from the given filename.
594
595 Use "stdin" or "-" to read from stdin.
596 */
597 int readMps(const char *filename, const char *extension = "mps");
598
599 /** Read a problem in MPS format from the given filename.
600
601 Use "stdin" or "-" to read from stdin.
602 But do sets as well
603 */
604 int readMps(const char *filename, const char *extension ,
605 int & numberSets, CoinSet **& sets);
606
607 /** Read a problem in MPS format from a previously opened file
608
609 More precisely, read a problem using a CoinMpsCardReader object already
610 associated with this CoinMpsIO object.
611
612 \todo
613 Provide an interface that will allow a client to associate a
614 CoinMpsCardReader object with a CoinMpsIO object by setting the
615 cardReader_ field.
616 */
617 int readMps();
618 /// and
619 int readMps(int & numberSets, CoinSet **& sets);
620 /** Read a basis in MPS format from the given filename.
621 If VALUES on NAME card and solution not NULL fills in solution
622 status values as for CoinWarmStartBasis (but one per char)
623 -1 file error, 0 normal, 1 has solution values
624
625 Use "stdin" or "-" to read from stdin.
626
627 If sizes of names incorrect - read without names
628 */
629 int readBasis(const char *filename, const char *extension ,
630 double * solution, unsigned char *rowStatus, unsigned char *columnStatus,
631 const std::vector<std::string> & colnames,int numberColumns,
632 const std::vector<std::string> & rownames, int numberRows);
633
634 /** Read a problem in GAMS format from the given filename.
635
636 Use "stdin" or "-" to read from stdin.
637 if convertObjective then massages objective column
638 */
639 int readGms(const char *filename, const char *extension = "gms",bool convertObjective=false);
640
641 /** Read a problem in GAMS format from the given filename.
642
643 Use "stdin" or "-" to read from stdin.
644 But do sets as well
645 */
646 int readGms(const char *filename, const char *extension ,
647 int & numberSets, CoinSet **& sets);
648
649 /** Read a problem in GAMS format from a previously opened file
650
651 More precisely, read a problem using a CoinMpsCardReader object already
652 associated with this CoinMpsIO object.
653
654 */
655 // Not for now int readGms();
656 /// and
657 int readGms(int & numberSets, CoinSet **& sets);
658 /** Read a problem in GMPL (subset of AMPL) format from the given filenames.
659 */
660 int readGMPL(const char *modelName, const char * dataName=nullptr, bool keepNames=false);
661
662 /** Write the problem in MPS format to a file with the given filename.
663
664 \param compression can be set to three values to indicate what kind
665 of file should be written
666 <ul>
667 <li> 0: plain text (default)
668 <li> 1: gzip compressed (.gz is appended to \c filename)
669 <li> 2: bzip2 compressed (.bz2 is appended to \c filename) (TODO)
670 </ul>
671 If the library was not compiled with the requested compression then
672 writeMps falls back to writing a plain text file.
673
674 \param formatType specifies the precision to used for values in the
675 MPS file
676 <ul>
677 <li> 0: normal precision (default)
678 <li> 1: extra accuracy
679 <li> 2: IEEE hex
680 </ul>
681
682 \param numberAcross specifies whether 1 or 2 (default) values should be
683 specified on every data line in the MPS file.
684
685 \param quadratic specifies quadratic objective to be output
686 */
687 int writeMps(const char *filename, int compression = 0,
688 int formatType = 0, int numberAcross = 2,
689 CoinPackedMatrix * quadratic = nullptr,
690 int numberSOS=0,const CoinSet * setInfo=nullptr) const;
691
692 /// Return card reader object so can see what last card was e.g. QUADOBJ
693 inline const CoinMpsCardReader * reader() const
694 { return cardReader_;}
695
696 /** Read in a quadratic objective from the given filename.
697
698 If filename is NULL (or the same as the currently open file) then
699 reading continues from the current file.
700 If not, the file is closed and the specified file is opened.
701
702 Code should be added to
703 general MPS reader to read this if QSECTION
704 Data is assumed to be Q and objective is c + 1/2 xT Q x
705 No assumption is made for symmetry, positive definite, etc.
706 No check is made for duplicates or non-triangular if checkSymmetry==0.
707 If 1 checks lower triangular (so off diagonal should be 2*Q)
708 if 2 makes lower triangular and assumes full Q (but adds off diagonals)
709
710 Arrays should be deleted by delete []
711
712 Returns number of errors:
713 <ul>
714 <li> -1: bad file
715 <li> -2: no Quadratic section
716 <li> -3: an empty section
717 <li> +n: then matching errors etc (symmetry forced)
718 <li> -4: no matching errors but fails triangular test
719 (triangularity forced)
720 </ul>
721 columnStart is numberColumns+1 long, others numberNonZeros
722 */
723 int readQuadraticMps(const char * filename,
724 int * &columnStart, int * &column, double * &elements,
725 int checkSymmetry);
726
727 /** Read in a list of cones from the given filename.
728
729 If filename is NULL (or the same as the currently open file) then
730 reading continues from the current file.
731 If not, the file is closed and the specified file is opened.
732
733 Code should be added to
734 general MPS reader to read this if CSECTION
735 No checking is done that in unique cone
736
737 Arrays should be deleted by delete []
738
739 Returns number of errors, -1 bad file, -2 no conic section,
740 -3 empty section
741
742 columnStart is numberCones+1 long, other number of columns in matrix
743 */
744 int readConicMps(const char * filename,
745 int * &columnStart, int * &column, int & numberCones);
746 /// Set whether to move objective from matrix
747 inline void setConvertObjective(bool trueFalse)
748 { convertObjective_=trueFalse;}
749 /// copies in strings from a CoinModel - returns number
750 int copyStringElements(const CoinModel * model);
751 //@}
752
753/** @name Constructors and destructors */
754//@{
755 /// Default Constructor
756 CoinMpsIO();
757
758 /// Copy constructor
759 CoinMpsIO (const CoinMpsIO &);
760
761 /// Assignment operator
762 CoinMpsIO & operator=(const CoinMpsIO& rhs);
763
764 /// Destructor
765 ~CoinMpsIO ();
766//@}
767
768
769/**@name Message handling */
770//@{
771 /** Pass in Message handler
772
773 Supply a custom message handler. It will not be destroyed when the
774 CoinMpsIO object is destroyed.
775 */
776 void passInMessageHandler(CoinMessageHandler * handler);
777
778 /// Set the language for messages.
779 void newLanguage(CoinMessages::Language language);
780
781 /// Set the language for messages.
782 inline void setLanguage(CoinMessages::Language language) {newLanguage(language);}
783
784 /// Return the message handler
785 inline CoinMessageHandler * messageHandler() const {return handler_;}
786
787 /// Return the messages
788 inline CoinMessages messages() {return messages_;}
789 /// Return the messages pointer
790 inline CoinMessages * messagesPointer() {return & messages_;}
791//@}
792
793
794/**@name Methods to release storage
795
796 These methods allow the client to reduce the storage used by the CoinMpsIO
797 object be selectively releasing unneeded problem information.
798*/
799//@{
800 /** Release all information which can be re-calculated.
801
802 E.g., row sense, copies of rows, hash tables for names.
803 */
804 void releaseRedundantInformation();
805
806 /// Release all row information (lower, upper)
807 void releaseRowInformation();
808
809 /// Release all column information (lower, upper, objective)
810 void releaseColumnInformation();
811
812 /// Release integer information
813 void releaseIntegerInformation();
814
815 /// Release row names
816 void releaseRowNames();
817
818 /// Release column names
819 void releaseColumnNames();
820
821 /// Release matrix information
822 void releaseMatrixInformation();
823 //@}
824
825protected:
826
827/**@name Miscellaneous helper functions */
828 //@{
829
830 /// Utility method used several times to implement public methods
831 void
832 setMpsDataWithoutRowAndColNames(
833 const CoinPackedMatrix& m, const double infinity,
834 const double* collb, const double* colub,
835 const double* obj, const char* integrality,
836 const double* rowlb, const double* rowub);
837 void
838 setMpsDataColAndRowNames(
839 const std::vector<std::string> & colnames,
840 const std::vector<std::string> & rownames);
841 void
842 setMpsDataColAndRowNames(
843 char const * const * const colnames,
844 char const * const * const rownames);
845
846
847 /// Does the heavy lifting for destruct and assignment.
848 void gutsOfDestructor();
849
850 /// Does the heavy lifting for copy and assignment.
851 void gutsOfCopy(const CoinMpsIO &);
852
853 /// Clears problem data from the CoinMpsIO object.
854 void freeAll();
855
856
857 /** A quick inlined function to convert from lb/ub style constraint
858 definition to sense/rhs/range style */
859 inline void
860 convertBoundToSense(const double lower, const double upper,
861 char& sense, double& right, double& range) const;
862 /** A quick inlined function to convert from sense/rhs/range stryle
863 constraint definition to lb/ub style */
864 inline void
865 convertSenseToBound(const char sense, const double right,
866 const double range,
867 double& lower, double& upper) const;
868
869 /** Deal with a filename
870
871 As the name says.
872 Returns +1 if the file name is new, 0 if it's the same as before
873 (i.e., matches fileName_), and -1 if there's an error and the file
874 can't be opened.
875 Handles automatic append of .gz suffix when compiled with libz.
876
877 \todo
878 Add automatic append of .bz2 suffix when compiled with libbz.
879 */
880
881 int dealWithFileName(const char * filename, const char * extension,
882 CoinFileInput * &input);
883 /** Add string to list
884 iRow==numberRows is objective, nr+1 is lo, nr+2 is up
885 iColumn==nc is rhs (can't cope with ranges at present)
886 */
887 void addString(int iRow,int iColumn, const char * value);
888 /// Decode string
889 void decodeString(int iString, int & iRow, int & iColumn, const char * & value) const;
890 //@}
891
892
893 // for hashing
894 typedef struct {
895 int index, next;
896 } CoinHashLink;
897
898 /**@name Hash table methods */
899 //@{
900 /// Creates hash list for names (section = 0 for rows, 1 columns)
901 void startHash ( char **names, const int number , int section );
902 /// This one does it when names are already in
903 void startHash ( int section ) const;
904 /// Deletes hash storage
905 void stopHash ( int section );
906 /// Finds match using hash, -1 not found
907 int findHash ( const char *name , int section ) const;
908 //@}
909
910 /**@name Cached problem information */
911 //@{
912 /// Problem name
913 char * problemName_;
914
915 /// Objective row name
916 char * objectiveName_;
917
918 /// Right-hand side vector name
919 char * rhsName_;
920
921 /// Range vector name
922 char * rangeName_;
923
924 /// Bounds vector name
925 char * boundName_;
926
927 /// Number of rows
928 int numberRows_;
929
930 /// Number of columns
931 int numberColumns_;
932
933 /// Number of coefficients
934 CoinBigIndex numberElements_;
935
936 /// Pointer to dense vector of row sense indicators
937 mutable char *rowsense_;
938
939 /// Pointer to dense vector of row right-hand side values
940 mutable double *rhs_;
941
942 /** Pointer to dense vector of slack variable upper bounds for range
943 constraints (undefined for non-range rows)
944 */
945 mutable double *rowrange_;
946
947 /// Pointer to row-wise copy of problem matrix coefficients.
948 mutable CoinPackedMatrix *matrixByRow_;
949
950 /// Pointer to column-wise copy of problem matrix coefficients.
951 CoinPackedMatrix *matrixByColumn_;
952
953 /// Pointer to dense vector of row lower bounds
954 double * rowlower_;
955
956 /// Pointer to dense vector of row upper bounds
957 double * rowupper_;
958
959 /// Pointer to dense vector of column lower bounds
960 double * collower_;
961
962 /// Pointer to dense vector of column upper bounds
963 double * colupper_;
964
965 /// Pointer to dense vector of objective coefficients
966 double * objective_;
967
968 /// Constant offset for objective value (i.e., RHS value for OBJ row)
969 double objectiveOffset_;
970
971
972 /** Pointer to dense vector specifying if a variable is continuous
973 (0) or integer (1).
974 */
975 char * integerType_;
976
977 /** Row and column names
978 Linked to hash table sections (0 - row names, 1 column names)
979 */
980 char **names_[2];
981 //@}
982
983 /** @name Hash tables */
984 //@{
985 /// Current file name
986 char * fileName_;
987
988 /// Number of entries in a hash table section
989 int numberHash_[2];
990
991 /// Hash tables (two sections, 0 - row names, 1 - column names)
992 mutable CoinHashLink *hash_[2];
993 //@}
994
995 /** @name CoinMpsIO object parameters */
996 //@{
997 /// Upper bound when no bounds for integers
998 int defaultBound_;
999
1000 /// Value to use for infinity
1001 double infinity_;
1002 /// Small element value
1003 double smallElement_;
1004
1005 /// Message handler
1006 CoinMessageHandler * handler_;
1007 /** Flag to say if the message handler is the default handler.
1008
1009 If true, the handler will be destroyed when the CoinMpsIO
1010 object is destroyed; if false, it will not be destroyed.
1011 */
1012 bool defaultHandler_;
1013 /// Messages
1014 CoinMessages messages_;
1015 /// Card reader
1016 CoinMpsCardReader * cardReader_;
1017 /// If .gms file should it be massaged to move objective
1018 bool convertObjective_;
1019 /// Whether to allow string elements
1020 int allowStringElements_;
1021 /// Maximum number of string elements
1022 int maximumStringElements_;
1023 /// Number of string elements
1024 int numberStringElements_;
1025 /// String elements
1026 char ** stringElements_;
1027 //@}
1028
1029};
1030
1031//#############################################################################
1032/** A function that tests the methods in the CoinMpsIO class. The
1033 only reason for it not to be a member method is that this way it doesn't
1034 have to be compiled into the library. And that's a gain, because the
1035 library should be compiled with optimization on, but this method should be
1036 compiled with debugging. Also, if this method is compiled with
1037 optimization, the compilation takes 10-15 minutes and the machine pages
1038 (has 256M core memory!)... */
1039void
1040CoinMpsIOUnitTest(const std::string & mpsDir);
1041// Function to return number in most efficient way
1042// section is 0 for columns, 1 for rhs,ranges and 2 for bounds
1043/* formatType is
1044 0 - normal and 8 character names
1045 1 - extra accuracy
1046 2 - IEEE hex - INTEL
1047 3 - IEEE hex - not INTEL
1048*/
1049void
1050CoinConvertDouble(int section, int formatType, double value, char outputValue[24]);
1051
1052#endif
1053