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

- File List
- File Members

# /home/coin/SVN-release/Cgl-0.55.0/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