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();
00281 int cleanMatrix(double threshold=1.0e-20);
00283
00284
00289 void removeGaps(double removeValue=-1.0);
00290
00294 void submatrixOf(const CoinPackedMatrix& matrix,
00295 const int numMajor, const int * indMajor);
00299 void submatrixOfWithDuplicates(const CoinPackedMatrix& matrix,
00300 const int numMajor, const int * indMajor);
00301 #if 0
00302
00305 void submatrixOf(const CoinPackedMatrix& matrix,
00306 const int numMajor, const int * indMajor,
00307 const int numMinor, const int * indMinor);
00308 #endif
00309
00312 void copyOf(const CoinPackedMatrix& rhs);
00316 void copyOf(const bool colordered,
00317 const int minor, const int major, const CoinBigIndex numels,
00318 const double * elem, const int * ind,
00319 const CoinBigIndex * start, const int * len,
00320 const double extraMajor=0.0, const double extraGap=0.0);
00324 void copyReuseArrays(const CoinPackedMatrix& rhs);
00328 void reverseOrderedCopyOf(const CoinPackedMatrix& rhs);
00337 void assignMatrix(const bool colordered,
00338 const int minor, const int major,
00339 const CoinBigIndex numels,
00340 double *& elem, int *& ind,
00341 CoinBigIndex *& start, int *& len,
00342 const int maxmajor = -1, const CoinBigIndex maxsize = -1);
00343
00344
00345
00348 CoinPackedMatrix & operator=(const CoinPackedMatrix& rhs);
00349
00351 void reverseOrdering();
00358 void transpose();
00359
00361 void swap(CoinPackedMatrix& matrix);
00362
00364
00365
00371 void times(const double * x, double * y) const;
00372 #ifndef CLP_NO_VECTOR
00373
00375 void times(const CoinPackedVectorBase& x, double * y) const;
00376 #endif
00377
00380 void transposeTimes(const double * x, double * y) const;
00381 #ifndef CLP_NO_VECTOR
00382
00384 void transposeTimes(const CoinPackedVectorBase& x, double * y) const;
00385 #endif
00386
00387
00388
00396
00397
00404 int * countOrthoLength() const;
00407 void countOrthoLength(int * counts) const;
00410 int getMajorDim() const { return majorDim_; }
00413 int getMinorDim() const { return minorDim_; }
00417 int getMaxMajorDim() const { return maxMajorDim_; }
00418
00421 void dumpMatrix(const char* fname = NULL) const;
00422
00424 void printMatrixElement(const int row_val, const int col_val) const;
00426
00427
00434 #ifndef CLP_NO_VECTOR
00435
00436 void appendMajorVector(const CoinPackedVectorBase& vec);
00437 #endif
00438
00439 void appendMajorVector(const int vecsize, const int *vecind,
00440 const double *vecelem);
00441 #ifndef CLP_NO_VECTOR
00442
00443 void appendMajorVectors(const int numvecs,
00444 const CoinPackedVectorBase * const * vecs);
00445
00447 void appendMinorVector(const CoinPackedVectorBase& vec);
00448 #endif
00449
00450 void appendMinorVector(const int vecsize, const int *vecind,
00451 const double *vecelem);
00452 #ifndef CLP_NO_VECTOR
00453
00454 void appendMinorVectors(const int numvecs,
00455 const CoinPackedVectorBase * const * vecs);
00456 #endif
00457
00458
00459
00472 void majorAppendSameOrdered(const CoinPackedMatrix& matrix);
00477 void minorAppendSameOrdered(const CoinPackedMatrix& matrix);
00483 void majorAppendOrthoOrdered(const CoinPackedMatrix& matrix);
00489 void minorAppendOrthoOrdered(const CoinPackedMatrix& matrix);
00491
00492
00497 void deleteMajorVectors(const int numDel, const int * indDel);
00500 void deleteMinorVectors(const int numDel, const int * indDel);
00502
00503
00510 void timesMajor(const double * x, double * y) const;
00511 #ifndef CLP_NO_VECTOR
00512
00515 void timesMajor(const CoinPackedVectorBase& x, double * y) const;
00516 #endif
00517
00521 void timesMinor(const double * x, double * y) const;
00522 #ifndef CLP_NO_VECTOR
00523
00526 void timesMinor(const CoinPackedVectorBase& x, double * y) const;
00527 #endif
00528
00529
00530
00531
00534 #ifndef CLP_NO_VECTOR
00535
00540 template <class FloatEqual> bool
00541 isEquivalent(const CoinPackedMatrix& rhs, const FloatEqual& eq) const
00542 {
00543
00544 if ((isColOrdered() ^ rhs.isColOrdered()) ||
00545 (getNumCols() != rhs.getNumCols()) ||
00546 (getNumRows() != rhs.getNumRows()) ||
00547 (getNumElements() != rhs.getNumElements()))
00548 return false;
00549
00550 for (int i=getMajorDim()-1; i >= 0; --i) {
00551 CoinShallowPackedVector pv = getVector(i);
00552 CoinShallowPackedVector rhsPv = rhs.getVector(i);
00553 if ( !pv.isEquivalent(rhsPv,eq) )
00554 return false;
00555 }
00556 return true;
00557 }
00558
00559 bool isEquivalent2(const CoinPackedMatrix& rhs) const;
00560 #else
00561
00566 bool isEquivalent(const CoinPackedMatrix& rhs, const CoinRelFltEq & eq) const;
00567 #endif
00569 bool isEquivalent(const CoinPackedMatrix& rhs) const
00570 {
00571 return isEquivalent(rhs, CoinRelFltEq());
00572 }
00574
00575
00583 inline double * getMutableElements() const { return element_; }
00589 inline int * getMutableIndices() const { return index_; }
00590
00593 inline CoinBigIndex * getMutableVectorStarts() const { return start_; }
00595 inline int * getMutableVectorLengths() const { return length_; }
00597 inline void setNumElements(CoinBigIndex value)
00598 { size_ = value;}
00600 inline void nullElementArray() {element_=NULL;}
00602 inline void nullStartArray() {start_=NULL;}
00604 inline void nullLengthArray() {length_=NULL;}
00606 inline void nullIndexArray() {index_=NULL;}
00608
00609
00612
00613 CoinPackedMatrix();
00614
00616 CoinPackedMatrix(const bool colordered,
00617 const double extraMajor, const double extraGap);
00618
00619 CoinPackedMatrix(const bool colordered,
00620 const int minor, const int major, const CoinBigIndex numels,
00621 const double * elem, const int * ind,
00622 const CoinBigIndex * start, const int * len,
00623 const double extraMajor, const double extraGap);
00624
00625 CoinPackedMatrix(const bool colordered,
00626 const int minor, const int major, const CoinBigIndex numels,
00627 const double * elem, const int * ind,
00628 const CoinBigIndex * start, const int * len);
00629
00640 CoinPackedMatrix(const bool colordered,
00641 const int * rowIndices,
00642 const int * colIndices,
00643 const double * elements,
00644 CoinBigIndex numels );
00645
00647 CoinPackedMatrix(const CoinPackedMatrix& m);
00648
00653 CoinPackedMatrix(const CoinPackedMatrix& m, int extraForMajor, int extraElements, bool reverseOrdering=false);
00654
00657 CoinPackedMatrix (const CoinPackedMatrix & wholeModel,
00658 int numberRows, const int * whichRows,
00659 int numberColumns, const int * whichColumns);
00660
00662 virtual ~CoinPackedMatrix();
00664
00665
00666 protected:
00667 void gutsOfDestructor();
00668 void gutsOfCopyOf(const bool colordered,
00669 const int minor, const int major, const CoinBigIndex numels,
00670 const double * elem, const int * ind,
00671 const CoinBigIndex * start, const int * len,
00672 const double extraMajor=0.0, const double extraGap=0.0);
00674 void gutsOfCopyOfNoGaps(const bool colordered,
00675 const int minor, const int major,
00676 const double * elem, const int * ind,
00677 const CoinBigIndex * start);
00678 void gutsOfOpEqual(const bool colordered,
00679 const int minor, const int major, const CoinBigIndex numels,
00680 const double * elem, const int * ind,
00681 const CoinBigIndex * start, const int * len);
00682 void resizeForAddingMajorVectors(const int numVec, const int * lengthVec);
00683 void resizeForAddingMinorVectors(const int * addedEntries);
00688 int appendMajor(const int number,
00689 const CoinBigIndex * starts, const int * index,
00690 const double * element, int numberOther=-1);
00695 int appendMinor(const int number,
00696 const CoinBigIndex * starts, const int * index,
00697 const double * element, int numberOther=-1);
00698 private:
00699 inline CoinBigIndex getLastStart() const {
00700 return majorDim_ == 0 ? 0 : start_[majorDim_];
00701 }
00702
00703
00704 protected:
00709 bool colOrdered_;
00714 double extraGap_;
00718 double extraMajor_;
00719
00722 double *element_;
00725 int *index_;
00727 CoinBigIndex *start_;
00729 int *length_;
00730
00732 int majorDim_;
00734 int minorDim_;
00736 CoinBigIndex size_;
00737
00739 int maxMajorDim_;
00741 CoinBigIndex maxSize_;
00743 };
00744
00745
00751 void
00752 CoinPackedMatrixUnitTest();
00753
00754 #endif