00001
00002
00003
00004 #ifndef CoinPackedMatrix_H
00005 #define CoinPackedMatrix_H
00006
00007 #include "CoinError.hpp"
00008 #ifndef CLP_NO_VECTOR
00009 #include "CoinPackedVectorBase.hpp"
00010 #include "CoinShallowPackedVector.hpp"
00011 #else
00012 #include "CoinFinite.hpp"
00013 #include "CoinFloatEqual.hpp"
00014 #endif
00015
00075 class CoinPackedMatrix {
00076 friend void CoinPackedMatrixUnitTest();
00077
00078 public:
00079
00080
00081
00085 inline double getExtraGap() const { return extraGap_; }
00087 inline double getExtraMajor() const { return extraMajor_; }
00088
00091 void reserve(const int newMaxMajorDim, const CoinBigIndex newMaxSize,
00092 bool create=false);
00094 void clear();
00095
00097 inline bool isColOrdered() const { return colOrdered_; }
00099 inline bool hasGaps() const
00100 { return size_<start_[majorDim_];}
00101
00103 inline CoinBigIndex getNumElements() const { return size_; }
00105 inline int getNumCols() const { return colOrdered_ ? majorDim_ : minorDim_; }
00107 inline int getNumRows() const { return colOrdered_ ? minorDim_ : majorDim_; }
00108
00113 inline const double * getElements() const { return element_; }
00119 inline const int * getIndices() const { return index_; }
00120
00122 inline int getSizeVectorStarts()const { return majorDim_ > 0 ? majorDim_+1 : 0;}
00124 inline int getSizeVectorLengths() const { return majorDim_; }
00127 inline const CoinBigIndex * getVectorStarts() const { return start_; }
00129 inline const int * getVectorLengths() const { return length_; }
00130
00131
00134 CoinBigIndex getVectorFirst(const int i) const {
00135 #ifndef COIN_FAST_CODE
00136 if (i < 0 || i >= majorDim_)
00137 throw CoinError("bad index", "vectorFirst", "CoinPackedMatrix");
00138 #endif
00139 return start_[i];
00140 }
00143 CoinBigIndex getVectorLast(const int i) const {
00144 #ifndef COIN_FAST_CODE
00145 if (i < 0 || i >= majorDim_)
00146 throw CoinError("bad index", "vectorLast", "CoinPackedMatrix");
00147 #endif
00148 return start_[i] + length_[i];
00149 }
00151 inline int getVectorSize(const int i) const {
00152 #ifndef COIN_FAST_CODE
00153 if (i < 0 || i >= majorDim_)
00154 throw CoinError("bad index", "vectorSize", "CoinPackedMatrix");
00155 #endif
00156 return length_[i];
00157 }
00158 #ifndef CLP_NO_VECTOR
00159
00160 const CoinShallowPackedVector getVector(int i) const {
00161 #ifndef COIN_FAST_CODE
00162 if (i < 0 || i >= majorDim_)
00163 throw CoinError("bad index", "vector", "CoinPackedMatrix");
00164 #endif
00165 return CoinShallowPackedVector(length_[i],
00166 index_ + start_[i],
00167 element_ + start_[i],
00168 false);
00169 }
00170 #endif
00171
00181 int * getMajorIndices() const;
00183
00184
00195 void setDimensions(int numrows, int numcols);
00196
00198 void setExtraGap(const double newGap);
00200 void setExtraMajor(const double newMajor);
00201 #ifndef CLP_NO_VECTOR
00202
00208 void appendCol(const CoinPackedVectorBase& vec);
00209 #endif
00210
00216 void appendCol(const int vecsize,
00217 const int *vecind, const double *vecelem);
00218 #ifndef CLP_NO_VECTOR
00219
00225 void appendCols(const int numcols,
00226 const CoinPackedVectorBase * const * cols);
00227 #endif
00228
00233 int appendCols(const int numcols,
00234 const CoinBigIndex * columnStarts, const int * row,
00235 const double * element, int numberRows=-1);
00236 #ifndef CLP_NO_VECTOR
00237
00243 void appendRow(const CoinPackedVectorBase& vec);
00244 #endif
00245
00251 void appendRow(const int vecsize,
00252 const int *vecind, const double *vecelem);
00253 #ifndef CLP_NO_VECTOR
00254
00260 void appendRows(const int numrows,
00261 const CoinPackedVectorBase * const * rows);
00262 #endif
00263
00268 int appendRows(const int numrows,
00269 const CoinBigIndex * rowStarts, const int * column,
00270 const double * element, int numberColumns=-1);
00271
00276 void rightAppendPackedMatrix(const CoinPackedMatrix& matrix);
00281 void bottomAppendPackedMatrix(const CoinPackedMatrix& matrix);
00282
00284 void deleteCols(const int numDel, const int * indDel);
00286 void deleteRows(const int numDel, const int * indDel);
00287
00291 void replaceVector(const int index,
00292 const int numReplace, const double * newElements);
00297 void modifyCoefficient(int row, int column, double newElement,
00298 bool keepZero=false);
00302 double getCoefficient(int row, int column) const;
00303
00309 int compress(double threshold);
00314 int eliminateDuplicates(double threshold);
00316 void orderMatrix();
00324 int cleanMatrix(double threshold=1.0e-20);
00326
00327
00332 void removeGaps(double removeValue=-1.0);
00333
00337 void submatrixOf(const CoinPackedMatrix& matrix,
00338 const int numMajor, const int * indMajor);
00342 void submatrixOfWithDuplicates(const CoinPackedMatrix& matrix,
00343 const int numMajor, const int * indMajor);
00344 #if 0
00345
00348 void submatrixOf(const CoinPackedMatrix& matrix,
00349 const int numMajor, const int * indMajor,
00350 const int numMinor, const int * indMinor);
00351 #endif
00352
00355 void copyOf(const CoinPackedMatrix& rhs);
00359 void copyOf(const bool colordered,
00360 const int minor, const int major, const CoinBigIndex numels,
00361 const double * elem, const int * ind,
00362 const CoinBigIndex * start, const int * len,
00363 const double extraMajor=0.0, const double extraGap=0.0);
00367 void copyReuseArrays(const CoinPackedMatrix& rhs);
00368
00376 void reverseOrderedCopyOf(const CoinPackedMatrix& rhs);
00377
00386 void assignMatrix(const bool colordered,
00387 const int minor, const int major,
00388 const CoinBigIndex numels,
00389 double *& elem, int *& ind,
00390 CoinBigIndex *& start, int *& len,
00391 const int maxmajor = -1, const CoinBigIndex maxsize = -1);
00392
00393
00394
00397 CoinPackedMatrix & operator=(const CoinPackedMatrix& rhs);
00398
00405 void reverseOrdering();
00406
00416 void transpose();
00417
00419 void swap(CoinPackedMatrix& matrix);
00420
00422
00423
00429 void times(const double * x, double * y) const;
00430 #ifndef CLP_NO_VECTOR
00431
00433 void times(const CoinPackedVectorBase& x, double * y) const;
00434 #endif
00435
00438 void transposeTimes(const double * x, double * y) const;
00439 #ifndef CLP_NO_VECTOR
00440
00442 void transposeTimes(const CoinPackedVectorBase& x, double * y) const;
00443 #endif
00444
00445
00446
00454
00455
00462 int * countOrthoLength() const;
00465 void countOrthoLength(int * counts) const;
00468 int getMajorDim() const { return majorDim_; }
00471 int getMinorDim() const { return minorDim_; }
00475 int getMaxMajorDim() const { return maxMajorDim_; }
00476
00479 void dumpMatrix(const char* fname = NULL) const;
00480
00482 void printMatrixElement(const int row_val, const int col_val) const;
00484
00485
00494 #ifndef CLP_NO_VECTOR
00495
00496 void appendMajorVector(const CoinPackedVectorBase& vec);
00497 #endif
00498
00499 void appendMajorVector(const int vecsize, const int *vecind,
00500 const double *vecelem);
00501 #ifndef CLP_NO_VECTOR
00502
00503 void appendMajorVectors(const int numvecs,
00504 const CoinPackedVectorBase * const * vecs);
00505
00507 void appendMinorVector(const CoinPackedVectorBase& vec);
00508 #endif
00509
00510 void appendMinorVector(const int vecsize, const int *vecind,
00511 const double *vecelem);
00512 #ifndef CLP_NO_VECTOR
00513
00514 void appendMinorVectors(const int numvecs,
00515 const CoinPackedVectorBase * const * vecs);
00516 #endif
00517
00529 void appendMinorFast(const int number,
00530 const CoinBigIndex * starts, const int * index,
00531 const double * element);
00533
00534
00547 void majorAppendSameOrdered(const CoinPackedMatrix& matrix);
00552 void minorAppendSameOrdered(const CoinPackedMatrix& matrix);
00558 void majorAppendOrthoOrdered(const CoinPackedMatrix& matrix);
00564 void minorAppendOrthoOrdered(const CoinPackedMatrix& matrix);
00566
00567
00572 void deleteMajorVectors(const int numDel, const int * indDel);
00575 void deleteMinorVectors(const int numDel, const int * indDel);
00577
00578
00585 void timesMajor(const double * x, double * y) const;
00586 #ifndef CLP_NO_VECTOR
00587
00590 void timesMajor(const CoinPackedVectorBase& x, double * y) const;
00591 #endif
00592
00596 void timesMinor(const double * x, double * y) const;
00597 #ifndef CLP_NO_VECTOR
00598
00601 void timesMinor(const CoinPackedVectorBase& x, double * y) const;
00602 #endif
00603
00604
00605
00606
00609 #ifndef CLP_NO_VECTOR
00610
00617 template <class FloatEqual> bool
00618 isEquivalent(const CoinPackedMatrix& rhs, const FloatEqual& eq) const
00619 {
00620
00621 if ((isColOrdered() ^ rhs.isColOrdered()) ||
00622 (getNumCols() != rhs.getNumCols()) ||
00623 (getNumRows() != rhs.getNumRows()) ||
00624 (getNumElements() != rhs.getNumElements()))
00625 return false;
00626
00627 for (int i=getMajorDim()-1; i >= 0; --i) {
00628 CoinShallowPackedVector pv = getVector(i);
00629 CoinShallowPackedVector rhsPv = rhs.getVector(i);
00630 if ( !pv.isEquivalent(rhsPv,eq) )
00631 return false;
00632 }
00633 return true;
00634 }
00635
00642 bool isEquivalent2(const CoinPackedMatrix& rhs) const;
00643 #else
00644
00652 bool isEquivalent(const CoinPackedMatrix& rhs, const CoinRelFltEq & eq) const;
00653 #endif
00654
00658 bool isEquivalent(const CoinPackedMatrix& rhs) const
00659 {
00660 return isEquivalent(rhs,CoinRelFltEq());
00661 }
00663
00664
00672 inline double * getMutableElements() const { return element_; }
00678 inline int * getMutableIndices() const { return index_; }
00679
00682 inline CoinBigIndex * getMutableVectorStarts() const { return start_; }
00684 inline int * getMutableVectorLengths() const { return length_; }
00686 inline void setNumElements(CoinBigIndex value)
00687 { size_ = value;}
00689 inline void nullElementArray() {element_=NULL;}
00691 inline void nullStartArray() {start_=NULL;}
00693 inline void nullLengthArray() {length_=NULL;}
00695 inline void nullIndexArray() {index_=NULL;}
00697
00698
00701
00702 CoinPackedMatrix();
00703
00705 CoinPackedMatrix(const bool colordered,
00706 const double extraMajor, const double extraGap);
00707
00708 CoinPackedMatrix(const bool colordered,
00709 const int minor, const int major, const CoinBigIndex numels,
00710 const double * elem, const int * ind,
00711 const CoinBigIndex * start, const int * len,
00712 const double extraMajor, const double extraGap);
00713
00714 CoinPackedMatrix(const bool colordered,
00715 const int minor, const int major, const CoinBigIndex numels,
00716 const double * elem, const int * ind,
00717 const CoinBigIndex * start, const int * len);
00718
00729 CoinPackedMatrix(const bool colordered,
00730 const int * rowIndices,
00731 const int * colIndices,
00732 const double * elements,
00733 CoinBigIndex numels );
00734
00736 CoinPackedMatrix(const CoinPackedMatrix& m);
00737
00742 CoinPackedMatrix(const CoinPackedMatrix& m, int extraForMajor, int extraElements, bool reverseOrdering=false);
00743
00746 CoinPackedMatrix (const CoinPackedMatrix & wholeModel,
00747 int numberRows, const int * whichRows,
00748 int numberColumns, const int * whichColumns);
00749
00751 virtual ~CoinPackedMatrix();
00753
00754
00755 protected:
00756 void gutsOfDestructor();
00757 void gutsOfCopyOf(const bool colordered,
00758 const int minor, const int major, const CoinBigIndex numels,
00759 const double * elem, const int * ind,
00760 const CoinBigIndex * start, const int * len,
00761 const double extraMajor=0.0, const double extraGap=0.0);
00763 void gutsOfCopyOfNoGaps(const bool colordered,
00764 const int minor, const int major,
00765 const double * elem, const int * ind,
00766 const CoinBigIndex * start);
00767 void gutsOfOpEqual(const bool colordered,
00768 const int minor, const int major, const CoinBigIndex numels,
00769 const double * elem, const int * ind,
00770 const CoinBigIndex * start, const int * len);
00771 void resizeForAddingMajorVectors(const int numVec, const int * lengthVec);
00772 void resizeForAddingMinorVectors(const int * addedEntries);
00773
00783 int appendMajor(const int number,
00784 const CoinBigIndex * starts, const int * index,
00785 const double * element, int numberOther=-1);
00795 int appendMinor(const int number,
00796 const CoinBigIndex * starts, const int * index,
00797 const double * element, int numberOther=-1);
00798
00799 private:
00800 inline CoinBigIndex getLastStart() const {
00801 return majorDim_ == 0 ? 0 : start_[majorDim_];
00802 }
00803
00804
00805 protected:
00810 bool colOrdered_;
00815 double extraGap_;
00819 double extraMajor_;
00820
00823 double *element_;
00826 int *index_;
00828 CoinBigIndex *start_;
00830 int *length_;
00831
00833 int majorDim_;
00835 int minorDim_;
00837 CoinBigIndex size_;
00838
00840 int maxMajorDim_;
00842 CoinBigIndex maxSize_;
00844 };
00845
00846
00852 void
00853 CoinPackedMatrixUnitTest();
00854
00855 #endif