- Main Page
- Namespaces
- Classes
- Files
- Directories

- Search for |

- File List
- File Members

# CoinWarmStartVector.hpp

Go to the documentation of this file.

    00001 /* $Id: CoinWarmStartVector.hpp 1372 2011-01-03 23:31:00Z lou $ */
    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