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