00001
00002
00003
00004
00005
00006 #ifndef CoinIndexedVector_H
00007 #define CoinIndexedVector_H
00008
00009 #if defined(_MSC_VER)
00010
00011 # pragma warning(disable:4786)
00012 #endif
00013
00014 #include <map>
00015 #include "CoinFinite.hpp"
00016 #ifndef CLP_NO_VECTOR
00017 #include "CoinPackedVectorBase.hpp"
00018 #endif
00019 #include "CoinSort.hpp"
00020 #include "CoinHelperFunctions.hpp"
00021 #include <cassert>
00022
00023 #ifndef COIN_FLOAT
00024 #define COIN_INDEXED_TINY_ELEMENT 1.0e-50
00025 #define COIN_INDEXED_REALLY_TINY_ELEMENT 1.0e-100
00026 #else
00027 #define COIN_INDEXED_TINY_ELEMENT 1.0e-35
00028 #define COIN_INDEXED_REALLY_TINY_ELEMENT 1.0e-39
00029 #endif
00030
00104 class CoinIndexedVector {
00105 friend void CoinIndexedVectorUnitTest();
00106
00107 public:
00110
00111 inline int getNumElements() const { return nElements_; }
00113 inline const int * getIndices() const { return indices_; }
00115
00117 inline int * getIndices() { return indices_; }
00121 inline double * denseVector() const { return elements_; }
00123 inline void setDenseVector(double * array)
00124 { elements_ = array;}
00126 inline void setIndexVector(int * array)
00127 { indices_ = array;}
00130 double & operator[](int i) const;
00131
00133
00134
00135
00136
00139
00140 inline void setNumElements(int value) { nElements_ = value;
00141 if (!nElements_) packedMode_=false;}
00143 void clear();
00145 void empty();
00147 CoinIndexedVector & operator=(const CoinIndexedVector &);
00148 #ifndef CLP_NO_VECTOR
00149
00151 CoinIndexedVector & operator=(const CoinPackedVectorBase & rhs);
00152 #endif
00153
00156 void copy(const CoinIndexedVector & rhs, double multiplier=1.0);
00157
00160 void borrowVector(int size, int numberIndices, int* inds, double* elems);
00161
00165 void returnVector();
00166
00171 void setVector(int numberIndices, const int * inds, const double * elems);
00172
00177 void setVector(int size, int numberIndices, const int * inds, const double * elems);
00178
00180 void setConstant(int size, const int * inds, double elems);
00181
00183 void setFull(int size, const double * elems);
00184
00188 void setElement(int index, double element);
00189
00191 void insert(int index, double element);
00193 inline void quickInsert(int index, double element)
00194 {
00195 assert (!elements_[index]);
00196 indices_[nElements_++] = index;
00197 assert (nElements_<=capacity_);
00198 elements_[index] = element;
00199 }
00202 void add(int index, double element);
00206 inline void quickAdd(int index, double element)
00207 {
00208 if (elements_[index]) {
00209 element += elements_[index];
00210 if ((element > 0 ? element : -element) >= COIN_INDEXED_TINY_ELEMENT) {
00211 elements_[index] = element;
00212 } else {
00213 elements_[index] = 1.0e-100;
00214 }
00215 } else if ((element > 0 ? element : -element) >= COIN_INDEXED_TINY_ELEMENT) {
00216 indices_[nElements_++] = index;
00217 assert (nElements_<=capacity_);
00218 elements_[index] = element;
00219 }
00220 }
00225 inline void quickAddNonZero(int index, double element)
00226 {
00227 assert (element);
00228 if (elements_[index]) {
00229 element += elements_[index];
00230 if (element) {
00231 elements_[index] = element;
00232 } else {
00233 elements_[index] = COIN_DBL_MIN;
00234 }
00235 } else {
00236 indices_[nElements_++] = index;
00237 assert (nElements_<=capacity_);
00238 elements_[index] = element;
00239 }
00240 }
00243 inline void zero(int index)
00244 {
00245 if (elements_[index])
00246 elements_[index] = COIN_DBL_MIN;
00247 }
00250 int clean(double tolerance);
00252 int cleanAndPack(double tolerance);
00254 int cleanAndPackSafe(double tolerance);
00256 inline void setPacked()
00257 { packedMode_ = true;}
00259 void checkClear();
00261 void checkClean();
00263 int scan();
00267 int scan(int start, int end);
00270 int scan(double tolerance);
00274 int scan(int start, int end, double tolerance);
00276 int scanAndPack();
00277 int scanAndPack(int start, int end);
00278 int scanAndPack(double tolerance);
00279 int scanAndPack(int start, int end, double tolerance);
00281 void createPacked(int number, const int * indices,
00282 const double * elements);
00284 void expand();
00285 #ifndef CLP_NO_VECTOR
00287 void append(const CoinPackedVectorBase & caboose);
00288 #endif
00290 void append(const CoinIndexedVector & caboose);
00291
00293 void swap(int i, int j);
00294
00296 void truncate(int newSize);
00298 void print() const;
00300
00302
00303 void operator+=(double value);
00305 void operator-=(double value);
00307 void operator*=(double value);
00309 void operator/=(double value);
00311
00314 #ifndef CLP_NO_VECTOR
00315
00317 bool operator==(const CoinPackedVectorBase & rhs) const;
00319 bool operator!=(const CoinPackedVectorBase & rhs) const;
00320 #endif
00321
00323 bool operator==(const CoinIndexedVector & rhs) const;
00325 bool operator!=(const CoinIndexedVector & rhs) const;
00327
00330
00331 int getMaxIndex() const;
00333 int getMinIndex() const;
00335
00336
00340 void sort()
00341 { std::sort(indices_,indices_+nElements_); }
00342
00343 void sortIncrIndex()
00344 { std::sort(indices_,indices_+nElements_); }
00345
00346 void sortDecrIndex();
00347
00348 void sortIncrElement();
00349
00350 void sortDecrElement();
00351
00353
00354
00355
00367
00368 CoinIndexedVector operator+(
00369 const CoinIndexedVector& op2);
00370
00372 CoinIndexedVector operator-(
00373 const CoinIndexedVector& op2);
00374
00376 CoinIndexedVector operator*(
00377 const CoinIndexedVector& op2);
00378
00380 CoinIndexedVector operator/(
00381 const CoinIndexedVector& op2);
00383 void operator+=(const CoinIndexedVector& op2);
00384
00386 void operator-=( const CoinIndexedVector& op2);
00387
00389 void operator*=(const CoinIndexedVector& op2);
00390
00392 void operator/=(const CoinIndexedVector& op2);
00394
00401 void reserve(int n);
00405 int capacity() const { return capacity_; }
00407 inline void setPackedMode(bool yesNo)
00408 { packedMode_=yesNo;}
00410 inline bool packedMode() const
00411 { return packedMode_;}
00413
00417 CoinIndexedVector();
00419 CoinIndexedVector(int size, const int * inds, const double * elems);
00421 CoinIndexedVector(int size, const int * inds, double element);
00424 CoinIndexedVector(int size, const double * elements);
00426 CoinIndexedVector(int size);
00428 CoinIndexedVector(const CoinIndexedVector &);
00430 CoinIndexedVector(const CoinIndexedVector *);
00431 #ifndef CLP_NO_VECTOR
00432
00433 CoinIndexedVector(const CoinPackedVectorBase & rhs);
00434 #endif
00435
00436 ~CoinIndexedVector ();
00438
00439 private:
00442
00443 void gutsOfSetVector(int size,
00444 const int * inds, const double * elems);
00445 void gutsOfSetVector(int size, int numberIndices,
00446 const int * inds, const double * elems);
00447 void gutsOfSetPackedVector(int size, int numberIndices,
00448 const int * inds, const double * elems);
00450 void gutsOfSetConstant(int size,
00451 const int * inds, double value);
00453
00454 private:
00457
00458 int * indices_;
00460 double * elements_;
00462 int nElements_;
00464 int capacity_;
00466 int offset_;
00468 bool packedMode_;
00470 };
00471
00472
00478 void
00479 CoinIndexedVectorUnitTest();
00496 class CoinArrayWithLength {
00497
00498 public:
00501
00502 inline int getSize() const
00503 { return size_; }
00505 inline int rawSize() const
00506 { return size_; }
00508 inline bool switchedOn() const
00509 { return size_!=-1; }
00511 inline int getCapacity() const
00512 { return (size_>-2) ? size_ : (-size_)-2; }
00514 inline void setCapacity()
00515 { if (size_<=-2) size_ = (-size_)-2; }
00517 inline const char * array() const
00518 { return (size_>-2) ? array_ : NULL; }
00520
00523
00524 inline void setSize(int value)
00525 { size_ = value; }
00527 inline void switchOff()
00528 { size_ = -1; }
00530 void setPersistence(int flag,int currentLength);
00532 void clear();
00534 void swap(CoinArrayWithLength & other);
00536 void extend(int newSize);
00538
00541
00542 char * conditionalNew(long sizeWanted);
00544 void conditionalDelete();
00546
00550 inline CoinArrayWithLength()
00551 { array_=NULL; size_=-1;}
00553 inline CoinArrayWithLength(int size)
00554 { array_=new char [size]; size_=-1;}
00559 inline CoinArrayWithLength(int size, int mode)
00560 { array_ = new char [size]; if (mode) memset(array_,0,size);size_=size;}
00562 CoinArrayWithLength(const CoinArrayWithLength & rhs);
00564 CoinArrayWithLength(const CoinArrayWithLength * rhs);
00566 CoinArrayWithLength& operator=(const CoinArrayWithLength & rhs);
00568 void copy(const CoinArrayWithLength & rhs, int numberBytes=-1);
00570 void allocate(const CoinArrayWithLength & rhs, int numberBytes);
00572 inline ~CoinArrayWithLength ()
00573 { delete [] array_; }
00574
00576
00577 protected:
00580
00581 char * array_;
00583 int size_;
00585 };
00587
00588 class CoinDoubleArrayWithLength : public CoinArrayWithLength {
00589
00590 public:
00593
00594 inline int getSize() const
00595 { return size_/CoinSizeofAsInt(double); }
00597 inline double * array() const
00598 { return reinterpret_cast<double *> ((size_>-2) ? array_ : NULL); }
00600
00603
00604 inline void setSize(int value)
00605 { size_ = value*CoinSizeofAsInt(double); }
00607
00610
00611 inline double * conditionalNew(int sizeWanted)
00612 { return reinterpret_cast<double *> ( CoinArrayWithLength::conditionalNew(sizeWanted>=0 ? static_cast<long> ((sizeWanted)*CoinSizeofAsInt(double)) : -1)); }
00614
00618 inline CoinDoubleArrayWithLength()
00619 { array_=NULL; size_=-1;}
00621 inline CoinDoubleArrayWithLength(int size)
00622 { array_=new char [size*CoinSizeofAsInt(double)]; size_=-1;}
00627 inline CoinDoubleArrayWithLength(int size, int mode)
00628 : CoinArrayWithLength(size*CoinSizeofAsInt(double),mode) {}
00630 inline CoinDoubleArrayWithLength(const CoinDoubleArrayWithLength & rhs)
00631 : CoinArrayWithLength(rhs) {}
00633 inline CoinDoubleArrayWithLength(const CoinDoubleArrayWithLength * rhs)
00634 : CoinArrayWithLength(rhs) {}
00636 inline CoinDoubleArrayWithLength& operator=(const CoinDoubleArrayWithLength & rhs)
00637 { CoinArrayWithLength::operator=(rhs); return *this;}
00639 };
00641
00642 class CoinFactorizationDoubleArrayWithLength : public CoinArrayWithLength {
00643
00644 public:
00647
00648 inline int getSize() const
00649 { return size_/CoinSizeofAsInt(CoinFactorizationDouble); }
00651 inline CoinFactorizationDouble * array() const
00652 { return reinterpret_cast<CoinFactorizationDouble *> ((size_>-2) ? array_ : NULL); }
00654
00657
00658 inline void setSize(int value)
00659 { size_ = value*CoinSizeofAsInt(CoinFactorizationDouble); }
00661
00664
00665 inline CoinFactorizationDouble * conditionalNew(int sizeWanted)
00666 { return reinterpret_cast<CoinFactorizationDouble *> (CoinArrayWithLength::conditionalNew(sizeWanted>=0 ? static_cast<long> (( sizeWanted)*CoinSizeofAsInt(CoinFactorizationDouble)) : -1)); }
00668
00672 inline CoinFactorizationDoubleArrayWithLength()
00673 { array_=NULL; size_=-1;}
00675 inline CoinFactorizationDoubleArrayWithLength(int size)
00676 { array_=new char [size*CoinSizeofAsInt(CoinFactorizationDouble)]; size_=-1;}
00681 inline CoinFactorizationDoubleArrayWithLength(int size, int mode)
00682 : CoinArrayWithLength(size*CoinSizeofAsInt(CoinFactorizationDouble),mode) {}
00684 inline CoinFactorizationDoubleArrayWithLength(const CoinFactorizationDoubleArrayWithLength & rhs)
00685 : CoinArrayWithLength(rhs) {}
00687 inline CoinFactorizationDoubleArrayWithLength(const CoinFactorizationDoubleArrayWithLength * rhs)
00688 : CoinArrayWithLength(rhs) {}
00690 inline CoinFactorizationDoubleArrayWithLength& operator=(const CoinFactorizationDoubleArrayWithLength & rhs)
00691 { CoinArrayWithLength::operator=(rhs); return *this;}
00693 };
00695
00696 class CoinIntArrayWithLength : public CoinArrayWithLength {
00697
00698 public:
00701
00702 inline int getSize() const
00703 { return size_/CoinSizeofAsInt(int); }
00705 inline int * array() const
00706 { return reinterpret_cast<int *> ((size_>-2) ? array_ : NULL); }
00708
00711
00712 inline void setSize(int value)
00713 { size_ = value*CoinSizeofAsInt(int); }
00715
00718
00719 inline int * conditionalNew(int sizeWanted)
00720 { return reinterpret_cast<int *> (CoinArrayWithLength::conditionalNew(sizeWanted>=0 ? static_cast<long> (( sizeWanted)*CoinSizeofAsInt(int)) : -1)); }
00722
00726 inline CoinIntArrayWithLength()
00727 { array_=NULL; size_=-1;}
00729 inline CoinIntArrayWithLength(int size)
00730 { array_=new char [size*CoinSizeofAsInt(int)]; size_=-1;}
00735 inline CoinIntArrayWithLength(int size, int mode)
00736 : CoinArrayWithLength(size*CoinSizeofAsInt(int),mode) {}
00738 inline CoinIntArrayWithLength(const CoinIntArrayWithLength & rhs)
00739 : CoinArrayWithLength(rhs) {}
00741 inline CoinIntArrayWithLength(const CoinIntArrayWithLength * rhs)
00742 : CoinArrayWithLength(rhs) {}
00744 inline CoinIntArrayWithLength& operator=(const CoinIntArrayWithLength & rhs)
00745 { CoinArrayWithLength::operator=(rhs); return *this;}
00747 };
00749
00750 class CoinBigIndexArrayWithLength : public CoinArrayWithLength {
00751
00752 public:
00755
00756 inline int getSize() const
00757 { return size_/CoinSizeofAsInt(CoinBigIndex); }
00759 inline CoinBigIndex * array() const
00760 { return reinterpret_cast<CoinBigIndex *> ((size_>-2) ? array_ : NULL); }
00762
00765
00766 inline void setSize(int value)
00767 { size_ = value*CoinSizeofAsInt(CoinBigIndex); }
00769
00772
00773 inline CoinBigIndex * conditionalNew(int sizeWanted)
00774 { return reinterpret_cast<CoinBigIndex *> (CoinArrayWithLength::conditionalNew(sizeWanted>=0 ? static_cast<long> (( sizeWanted)*CoinSizeofAsInt(CoinBigIndex)) : -1)); }
00776
00780 inline CoinBigIndexArrayWithLength()
00781 { array_=NULL; size_=-1;}
00783 inline CoinBigIndexArrayWithLength(int size)
00784 { array_=new char [size*CoinSizeofAsInt(CoinBigIndex)]; size_=-1;}
00789 inline CoinBigIndexArrayWithLength(int size, int mode)
00790 : CoinArrayWithLength(size*CoinSizeofAsInt(CoinBigIndex),mode) {}
00792 inline CoinBigIndexArrayWithLength(const CoinBigIndexArrayWithLength & rhs)
00793 : CoinArrayWithLength(rhs) {}
00795 inline CoinBigIndexArrayWithLength(const CoinBigIndexArrayWithLength * rhs)
00796 : CoinArrayWithLength(rhs) {}
00798 inline CoinBigIndexArrayWithLength& operator=(const CoinBigIndexArrayWithLength & rhs)
00799 { CoinArrayWithLength::operator=(rhs); return *this;}
00801 };
00803
00804 class CoinUnsignedIntArrayWithLength : public CoinArrayWithLength {
00805
00806 public:
00809
00810 inline int getSize() const
00811 { return size_/CoinSizeofAsInt(unsigned int); }
00813 inline unsigned int * array() const
00814 { return reinterpret_cast<unsigned int *> ((size_>-2) ? array_ : NULL); }
00816
00819
00820 inline void setSize(int value)
00821 { size_ = value*CoinSizeofAsInt(unsigned int); }
00823
00826
00827 inline unsigned int * conditionalNew(int sizeWanted)
00828 { return reinterpret_cast<unsigned int *> (CoinArrayWithLength::conditionalNew(sizeWanted>=0 ? static_cast<long> (( sizeWanted)*CoinSizeofAsInt(unsigned int)) : -1)); }
00830
00834 inline CoinUnsignedIntArrayWithLength()
00835 { array_=NULL; size_=-1;}
00837 inline CoinUnsignedIntArrayWithLength(int size)
00838 { array_=new char [size*CoinSizeofAsInt(unsigned int)]; size_=-1;}
00843 inline CoinUnsignedIntArrayWithLength(int size, int mode)
00844 : CoinArrayWithLength(size*CoinSizeofAsInt(unsigned int),mode) {}
00846 inline CoinUnsignedIntArrayWithLength(const CoinUnsignedIntArrayWithLength & rhs)
00847 : CoinArrayWithLength(rhs) {}
00849 inline CoinUnsignedIntArrayWithLength(const CoinUnsignedIntArrayWithLength * rhs)
00850 : CoinArrayWithLength(rhs) {}
00852 inline CoinUnsignedIntArrayWithLength& operator=(const CoinUnsignedIntArrayWithLength & rhs)
00853 { CoinArrayWithLength::operator=(rhs); return *this;}
00855 };
00856 #endif