- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages

- File List
- File Members

# /home/coin/SVN-release/Osi-0.98.1/CoinUtils/src/CoinWarmStartVector.hpp

Go to the documentation of this file.

    00001 // Copyright (C) 2000, International Business Machines
    00002 // Corporation and others.  All Rights Reserved.
    00003
    00004 #ifndef CoinWarmStartVector_H
    00005 #define CoinWarmStartVector_H
    00006
    00007 #if defined(_MSC_VER)
    00008 // Turn off compiler warning about long names
    00009 #  pragma warning(disable:4786)
    00010 #endif
    00011
    00012 #include <cassert>
    00013 #include <cmath>
    00014
    00015 #include "CoinHelperFunctions.hpp"
    00016 #include "CoinWarmStart.hpp"
    00017
    00018
    00019 //#############################################################################
    00020
    00023 template <typename T>
    00024 class CoinWarmStartVector : public virtual CoinWarmStart
    00025 {
    00026 protected:
    00027   inline void gutsOfDestructor() {
    00028     delete[] values_;
    00029   }
    00030   inline void gutsOfCopy(const CoinWarmStartVector<T>& rhs) {
    00031     size_  = rhs.size_;
    00032     values_ = new T[size_];
    00033     CoinDisjointCopyN(rhs.values_, size_, values_);
    00034   }
    00035
    00036 public:
    00038   int size() const { return size_; }
    00040   const T* values() const { return values_; }
    00041
    00045   void assignVector(int size, T*& vec) {
    00046     size_ = size;
    00047     delete[] values_;
    00048     values_ = vec;
    00049     vec = NULL;
    00050   }
    00051
    00052   CoinWarmStartVector() : size_(0), values_(NULL) {}
    00053
    00054   CoinWarmStartVector(int size, const T* vec) :
    00055     size_(size), values_(new T[size]) {
    00056     CoinDisjointCopyN(vec, size, values_);
    00057   }
    00058
    00059   CoinWarmStartVector(const CoinWarmStartVector& rhs) {
    00060     gutsOfCopy(rhs);
    00061   }
    00062
    00063   CoinWarmStartVector& operator=(const CoinWarmStartVector& rhs) {
    00064     if (this != &rhs) {
    00065       gutsOfDestructor();
    00066       gutsOfCopy(rhs);
    00067     }
    00068     return *this;
    00069   }
    00070
    00071   inline void swap(CoinWarmStartVector& rhs) {
    00072     if (this != &rhs) {
    00073       std::swap(size_, rhs.size_);
    00074       std::swap(values_, rhs.values_);
    00075     }
    00076   }
    00077
    00079   virtual CoinWarmStart *clone() const {
    00080     return new CoinWarmStartVector(*this);
    00081   }
    00082
    00083   virtual ~CoinWarmStartVector() {
    00084     gutsOfDestructor();
    00085   }
    00086
    00092   inline void clear() {
    00093     size_ = 0;
    00094     delete[] values_;
    00095     values_ = NULL;
    00096   }
    00097
    00100
    00108   virtual CoinWarmStartDiff*
    00109   generateDiff (const CoinWarmStart *const oldCWS) const ;
    00110
    00117   virtual void applyDiff (const CoinWarmStartDiff *const cwsdDiff) ;
    00118
    00120
    00121 private:
    00123
    00124
    00125   int size_;
    00127   T* values_;
    00129 };
    00130
    00131 //=============================================================================
    00132
    00148 template <typename T>
    00149 class CoinWarmStartVectorDiff : public virtual CoinWarmStartDiff
    00150 {
    00151   friend CoinWarmStartDiff*
    00152   CoinWarmStartVector<T>::generateDiff(const CoinWarmStart *const oldCWS) const;
    00153   friend void
    00154   CoinWarmStartVector<T>::applyDiff(const CoinWarmStartDiff *const diff) ;
    00155
    00156 public:
    00157
    00159   virtual CoinWarmStartDiff * clone() const {
    00160     return new CoinWarmStartVectorDiff(*this) ;
    00161   }
    00162
    00164   virtual CoinWarmStartVectorDiff &
    00165   operator= (const CoinWarmStartVectorDiff<T>& rhs) ;
    00166
    00168   virtual ~CoinWarmStartVectorDiff() {
    00169     delete[] diffNdxs_ ;
    00170     delete[] diffVals_ ;
    00171   }
    00172
    00173   inline void swap(CoinWarmStartVectorDiff& rhs) {
    00174     if (this != &rhs) {
    00175       std::swap(sze_, rhs.sze_);
    00176       std::swap(diffNdxs_, rhs.diffNdxs_);
    00177       std::swap(diffVals_, rhs.diffVals_);
    00178     }
    00179   }
    00180
    00183   CoinWarmStartVectorDiff () : sze_(0), diffNdxs_(0), diffVals_(NULL) {}
    00184
    00191   CoinWarmStartVectorDiff(const CoinWarmStartVectorDiff<T>& rhs) ;
    00192
    00194   CoinWarmStartVectorDiff(int sze, const unsigned int* const diffNdxs,
    00195                           const T* const diffVals) ;
    00196
    00202   inline void clear() {
    00203     sze_ = 0;
    00204     delete[] diffNdxs_;  diffNdxs_ = NULL;
    00205     delete[] diffVals_;  diffVals_ = NULL;
    00206   }
    00207
    00208 private:
    00209
    00213   int sze_ ;
    00214
    00217   unsigned int* diffNdxs_ ;
    00218
    00221   T* diffVals_ ;
    00222 };
    00223
    00224 //##############################################################################
    00225
    00226 template <typename T, typename U>
    00227 class CoinWarmStartVectorPair : public virtual CoinWarmStart
    00228 {
    00229 private:
    00230   CoinWarmStartVector<T> t_;
    00231   CoinWarmStartVector<U> u_;
    00232
    00233 public:
    00234   inline int size0() const { return t_.size(); }
    00235   inline int size1() const { return u_.size(); }
    00236   inline const T* values0() const { return t_.values(); }
    00237   inline const U* values1() const { return u_.values(); }
    00238
    00239   inline void assignVector0(int size, T*& vec) { t_.assignVector(size, vec); }
    00240   inline void assignVector1(int size, U*& vec) { u_.assignVector(size, vec); }
    00241
    00242   CoinWarmStartVectorPair() {}
    00243   CoinWarmStartVectorPair(int s0, const T* v0, int s1, const U* v1) :
    00244     t_(s0, v0), u_(s1, v1) {}
    00245
    00246   CoinWarmStartVectorPair(const CoinWarmStartVectorPair<T,U>& rhs) :
    00247     t_(rhs.t_), u_(rhs.u_) {}
    00248   CoinWarmStartVectorPair& operator=(const CoinWarmStartVectorPair<T,U>& rhs) {
    00249     if (this != &rhs) {
    00250       t_ = rhs.t_;
    00251       u_ = rhs.u_;
    00252     }
    00253   }
    00254
    00255   inline void swap(CoinWarmStartVectorPair<T,U>& rhs) {
    00256     t_.swap(rhs.t_);
    00257     u_.swap(rhs.u_);
    00258   }
    00259
    00260   virtual CoinWarmStart *clone() const {
    00261     return new CoinWarmStartVectorPair(*this);
    00262   }
    00263
    00264   virtual ~CoinWarmStartVectorPair() {}
    00265
    00266   inline void clear() {
    00267     t_.clear();
    00268     u_.clear();
    00269   }
    00270
    00271   virtual CoinWarmStartDiff*
    00272   generateDiff (const CoinWarmStart *const oldCWS) const ;
    00273
    00274   virtual void applyDiff (const CoinWarmStartDiff *const cwsdDiff) ;
    00275 };
    00276
    00277 //=============================================================================
    00278
    00279 template <typename T, typename U>
    00280 class CoinWarmStartVectorPairDiff : public virtual CoinWarmStartDiff
    00281 {
    00282   friend CoinWarmStartDiff*
    00283   CoinWarmStartVectorPair<T,U>::generateDiff(const CoinWarmStart *const oldCWS) const;
    00284   friend void
    00285   CoinWarmStartVectorPair<T,U>::applyDiff(const CoinWarmStartDiff *const diff) ;
    00286
    00287 private:
    00288   CoinWarmStartVectorDiff<T> tdiff_;
    00289   CoinWarmStartVectorDiff<U> udiff_;
    00290
    00291 public:
    00292   CoinWarmStartVectorPairDiff() {}
    00293   CoinWarmStartVectorPairDiff(const CoinWarmStartVectorPairDiff<T,U>& rhs) :
    00294     tdiff_(rhs.tdiff_), udiff_(rhs.udiff_) {}
    00295   ~CoinWarmStartVectorPairDiff() {}
    00296
    00297   virtual CoinWarmStartVectorPairDiff&
    00298   operator=(const CoinWarmStartVectorPairDiff<T,U>& rhs) {
    00299     tdiff_ = rhs.tdiff_;
    00300     udiff_ = rhs.udiff_;
    00301   }
    00302
    00303   virtual CoinWarmStartDiff * clone() const {
    00304     return new CoinWarmStartVectorPairDiff(*this) ;
    00305   }
    00306
    00307   inline void swap(CoinWarmStartVectorPairDiff<T,U>& rhs) {
    00308     tdiff_.swap(rhs.tdiff_);
    00309     udiff_.swap(rhs.udiff_);
    00310   }
    00311
    00312   inline void clear() {
    00313     tdiff_.clear();
    00314     udiff_.clear();
    00315   }
    00316 };
    00317
    00318 //##############################################################################
    00319 //#############################################################################
    00320
    00321 /*
    00322   Generate a `diff' that can convert the warm start passed as a parameter to
    00323   the warm start specified by this.
    00324
    00325   The capabilities are limited: the basis passed as a parameter can be no
    00326   larger than the basis pointed to by this.
    00327 */
    00328
    00329 template <typename T> CoinWarmStartDiff*
    00330 CoinWarmStartVector<T>::generateDiff(const CoinWarmStart *const oldCWS) const
    00331 {
    00332 /*
    00333   Make sure the parameter is CoinWarmStartVector or derived class.
    00334 */
    00335   const CoinWarmStartVector<T>* oldVector =
    00336     dynamic_cast<const CoinWarmStartVector<T>*>(oldCWS);
    00337   if (!oldVector)
    00338     { throw CoinError("Old warm start not derived from CoinWarmStartVector.",
    00339                       "generateDiff","CoinWarmStartVector") ; }
    00340   const CoinWarmStartVector<T>* newVector = this ;
    00341   /*
    00342     Make sure newVector is equal or bigger than oldVector. Calculate the worst
    00343     case number of diffs and allocate vectors to hold them.
    00344   */
    00345   const int oldCnt = oldVector->size() ;
    00346   const int newCnt = newVector->size() ;
    00347
    00348   assert(newCnt >= oldCnt) ;
    00349
    00350   unsigned int *diffNdx = new unsigned int [newCnt];
    00351   T* diffVal = new T[newCnt];
    00352   /*
    00353     Scan the vector vectors.  For the portion of the vectors which overlap,
    00354     create diffs. Then add any additional entries from newVector.
    00355   */
    00356   const T*oldVal = oldVector->values() ;
    00357   const T*newVal = newVector->values() ;
    00358   int numberChanged = 0 ;
    00359   int i ;
    00360   for (i = 0 ; i < oldCnt ; i++) {
    00361     if (oldVal[i] != newVal[i]) {
    00362       diffNdx[numberChanged] = i ;
    00363       diffVal[numberChanged++] = newVal[i] ;
    00364     }
    00365   }
    00366   for ( ; i < newCnt ; i++) {
    00367     diffNdx[numberChanged] = i ;
    00368     diffVal[numberChanged++] = newVal[i] ;
    00369   }
    00370   /*
    00371     Create the object of our desire.
    00372   */
    00373   CoinWarmStartVectorDiff<T> *diff =
    00374     new CoinWarmStartVectorDiff<T>(numberChanged,diffNdx,diffVal) ;
    00375   /*
    00376     Clean up and return.
    00377   */
    00378   delete[] diffNdx ;
    00379   delete[] diffVal ;
    00380
    00381   return diff;
    00382   //  return (dynamic_cast<CoinWarmStartDiff<T>*>(diff)) ;
    00383 }
    00384
    00385
    00386 /*
    00387   Apply diff to this warm start.
    00388
    00389   Update this warm start by applying diff. It's assumed that the
    00390   allocated capacity of the warm start is sufficiently large.
    00391 */
    00392
    00393 template <typename T> void
    00394 CoinWarmStartVector<T>::applyDiff (const CoinWarmStartDiff *const cwsdDiff)
    00395 {
    00396   /*
    00397     Make sure we have a CoinWarmStartVectorDiff
    00398   */
    00399   const CoinWarmStartVectorDiff<T>* diff =
    00400     dynamic_cast<const CoinWarmStartVectorDiff<T>*>(cwsdDiff) ;
    00401   if (!diff) {
    00402     throw CoinError("Diff not derived from CoinWarmStartVectorDiff.",
    00403                     "applyDiff","CoinWarmStartVector") ;
    00404   }
    00405   /*
    00406     Application is by straighforward replacement of words in the vector vector.
    00407   */
    00408   const int numberChanges = diff->sze_ ;
    00409   const unsigned int *diffNdxs = diff->diffNdxs_ ;
    00410   const T* diffVals = diff->diffVals_ ;
    00411   T* vals = this->values_ ;
    00412
    00413   for (int i = 0 ; i < numberChanges ; i++) {
    00414     unsigned int diffNdx = diffNdxs[i] ;
    00415     T diffVal = diffVals[i] ;
    00416     vals[diffNdx] = diffVal ;
    00417   }
    00418 }
    00419
    00420 //#############################################################################
    00421
    00422
    00423 // Assignment
    00424
    00425 template <typename T> CoinWarmStartVectorDiff<T>&
    00426 CoinWarmStartVectorDiff<T>::operator=(const CoinWarmStartVectorDiff<T> &rhs)
    00427 {
    00428   if (this != &rhs) {
    00429     if (sze_ > 0) {
    00430       delete[] diffNdxs_ ;
    00431       delete[] diffVals_ ;
    00432     }
    00433     sze_ = rhs.sze_ ;
    00434     if (sze_ > 0) {
    00435       diffNdxs_ = new unsigned int[sze_] ;
    00436       memcpy(diffNdxs_,rhs.diffNdxs_,sze_*sizeof(unsigned int)) ;
    00437       diffVals_ = new T[sze_] ;
    00438       memcpy(diffVals_,rhs.diffVals_,sze_*sizeof(T)) ;
    00439     } else {
    00440       diffNdxs_ = 0 ;
    00441       diffVals_ = 0 ;
    00442     }
    00443   }
    00444
    00445   return (*this) ;
    00446 }
    00447
    00448
    00449 // Copy constructor
    00450
    00451 template <typename T>
    00452 CoinWarmStartVectorDiff<T>::CoinWarmStartVectorDiff(const CoinWarmStartVectorDiff<T> &rhs)
    00453   : sze_(rhs.sze_),
    00454     diffNdxs_(0),
    00455     diffVals_(0)
    00456 {
    00457   if (sze_ > 0) {
    00458     diffNdxs_ = new unsigned int[sze_] ;
    00459     memcpy(diffNdxs_,rhs.diffNdxs_,sze_*sizeof(unsigned int)) ;
    00460     diffVals_ = new T[sze_] ;
    00461     memcpy(diffVals_,rhs.diffVals_,sze_*sizeof(T)) ;
    00462   }
    00463 }
    00464
    00466
    00467 template <typename T>
    00468 CoinWarmStartVectorDiff<T>::CoinWarmStartVectorDiff
    00469 (int sze, const unsigned int *const diffNdxs, const T *const diffVals)
    00470   : sze_(sze),
    00471     diffNdxs_(0),
    00472     diffVals_(0)
    00473 {
    00474   if (sze > 0) {
    00475     diffNdxs_ = new unsigned int[sze] ;
    00476     memcpy(diffNdxs_,diffNdxs,sze*sizeof(unsigned int)) ;
    00477     diffVals_ = new T[sze] ;
    00478     memcpy(diffVals_,diffVals,sze*sizeof(T)) ;
    00479   }
    00480 }
    00481
    00482 #endif