00001
00002
00003 #ifndef CoinPackedMatrix_H
00004 #define CoinPackedMatrix_H
00005
00006 #include "CoinError.hpp"
00007 #ifndef CLP_NO_VECTOR
00008 #include "CoinPackedVectorBase.hpp"
00009 #include "CoinShallowPackedVector.hpp"
00010 #else
00011 #include "CoinFinite.hpp"
00012 #include "CoinFloatEqual.hpp"
00013 #endif
00014
00061 class CoinPackedMatrix {
00062 friend void CoinPackedMatrixUnitTest();
00063
00064 public:
00065
00066
00067
00071 double getExtraGap() const { return extraGap_; }
00073 double getExtraMajor() const { return extraMajor_; }
00074
00077 void reserve(const int newMaxMajorDim, const CoinBigIndex newMaxSize,
00078 bool create=false);
00080 void clear();
00081
00083 bool isColOrdered() const { return colOrdered_; }
00085 CoinBigIndex getNumElements() const { return size_; }
00087 int getNumCols() const { return colOrdered_ ? majorDim_ : minorDim_; }
00089 int getNumRows() const { return colOrdered_ ? minorDim_ : majorDim_; }
00090
00095 inline const double * getElements() const { return element_; }
00101 inline const int * getIndices() const { return index_; }
00102
00104 int getSizeVectorStarts()const { return majorDim_ > 0 ? majorDim_+1 : 0;}
00106 int getSizeVectorLengths() const { return majorDim_; }
00109 inline const CoinBigIndex * getVectorStarts() const { return start_; }
00111 inline const int * getVectorLengths() const { return length_; }
00112
00113
00116 CoinBigIndex getVectorFirst(const int i) const {
00117 if (i < 0 || i >= majorDim_)
00118 throw CoinError("bad index", "vectorFirst", "CoinPackedMatrix");
00119 return start_[i];
00120 }
00123 CoinBigIndex getVectorLast(const int i) const {
00124 if (i < 0 || i >= majorDim_)
00125 throw CoinError("bad index", "vectorLast", "CoinPackedMatrix");
00126 return start_[i] + length_[i];
00127 }
00129 inline int getVectorSize(const int i) const {
00130 if (i < 0 || i >= majorDim_)
00131 throw CoinError("bad index", "vectorSize", "CoinPackedMatrix");
00132 return length_[i];
00133 }
00134 #ifndef CLP_NO_VECTOR
00135
00136 const CoinShallowPackedVector getVector(int i) const {
00137 if (i < 0 || i >= majorDim_)
00138 throw CoinError("bad index", "vector", "CoinPackedMatrix");
00139 return CoinShallowPackedVector(length_[i],
00140 index_ + start_[i],
00141 element_ + start_[i],
00142 false);
00143 }
00144 #endif
00145
00155 int * getMajorIndices() const;
00157
00158
00166 void setDimensions(int numrows, int numcols);
00167
00169 void setExtraGap(const double newGap);
00171 void setExtraMajor(const double newMajor);
00172 #ifndef CLP_NO_VECTOR
00173
00177 void appendCol(const CoinPackedVectorBase& vec);
00178 #endif
00179
00183 void appendCol(const int vecsize,
00184 const int *vecind, const double *vecelem);
00185 #ifndef CLP_NO_VECTOR
00186
00191 void appendCols(const int numcols,
00192 const CoinPackedVectorBase * const * cols);
00193 #endif
00194
00197 int appendCols(const int numcols,
00198 const CoinBigIndex * columnStarts, const int * row,
00199 const double * element, int numberRows=-1);
00200 #ifndef CLP_NO_VECTOR
00201
00205 void appendRow(const CoinPackedVectorBase& vec);
00206 #endif
00207
00211 void appendRow(const int vecsize,
00212 const int *vecind, const double *vecelem);
00213 #ifndef CLP_NO_VECTOR
00214
00219 void appendRows(const int numrows,
00220 const CoinPackedVectorBase * const * rows);
00221 #endif
00222
00225 int appendRows(const int numrows,
00226 const CoinBigIndex * rowStarts, const int * column,
00227 const double * element, int numberColumns=-1);
00228
00233 void rightAppendPackedMatrix(const CoinPackedMatrix& matrix);
00238 void bottomAppendPackedMatrix(const CoinPackedMatrix& matrix);
00239
00241 void deleteCols(const int numDel, const int * indDel);
00243 void deleteRows(const int numDel, const int * indDel);
00244
00248 void replaceVector(const int index,
00249 const int numReplace, const double * newElements);
00254 void modifyCoefficient(int row, int column, double newElement,
00255 bool keepZero=false);
00259 double getCoefficient(int row, int column) const;
00260
00266 int compress(double threshold);
00271 int eliminateDuplicates(double threshold);
00273 void orderMatrix();
00275
00276
00281 void removeGaps(double removeValue=-1.0);
00282
00286 void submatrixOf(const CoinPackedMatrix& matrix,
00287 const int numMajor, const int * indMajor);
00291 void submatrixOfWithDuplicates(const CoinPackedMatrix& matrix,
00292 const int numMajor, const int * indMajor);
00293 #if 0
00294
00297 void submatrixOf(const CoinPackedMatrix& matrix,
00298 const int numMajor, const int * indMajor,
00299 const int numMinor, const int * indMinor);
00300 #endif
00301
00304 void copyOf(const CoinPackedMatrix& rhs);
00308 void copyOf(const bool colordered,
00309 const int minor, const int major, const CoinBigIndex numels,
00310 const double * elem, const int * ind,
00311 const CoinBigIndex * start, const int * len,
00312 const double extraMajor=0.0, const double extraGap=0.0);
00316 void reverseOrderedCopyOf(const CoinPackedMatrix& rhs);
00325 void assignMatrix(const bool colordered,
00326 const int minor, const int major,
00327 const CoinBigIndex numels,
00328 double *& elem, int *& ind,
00329 CoinBigIndex *& start, int *& len,
00330 const int maxmajor = -1, const CoinBigIndex maxsize = -1);
00331
00332
00333
00336 CoinPackedMatrix & operator=(const CoinPackedMatrix& rhs);
00337
00339 void reverseOrdering();
00346 void transpose();
00347
00349 void swap(CoinPackedMatrix& matrix);
00350
00352
00353
00359 void times(const double * x, double * y) const;
00360 #ifndef CLP_NO_VECTOR
00361
00363 void times(const CoinPackedVectorBase& x, double * y) const;
00364 #endif
00365
00368 void transposeTimes(const double * x, double * y) const;
00369 #ifndef CLP_NO_VECTOR
00370
00372 void transposeTimes(const CoinPackedVectorBase& x, double * y) const;
00373 #endif
00374
00375
00376
00384
00385
00392 int * countOrthoLength() const;
00395 int getMajorDim() const { return majorDim_; }
00398 int getMinorDim() const { return minorDim_; }
00402 int getMaxMajorDim() const { return maxMajorDim_; }
00403
00406 void dumpMatrix(const char* fname = NULL) const;
00407
00409 void printMatrixElement(const int row_val, const int col_val) const;
00411
00412
00419 #ifndef CLP_NO_VECTOR
00420
00421 void appendMajorVector(const CoinPackedVectorBase& vec);
00422 #endif
00423
00424 void appendMajorVector(const int vecsize, const int *vecind,
00425 const double *vecelem);
00426 #ifndef CLP_NO_VECTOR
00427
00428 void appendMajorVectors(const int numvecs,
00429 const CoinPackedVectorBase * const * vecs);
00430
00432 void appendMinorVector(const CoinPackedVectorBase& vec);
00433 #endif
00434
00435 void appendMinorVector(const int vecsize, const int *vecind,
00436 const double *vecelem);
00437 #ifndef CLP_NO_VECTOR
00438
00439 void appendMinorVectors(const int numvecs,
00440 const CoinPackedVectorBase * const * vecs);
00441 #endif
00442
00443
00444
00457 void majorAppendSameOrdered(const CoinPackedMatrix& matrix);
00462 void minorAppendSameOrdered(const CoinPackedMatrix& matrix);
00468 void majorAppendOrthoOrdered(const CoinPackedMatrix& matrix);
00474 void minorAppendOrthoOrdered(const CoinPackedMatrix& matrix);
00476
00477
00482 void deleteMajorVectors(const int numDel, const int * indDel);
00485 void deleteMinorVectors(const int numDel, const int * indDel);
00487
00488
00495 void timesMajor(const double * x, double * y) const;
00496 #ifndef CLP_NO_VECTOR
00497
00500 void timesMajor(const CoinPackedVectorBase& x, double * y) const;
00501 #endif
00502
00506 void timesMinor(const double * x, double * y) const;
00507 #ifndef CLP_NO_VECTOR
00508
00511 void timesMinor(const CoinPackedVectorBase& x, double * y) const;
00512 #endif
00513
00514
00515
00516
00519 #ifndef CLP_NO_VECTOR
00520
00525 template <class FloatEqual> bool
00526 isEquivalent(const CoinPackedMatrix& rhs, const FloatEqual& eq) const
00527 {
00528
00529 if ((isColOrdered() ^ rhs.isColOrdered()) ||
00530 (getNumCols() != rhs.getNumCols()) ||
00531 (getNumRows() != rhs.getNumRows()) ||
00532 (getNumElements() != rhs.getNumElements()))
00533 return false;
00534
00535 for (int i=getMajorDim()-1; i >= 0; --i) {
00536 CoinShallowPackedVector pv = getVector(i);
00537 CoinShallowPackedVector rhsPv = rhs.getVector(i);
00538 if ( !pv.isEquivalent(rhsPv,eq) )
00539 return false;
00540 }
00541 return true;
00542 }
00543
00544 bool isEquivalent2(const CoinPackedMatrix& rhs) const;
00545 #else
00546
00551 bool isEquivalent(const CoinPackedMatrix& rhs, const CoinRelFltEq & eq) const;
00552 #endif
00554 bool isEquivalent(const CoinPackedMatrix& rhs) const
00555 {
00556 return isEquivalent(rhs, CoinRelFltEq());
00557 }
00559
00560
00568 inline double * getMutableElements() const { return element_; }
00574 inline int * getMutableIndices() const { return index_; }
00575
00578 inline CoinBigIndex * getMutableVectorStarts() const { return start_; }
00580 inline int * getMutableVectorLengths() const { return length_; }
00582 inline void nullElementArray() {element_=NULL;};
00584 inline void nullStartArray() {start_=NULL;};
00586 inline void nullLengthArray() {length_=NULL;};
00588 inline void nullIndexArray() {index_=NULL;};
00590
00591
00594
00595 CoinPackedMatrix();
00596
00598 CoinPackedMatrix(const bool colordered,
00599 const double extraMajor, const double extraGap);
00600
00601 CoinPackedMatrix(const bool colordered,
00602 const int minor, const int major, const CoinBigIndex numels,
00603 const double * elem, const int * ind,
00604 const CoinBigIndex * start, const int * len,
00605 const double extraMajor, const double extraGap);
00606
00607 CoinPackedMatrix(const bool colordered,
00608 const int minor, const int major, const CoinBigIndex numels,
00609 const double * elem, const int * ind,
00610 const CoinBigIndex * start, const int * len);
00611
00622 CoinPackedMatrix(const bool colordered,
00623 const int * rowIndices,
00624 const int * colIndices,
00625 const double * elements,
00626 CoinBigIndex numels );
00627
00629 CoinPackedMatrix(const CoinPackedMatrix& m);
00630
00633 CoinPackedMatrix (const CoinPackedMatrix & wholeModel,
00634 int numberRows, const int * whichRows,
00635 int numberColumns, const int * whichColumns);
00636
00638 virtual ~CoinPackedMatrix();
00640
00641
00642 protected:
00643 void gutsOfDestructor();
00644 void gutsOfCopyOf(const bool colordered,
00645 const int minor, const int major, const CoinBigIndex numels,
00646 const double * elem, const int * ind,
00647 const CoinBigIndex * start, const int * len,
00648 const double extraMajor=0.0, const double extraGap=0.0);
00650 void gutsOfCopyOfNoGaps(const bool colordered,
00651 const int minor, const int major,
00652 const double * elem, const int * ind,
00653 const CoinBigIndex * start);
00654 void gutsOfOpEqual(const bool colordered,
00655 const int minor, const int major, const CoinBigIndex numels,
00656 const double * elem, const int * ind,
00657 const CoinBigIndex * start, const int * len);
00658 void resizeForAddingMajorVectors(const int numVec, const int * lengthVec);
00659 void resizeForAddingMinorVectors(const int * addedEntries);
00664 int appendMajor(const int number,
00665 const CoinBigIndex * starts, const int * index,
00666 const double * element, int numberOther=-1);
00671 int appendMinor(const int number,
00672 const CoinBigIndex * starts, const int * index,
00673 const double * element, int numberOther=-1);
00674 private:
00675 inline CoinBigIndex getLastStart() const {
00676 return majorDim_ == 0 ? 0 : start_[majorDim_];
00677 }
00678
00679
00680 protected:
00685 bool colOrdered_;
00690 double extraGap_;
00694 double extraMajor_;
00695
00698 double *element_;
00701 int *index_;
00703 CoinBigIndex *start_;
00705 int *length_;
00706
00708 int majorDim_;
00710 int minorDim_;
00712 CoinBigIndex size_;
00713
00715 int maxMajorDim_;
00717 CoinBigIndex maxSize_;
00719 };
00720
00721
00727 void
00728 CoinPackedMatrixUnitTest();
00729
00730 #endif