CoinUtils trunk
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   }
00256 
00257   inline void swap(CoinWarmStartVectorPair<T,U>& rhs) {
00258     t_.swap(rhs.t_);
00259     u_.swap(rhs.u_);
00260   }
00261 
00262   virtual CoinWarmStart *clone() const {
00263     return new CoinWarmStartVectorPair(*this);
00264   }
00265 
00266   virtual ~CoinWarmStartVectorPair() {}
00267 
00268   inline void clear() {
00269     t_.clear();
00270     u_.clear();
00271   }
00272 
00273   virtual CoinWarmStartDiff*
00274   generateDiff (const CoinWarmStart *const oldCWS) const ;
00275 
00276   virtual void applyDiff (const CoinWarmStartDiff *const cwsdDiff) ;
00277 };
00278 
00279 //=============================================================================
00280 
00281 template <typename T, typename U>
00282 class CoinWarmStartVectorPairDiff : public virtual CoinWarmStartDiff
00283 {
00284   friend CoinWarmStartDiff*
00285   CoinWarmStartVectorPair<T,U>::generateDiff(const CoinWarmStart *const oldCWS) const;
00286   friend void
00287   CoinWarmStartVectorPair<T,U>::applyDiff(const CoinWarmStartDiff *const diff) ;
00288 
00289 private:
00290   CoinWarmStartVectorDiff<T> tdiff_;
00291   CoinWarmStartVectorDiff<U> udiff_;
00292 
00293 public:
00294   CoinWarmStartVectorPairDiff() {}
00295   CoinWarmStartVectorPairDiff(const CoinWarmStartVectorPairDiff<T,U>& rhs) :
00296     tdiff_(rhs.tdiff_), udiff_(rhs.udiff_) {}
00297   ~CoinWarmStartVectorPairDiff() {}
00298 
00299   virtual CoinWarmStartVectorPairDiff&
00300   operator=(const CoinWarmStartVectorPairDiff<T,U>& rhs) {
00301     tdiff_ = rhs.tdiff_;
00302     udiff_ = rhs.udiff_;
00303   }
00304 
00305   virtual CoinWarmStartDiff * clone() const {
00306     return new CoinWarmStartVectorPairDiff(*this) ;
00307   }
00308 
00309   inline void swap(CoinWarmStartVectorPairDiff<T,U>& rhs) {
00310     tdiff_.swap(rhs.tdiff_);
00311     udiff_.swap(rhs.udiff_);
00312   }
00313 
00314   inline void clear() {
00315     tdiff_.clear();
00316     udiff_.clear();
00317   }
00318 };
00319 
00320 //##############################################################################
00321 //#############################################################################
00322 
00323 /*
00324   Generate a `diff' that can convert the warm start passed as a parameter to
00325   the warm start specified by this.
00326 
00327   The capabilities are limited: the basis passed as a parameter can be no
00328   larger than the basis pointed to by this.
00329 */
00330 
00331 template <typename T> CoinWarmStartDiff*
00332 CoinWarmStartVector<T>::generateDiff(const CoinWarmStart *const oldCWS) const
00333 { 
00334 /*
00335   Make sure the parameter is CoinWarmStartVector or derived class.
00336 */
00337   const CoinWarmStartVector<T>* oldVector =
00338     dynamic_cast<const CoinWarmStartVector<T>*>(oldCWS);
00339   if (!oldVector)
00340     { throw CoinError("Old warm start not derived from CoinWarmStartVector.",
00341                       "generateDiff","CoinWarmStartVector") ; }
00342   const CoinWarmStartVector<T>* newVector = this ;
00343   /*
00344     Make sure newVector is equal or bigger than oldVector. Calculate the worst
00345     case number of diffs and allocate vectors to hold them.
00346   */
00347   const int oldCnt = oldVector->size() ;
00348   const int newCnt = newVector->size() ;
00349 
00350   assert(newCnt >= oldCnt) ;
00351 
00352   unsigned int *diffNdx = new unsigned int [newCnt]; 
00353   T* diffVal = new T[newCnt]; 
00354   /*
00355     Scan the vector vectors.  For the portion of the vectors which overlap,
00356     create diffs. Then add any additional entries from newVector.
00357   */
00358   const T*oldVal = oldVector->values() ;
00359   const T*newVal = newVector->values() ;
00360   int numberChanged = 0 ;
00361   int i ;
00362   for (i = 0 ; i < oldCnt ; i++) {
00363     if (oldVal[i] != newVal[i]) {
00364       diffNdx[numberChanged] = i ;
00365       diffVal[numberChanged++] = newVal[i] ;
00366     }
00367   }
00368   for ( ; i < newCnt ; i++) {
00369     diffNdx[numberChanged] = i ;
00370     diffVal[numberChanged++] = newVal[i] ;
00371   }
00372   /*
00373     Create the object of our desire.
00374   */
00375   CoinWarmStartVectorDiff<T> *diff =
00376     new CoinWarmStartVectorDiff<T>(numberChanged,diffNdx,diffVal) ;
00377   /*
00378     Clean up and return.
00379   */
00380   delete[] diffNdx ;
00381   delete[] diffVal ;
00382 
00383   return diff;
00384   //  return (dynamic_cast<CoinWarmStartDiff<T>*>(diff)) ;
00385 }
00386 
00387 
00388 /*
00389   Apply diff to this warm start.
00390   
00391   Update this warm start by applying diff. It's assumed that the
00392   allocated capacity of the warm start is sufficiently large.
00393 */
00394 
00395 template <typename T> void
00396 CoinWarmStartVector<T>::applyDiff (const CoinWarmStartDiff *const cwsdDiff)
00397 {
00398   /*
00399     Make sure we have a CoinWarmStartVectorDiff
00400   */
00401   const CoinWarmStartVectorDiff<T>* diff =
00402     dynamic_cast<const CoinWarmStartVectorDiff<T>*>(cwsdDiff) ;
00403   if (!diff) {
00404     throw CoinError("Diff not derived from CoinWarmStartVectorDiff.",
00405                     "applyDiff","CoinWarmStartVector") ;
00406   }
00407   /*
00408     Application is by straighforward replacement of words in the vector vector.
00409   */
00410   const int numberChanges = diff->sze_ ;
00411   const unsigned int *diffNdxs = diff->diffNdxs_ ;
00412   const T* diffVals = diff->diffVals_ ;
00413   T* vals = this->values_ ;
00414 
00415   for (int i = 0 ; i < numberChanges ; i++) {
00416     unsigned int diffNdx = diffNdxs[i] ;
00417     T diffVal = diffVals[i] ;
00418     vals[diffNdx] = diffVal ;
00419   }
00420 }
00421 
00422 //#############################################################################
00423 
00424 
00425 // Assignment
00426 
00427 template <typename T> CoinWarmStartVectorDiff<T>&
00428 CoinWarmStartVectorDiff<T>::operator=(const CoinWarmStartVectorDiff<T> &rhs)
00429 {
00430   if (this != &rhs) {
00431     if (sze_ > 0) {
00432       delete[] diffNdxs_ ;
00433       delete[] diffVals_ ;
00434     }
00435     sze_ = rhs.sze_ ;
00436     if (sze_ > 0) {
00437       diffNdxs_ = new unsigned int[sze_] ;
00438       memcpy(diffNdxs_,rhs.diffNdxs_,sze_*sizeof(unsigned int)) ;
00439       diffVals_ = new T[sze_] ;
00440       memcpy(diffVals_,rhs.diffVals_,sze_*sizeof(T)) ;
00441     } else {
00442       diffNdxs_ = 0 ;
00443       diffVals_ = 0 ;
00444     }
00445   }
00446 
00447   return (*this) ;
00448 }
00449 
00450 
00451 // Copy constructor
00452 
00453 template <typename T>
00454 CoinWarmStartVectorDiff<T>::CoinWarmStartVectorDiff(const CoinWarmStartVectorDiff<T> &rhs)
00455   : sze_(rhs.sze_),
00456     diffNdxs_(0),
00457     diffVals_(0)
00458 {
00459   if (sze_ > 0) {
00460     diffNdxs_ = new unsigned int[sze_] ;
00461     memcpy(diffNdxs_,rhs.diffNdxs_,sze_*sizeof(unsigned int)) ;
00462     diffVals_ = new T[sze_] ;
00463     memcpy(diffVals_,rhs.diffVals_,sze_*sizeof(T)) ;
00464   }
00465 }
00466 
00468 
00469 template <typename T>
00470 CoinWarmStartVectorDiff<T>::CoinWarmStartVectorDiff
00471 (int sze, const unsigned int *const diffNdxs, const T *const diffVals)
00472   : sze_(sze),
00473     diffNdxs_(0),
00474     diffVals_(0)
00475 {
00476   if (sze > 0) {
00477     diffNdxs_ = new unsigned int[sze] ;
00478     memcpy(diffNdxs_,diffNdxs,sze*sizeof(unsigned int)) ;
00479     diffVals_ = new T[sze] ;
00480     memcpy(diffVals_,diffVals,sze*sizeof(T)) ;
00481   }
00482 }
00483 
00484 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines