/home/coin/SVN-release/CoinAll-1.1.0/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

Generated on Sun Nov 14 14:06:32 2010 for Coin-All by  doxygen 1.4.7