CoinUtils trunk
|
00001 /* $Id$ */ 00002 // Copyright (C) 2000, International Business Machines 00003 // Corporation and others. All Rights Reserved. 00004 // This code is licensed under the terms of the Eclipse Public License (EPL). 00005 00006 #ifndef CoinPackedMatrix_H 00007 #define CoinPackedMatrix_H 00008 00009 #include "CoinError.hpp" 00010 #include "CoinTypes.hpp" 00011 #ifndef CLP_NO_VECTOR 00012 #include "CoinPackedVectorBase.hpp" 00013 #include "CoinShallowPackedVector.hpp" 00014 #else 00015 class CoinRelFltEq; 00016 #endif 00017 00079 class CoinPackedMatrix { 00080 friend void CoinPackedMatrixUnitTest(); 00081 00082 public: 00083 00084 00085 //--------------------------------------------------------------------------- 00089 inline double getExtraGap() const { return extraGap_; } 00091 inline double getExtraMajor() const { return extraMajor_; } 00092 00095 void reserve(const int newMaxMajorDim, const CoinBigIndex newMaxSize, 00096 bool create=false); 00098 void clear(); 00099 00101 inline bool isColOrdered() const { return colOrdered_; } 00102 00104 inline bool hasGaps() const { return (size_<start_[majorDim_]) ; } 00105 00107 inline CoinBigIndex getNumElements() const { return size_; } 00108 00110 inline int getNumCols() const 00111 { return colOrdered_ ? majorDim_ : minorDim_; } 00112 00114 inline int getNumRows() const 00115 { return colOrdered_ ? minorDim_ : majorDim_; } 00116 00124 inline const double * getElements() const { return element_; } 00125 00134 inline const int * getIndices() const { return index_; } 00135 00140 inline int getSizeVectorStarts() const 00141 { return ((majorDim_ > 0)?(majorDim_+1):(0)) ; } 00142 00147 inline int getSizeVectorLengths() const { return majorDim_; } 00148 00154 inline const CoinBigIndex * getVectorStarts() const { return start_; } 00155 00160 inline const int * getVectorLengths() const { return length_; } 00161 00164 CoinBigIndex getVectorFirst(const int i) const { 00165 #ifndef COIN_FAST_CODE 00166 if (i < 0 || i >= majorDim_) 00167 throw CoinError("bad index", "vectorFirst", "CoinPackedMatrix"); 00168 #endif 00169 return start_[i]; 00170 } 00173 CoinBigIndex getVectorLast(const int i) const { 00174 #ifndef COIN_FAST_CODE 00175 if (i < 0 || i >= majorDim_) 00176 throw CoinError("bad index", "vectorLast", "CoinPackedMatrix"); 00177 #endif 00178 return start_[i] + length_[i]; 00179 } 00181 inline int getVectorSize(const int i) const { 00182 #ifndef COIN_FAST_CODE 00183 if (i < 0 || i >= majorDim_) 00184 throw CoinError("bad index", "vectorSize", "CoinPackedMatrix"); 00185 #endif 00186 return length_[i]; 00187 } 00188 #ifndef CLP_NO_VECTOR 00189 00190 const CoinShallowPackedVector getVector(int i) const { 00191 #ifndef COIN_FAST_CODE 00192 if (i < 0 || i >= majorDim_) 00193 throw CoinError("bad index", "vector", "CoinPackedMatrix"); 00194 #endif 00195 return CoinShallowPackedVector(length_[i], 00196 index_ + start_[i], 00197 element_ + start_[i], 00198 false); 00199 } 00200 #endif 00201 00211 int * getMajorIndices() const; 00213 00214 //--------------------------------------------------------------------------- 00225 void setDimensions(int numrows, int numcols); 00226 00228 void setExtraGap(const double newGap); 00230 void setExtraMajor(const double newMajor); 00231 #ifndef CLP_NO_VECTOR 00232 00238 void appendCol(const CoinPackedVectorBase& vec); 00239 #endif 00240 00246 void appendCol(const int vecsize, 00247 const int *vecind, const double *vecelem); 00248 #ifndef CLP_NO_VECTOR 00249 00255 void appendCols(const int numcols, 00256 const CoinPackedVectorBase * const * cols); 00257 #endif 00258 00263 int appendCols(const int numcols, 00264 const CoinBigIndex * columnStarts, const int * row, 00265 const double * element, int numberRows=-1); 00266 #ifndef CLP_NO_VECTOR 00267 00273 void appendRow(const CoinPackedVectorBase& vec); 00274 #endif 00275 00281 void appendRow(const int vecsize, 00282 const int *vecind, const double *vecelem); 00283 #ifndef CLP_NO_VECTOR 00284 00290 void appendRows(const int numrows, 00291 const CoinPackedVectorBase * const * rows); 00292 #endif 00293 00298 int appendRows(const int numrows, 00299 const CoinBigIndex * rowStarts, const int * column, 00300 const double * element, int numberColumns=-1); 00301 00306 void rightAppendPackedMatrix(const CoinPackedMatrix& matrix); 00311 void bottomAppendPackedMatrix(const CoinPackedMatrix& matrix); 00312 00314 void deleteCols(const int numDel, const int * indDel); 00316 void deleteRows(const int numDel, const int * indDel); 00317 00321 void replaceVector(const int index, 00322 const int numReplace, const double * newElements); 00327 void modifyCoefficient(int row, int column, double newElement, 00328 bool keepZero=false); 00332 double getCoefficient(int row, int column) const; 00333 00339 int compress(double threshold); 00344 int eliminateDuplicates(double threshold); 00346 void orderMatrix(); 00354 int cleanMatrix(double threshold=1.0e-20); 00356 00357 //--------------------------------------------------------------------------- 00362 void removeGaps(double removeValue=-1.0); 00363 00367 void submatrixOf(const CoinPackedMatrix& matrix, 00368 const int numMajor, const int * indMajor); 00372 void submatrixOfWithDuplicates(const CoinPackedMatrix& matrix, 00373 const int numMajor, const int * indMajor); 00374 #if 0 00375 00378 void submatrixOf(const CoinPackedMatrix& matrix, 00379 const int numMajor, const int * indMajor, 00380 const int numMinor, const int * indMinor); 00381 #endif 00382 00385 void copyOf(const CoinPackedMatrix& rhs); 00389 void copyOf(const bool colordered, 00390 const int minor, const int major, const CoinBigIndex numels, 00391 const double * elem, const int * ind, 00392 const CoinBigIndex * start, const int * len, 00393 const double extraMajor=0.0, const double extraGap=0.0); 00397 void copyReuseArrays(const CoinPackedMatrix& rhs); 00398 00406 void reverseOrderedCopyOf(const CoinPackedMatrix& rhs); 00407 00416 void assignMatrix(const bool colordered, 00417 const int minor, const int major, 00418 const CoinBigIndex numels, 00419 double *& elem, int *& ind, 00420 CoinBigIndex *& start, int *& len, 00421 const int maxmajor = -1, const CoinBigIndex maxsize = -1); 00422 00423 00424 00427 CoinPackedMatrix & operator=(const CoinPackedMatrix& rhs); 00428 00435 void reverseOrdering(); 00436 00446 void transpose(); 00447 00449 void swap(CoinPackedMatrix& matrix); 00450 00452 00453 //--------------------------------------------------------------------------- 00459 void times(const double * x, double * y) const; 00460 #ifndef CLP_NO_VECTOR 00461 00463 void times(const CoinPackedVectorBase& x, double * y) const; 00464 #endif 00465 00468 void transposeTimes(const double * x, double * y) const; 00469 #ifndef CLP_NO_VECTOR 00470 00472 void transposeTimes(const CoinPackedVectorBase& x, double * y) const; 00473 #endif 00474 00475 00476 //--------------------------------------------------------------------------- 00484 00485 //------------------------------------------------------------------------- 00492 int * countOrthoLength() const; 00495 void countOrthoLength(int * counts) const; 00498 int getMajorDim() const { return majorDim_; } 00501 int getMinorDim() const { return minorDim_; } 00505 int getMaxMajorDim() const { return maxMajorDim_; } 00506 00509 void dumpMatrix(const char* fname = NULL) const; 00510 00512 void printMatrixElement(const int row_val, const int col_val) const; 00514 00515 //------------------------------------------------------------------------- 00525 #ifndef CLP_NO_VECTOR 00526 00527 void appendMajorVector(const CoinPackedVectorBase& vec); 00528 #endif 00529 00530 void appendMajorVector(const int vecsize, const int *vecind, 00531 const double *vecelem); 00532 #ifndef CLP_NO_VECTOR 00533 00534 void appendMajorVectors(const int numvecs, 00535 const CoinPackedVectorBase * const * vecs); 00536 00538 void appendMinorVector(const CoinPackedVectorBase& vec); 00539 #endif 00540 00541 void appendMinorVector(const int vecsize, const int *vecind, 00542 const double *vecelem); 00543 #ifndef CLP_NO_VECTOR 00544 00545 void appendMinorVectors(const int numvecs, 00546 const CoinPackedVectorBase * const * vecs); 00547 #endif 00548 00560 void appendMinorFast(const int number, 00561 const CoinBigIndex * starts, const int * index, 00562 const double * element); 00564 00565 //------------------------------------------------------------------------- 00579 void majorAppendSameOrdered(const CoinPackedMatrix& matrix); 00584 void minorAppendSameOrdered(const CoinPackedMatrix& matrix); 00590 void majorAppendOrthoOrdered(const CoinPackedMatrix& matrix); 00596 void minorAppendOrthoOrdered(const CoinPackedMatrix& matrix); 00598 00599 //----------------------------------------------------------------------- 00604 void deleteMajorVectors(const int numDel, const int * indDel); 00607 void deleteMinorVectors(const int numDel, const int * indDel); 00609 00610 //----------------------------------------------------------------------- 00617 void timesMajor(const double * x, double * y) const; 00618 #ifndef CLP_NO_VECTOR 00619 00622 void timesMajor(const CoinPackedVectorBase& x, double * y) const; 00623 #endif 00624 00628 void timesMinor(const double * x, double * y) const; 00629 #ifndef CLP_NO_VECTOR 00630 00633 void timesMinor(const CoinPackedVectorBase& x, double * y) const; 00634 #endif 00635 00636 00637 00638 //-------------------------------------------------------------------------- 00641 #ifndef CLP_NO_VECTOR 00642 00649 template <class FloatEqual> bool 00650 isEquivalent(const CoinPackedMatrix& rhs, const FloatEqual& eq) const 00651 { 00652 // Both must be column order or both row ordered and must be of same size 00653 if ((isColOrdered() ^ rhs.isColOrdered()) || 00654 (getNumCols() != rhs.getNumCols()) || 00655 (getNumRows() != rhs.getNumRows()) || 00656 (getNumElements() != rhs.getNumElements())) 00657 return false; 00658 00659 for (int i=getMajorDim()-1; i >= 0; --i) { 00660 CoinShallowPackedVector pv = getVector(i); 00661 CoinShallowPackedVector rhsPv = rhs.getVector(i); 00662 if ( !pv.isEquivalent(rhsPv,eq) ) 00663 return false; 00664 } 00665 return true; 00666 } 00667 00674 bool isEquivalent2(const CoinPackedMatrix& rhs) const; 00675 #else 00676 00684 bool isEquivalent(const CoinPackedMatrix& rhs, const CoinRelFltEq & eq) const; 00685 #endif 00686 00690 bool isEquivalent(const CoinPackedMatrix& rhs) const; 00692 00693 //-------------------------------------------------------------------------- 00703 inline double * getMutableElements() const { return element_; } 00709 inline int * getMutableIndices() const { return index_; } 00710 00713 inline CoinBigIndex * getMutableVectorStarts() const { return start_; } 00715 inline int * getMutableVectorLengths() const { return length_; } 00717 inline void setNumElements(CoinBigIndex value) 00718 { size_ = value;} 00723 inline void nullElementArray() {element_=NULL;} 00724 00729 inline void nullStartArray() {start_=NULL;} 00730 00735 inline void nullLengthArray() {length_=NULL;} 00736 00741 inline void nullIndexArray() {index_=NULL;} 00743 00744 //-------------------------------------------------------------------------- 00747 00748 CoinPackedMatrix(); 00749 00751 CoinPackedMatrix(const bool colordered, 00752 const double extraMajor, const double extraGap); 00753 00754 CoinPackedMatrix(const bool colordered, 00755 const int minor, const int major, const CoinBigIndex numels, 00756 const double * elem, const int * ind, 00757 const CoinBigIndex * start, const int * len, 00758 const double extraMajor, const double extraGap); 00759 00760 CoinPackedMatrix(const bool colordered, 00761 const int minor, const int major, const CoinBigIndex numels, 00762 const double * elem, const int * ind, 00763 const CoinBigIndex * start, const int * len); 00764 00775 CoinPackedMatrix(const bool colordered, 00776 const int * rowIndices, 00777 const int * colIndices, 00778 const double * elements, 00779 CoinBigIndex numels ); 00780 00782 CoinPackedMatrix(const CoinPackedMatrix& m); 00783 00788 CoinPackedMatrix(const CoinPackedMatrix& m, int extraForMajor, int extraElements, bool reverseOrdering=false); 00789 00792 CoinPackedMatrix (const CoinPackedMatrix & wholeModel, 00793 int numberRows, const int * whichRows, 00794 int numberColumns, const int * whichColumns); 00795 00797 virtual ~CoinPackedMatrix(); 00799 00823 int verifyMtx(int verbosity = 1, bool zeroesAreError = false) const ; 00825 00826 //-------------------------------------------------------------------------- 00827 protected: 00828 void gutsOfDestructor(); 00829 void gutsOfCopyOf(const bool colordered, 00830 const int minor, const int major, const CoinBigIndex numels, 00831 const double * elem, const int * ind, 00832 const CoinBigIndex * start, const int * len, 00833 const double extraMajor=0.0, const double extraGap=0.0); 00835 void gutsOfCopyOfNoGaps(const bool colordered, 00836 const int minor, const int major, 00837 const double * elem, const int * ind, 00838 const CoinBigIndex * start); 00839 void gutsOfOpEqual(const bool colordered, 00840 const int minor, const int major, const CoinBigIndex numels, 00841 const double * elem, const int * ind, 00842 const CoinBigIndex * start, const int * len); 00843 void resizeForAddingMajorVectors(const int numVec, const int * lengthVec); 00844 void resizeForAddingMinorVectors(const int * addedEntries); 00845 00855 int appendMajor(const int number, 00856 const CoinBigIndex * starts, const int * index, 00857 const double * element, int numberOther=-1); 00867 int appendMinor(const int number, 00868 const CoinBigIndex * starts, const int * index, 00869 const double * element, int numberOther=-1); 00870 00871 private: 00872 inline CoinBigIndex getLastStart() const { 00873 return majorDim_ == 0 ? 0 : start_[majorDim_]; 00874 } 00875 00876 //-------------------------------------------------------------------------- 00877 protected: 00882 bool colOrdered_; 00887 double extraGap_; 00891 double extraMajor_; 00892 00895 double *element_; 00898 int *index_; 00900 CoinBigIndex *start_; 00902 int *length_; 00903 00905 int majorDim_; 00907 int minorDim_; 00909 CoinBigIndex size_; 00910 00912 int maxMajorDim_; 00914 CoinBigIndex maxSize_; 00916 }; 00917 00918 //############################################################################# 00926 void 00927 CoinPackedMatrixUnitTest(); 00928 00929 #endif