# CoinWarmStartVector.hpp

Go to the documentation of this file.

    00001 /* $Id: CoinWarmStartVector.hpp 1498 2011-11-02 15:25:35Z mjs $ */
    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