• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

/build/buildd/coinutils-2.6.4/CoinUtils/src/CoinWarmStartVector.hpp

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

Generated on Fri Oct 15 2010 18:21:02 by  doxygen 1.7.1