00001
00002
00003
00004 #ifndef CoinWarmStartVector_H
00005 #define CoinWarmStartVector_H
00006
00007 #if defined(_MSC_VER)
00008
00009 # pragma warning(disable:4786)
00010 #endif
00011
00012 #include <cassert>
00013 #include <cmath>
00014
00015 #include "CoinHelperFunctions.hpp"
00016 #include "CoinWarmStart.hpp"
00017
00018
00019
00020
00023 template <typename T>
00024 class CoinWarmStartVector : public virtual CoinWarmStart
00025 {
00026 protected:
00027 inline void gutsOfDestructor() {
00028 delete[] values_;
00029 }
00030 inline void gutsOfCopy(const CoinWarmStartVector<T>& rhs) {
00031 size_ = rhs.size_;
00032 values_ = new T[size_];
00033 CoinDisjointCopyN(rhs.values_, size_, values_);
00034 }
00035
00036 public:
00038 int size() const { return size_; }
00040 const T* values() const { return values_; }
00041
00045 void assignVector(int size, T*& vec) {
00046 size_ = size;
00047 delete[] values_;
00048 values_ = vec;
00049 vec = NULL;
00050 }
00051
00052 CoinWarmStartVector() : size_(0), values_(NULL) {}
00053
00054 CoinWarmStartVector(int size, const T* vec) :
00055 size_(size), values_(new T[size]) {
00056 CoinDisjointCopyN(vec, size, values_);
00057 }
00058
00059 CoinWarmStartVector(const CoinWarmStartVector& rhs) {
00060 gutsOfCopy(rhs);
00061 }
00062
00063 CoinWarmStartVector& operator=(const CoinWarmStartVector& rhs) {
00064 if (this != &rhs) {
00065 gutsOfDestructor();
00066 gutsOfCopy(rhs);
00067 }
00068 return *this;
00069 }
00070
00071 inline void swap(CoinWarmStartVector& rhs) {
00072 if (this != &rhs) {
00073 std::swap(size_, rhs.size_);
00074 std::swap(values_, rhs.values_);
00075 }
00076 }
00077
00079 virtual CoinWarmStart *clone() const {
00080 return new CoinWarmStartVector(*this);
00081 }
00082
00083 virtual ~CoinWarmStartVector() {
00084 gutsOfDestructor();
00085 }
00086
00092 inline void clear() {
00093 size_ = 0;
00094 delete[] values_;
00095 values_ = NULL;
00096 }
00097
00100
00108 virtual CoinWarmStartDiff*
00109 generateDiff (const CoinWarmStart *const oldCWS) const ;
00110
00117 virtual void applyDiff (const CoinWarmStartDiff *const cwsdDiff) ;
00118
00120
00121 private:
00123
00124
00125 int size_;
00127 T* values_;
00129 };
00130
00131
00132
00148 template <typename T>
00149 class CoinWarmStartVectorDiff : public virtual CoinWarmStartDiff
00150 {
00151 friend CoinWarmStartDiff*
00152 CoinWarmStartVector<T>::generateDiff(const CoinWarmStart *const oldCWS) const;
00153 friend void
00154 CoinWarmStartVector<T>::applyDiff(const CoinWarmStartDiff *const diff) ;
00155
00156 public:
00157
00159 virtual CoinWarmStartDiff * clone() const {
00160 return new CoinWarmStartVectorDiff(*this) ;
00161 }
00162
00164 virtual CoinWarmStartVectorDiff &
00165 operator= (const CoinWarmStartVectorDiff<T>& rhs) ;
00166
00168 virtual ~CoinWarmStartVectorDiff() {
00169 delete[] diffNdxs_ ;
00170 delete[] diffVals_ ;
00171 }
00172
00173 inline void swap(CoinWarmStartVectorDiff& rhs) {
00174 if (this != &rhs) {
00175 std::swap(sze_, rhs.sze_);
00176 std::swap(diffNdxs_, rhs.diffNdxs_);
00177 std::swap(diffVals_, rhs.diffVals_);
00178 }
00179 }
00180
00183 CoinWarmStartVectorDiff () : sze_(0), diffNdxs_(0), diffVals_(NULL) {}
00184
00191 CoinWarmStartVectorDiff(const CoinWarmStartVectorDiff<T>& rhs) ;
00192
00194 CoinWarmStartVectorDiff(int sze, const unsigned int* const diffNdxs,
00195 const T* const diffVals) ;
00196
00202 inline void clear() {
00203 sze_ = 0;
00204 delete[] diffNdxs_; diffNdxs_ = NULL;
00205 delete[] diffVals_; diffVals_ = NULL;
00206 }
00207
00208 private:
00209
00213 int sze_ ;
00214
00217 unsigned int* diffNdxs_ ;
00218
00221 T* diffVals_ ;
00222 };
00223
00224
00225
00226 template <typename T, typename U>
00227 class CoinWarmStartVectorPair : public virtual CoinWarmStart
00228 {
00229 private:
00230 CoinWarmStartVector<T> t_;
00231 CoinWarmStartVector<U> u_;
00232
00233 public:
00234 inline int size0() const { return t_.size(); }
00235 inline int size1() const { return u_.size(); }
00236 inline const T* values0() const { return t_.values(); }
00237 inline const U* values1() const { return u_.values(); }
00238
00239 inline void assignVector0(int size, T*& vec) { t_.assignVector(size, vec); }
00240 inline void assignVector1(int size, U*& vec) { u_.assignVector(size, vec); }
00241
00242 CoinWarmStartVectorPair() {}
00243 CoinWarmStartVectorPair(int s0, const T* v0, int s1, const U* v1) :
00244 t_(s0, v0), u_(s1, v1) {}
00245
00246 CoinWarmStartVectorPair(const CoinWarmStartVectorPair<T,U>& rhs) :
00247 t_(rhs.t_), u_(rhs.u_) {}
00248 CoinWarmStartVectorPair& operator=(const CoinWarmStartVectorPair<T,U>& rhs) {
00249 if (this != &rhs) {
00250 t_ = rhs.t_;
00251 u_ = rhs.u_;
00252 }
00253 }
00254
00255 inline void swap(CoinWarmStartVectorPair<T,U>& rhs) {
00256 t_.swap(rhs.t_);
00257 u_.swap(rhs.u_);
00258 }
00259
00260 virtual CoinWarmStart *clone() const {
00261 return new CoinWarmStartVectorPair(*this);
00262 }
00263
00264 virtual ~CoinWarmStartVectorPair() {}
00265
00266 inline void clear() {
00267 t_.clear();
00268 u_.clear();
00269 }
00270
00271 virtual CoinWarmStartDiff*
00272 generateDiff (const CoinWarmStart *const oldCWS) const ;
00273
00274 virtual void applyDiff (const CoinWarmStartDiff *const cwsdDiff) ;
00275 };
00276
00277
00278
00279 template <typename T, typename U>
00280 class CoinWarmStartVectorPairDiff : public virtual CoinWarmStartDiff
00281 {
00282 friend CoinWarmStartDiff*
00283 CoinWarmStartVectorPair<T,U>::generateDiff(const CoinWarmStart *const oldCWS) const;
00284 friend void
00285 CoinWarmStartVectorPair<T,U>::applyDiff(const CoinWarmStartDiff *const diff) ;
00286
00287 private:
00288 CoinWarmStartVectorDiff<T> tdiff_;
00289 CoinWarmStartVectorDiff<U> udiff_;
00290
00291 public:
00292 CoinWarmStartVectorPairDiff() {}
00293 CoinWarmStartVectorPairDiff(const CoinWarmStartVectorPairDiff<T,U>& rhs) :
00294 tdiff_(rhs.tdiff_), udiff_(rhs.udiff_) {}
00295 ~CoinWarmStartVectorPairDiff() {}
00296
00297 virtual CoinWarmStartVectorPairDiff&
00298 operator=(const CoinWarmStartVectorPairDiff<T,U>& rhs) {
00299 tdiff_ = rhs.tdiff_;
00300 udiff_ = rhs.udiff_;
00301 }
00302
00303 virtual CoinWarmStartDiff * clone() const {
00304 return new CoinWarmStartVectorPairDiff(*this) ;
00305 }
00306
00307 inline void swap(CoinWarmStartVectorPairDiff<T,U>& rhs) {
00308 tdiff_.swap(rhs.tdiff_);
00309 udiff_.swap(rhs.udiff_);
00310 }
00311
00312 inline void clear() {
00313 tdiff_.clear();
00314 udiff_.clear();
00315 }
00316 };
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329 template <typename T> CoinWarmStartDiff*
00330 CoinWarmStartVector<T>::generateDiff(const CoinWarmStart *const oldCWS) const
00331 {
00332
00333
00334
00335 const CoinWarmStartVector<T>* oldVector =
00336 dynamic_cast<const CoinWarmStartVector<T>*>(oldCWS);
00337 if (!oldVector)
00338 { throw CoinError("Old warm start not derived from CoinWarmStartVector.",
00339 "generateDiff","CoinWarmStartVector") ; }
00340 const CoinWarmStartVector<T>* newVector = this ;
00341
00342
00343
00344
00345 const int oldCnt = oldVector->size() ;
00346 const int newCnt = newVector->size() ;
00347
00348 assert(newCnt >= oldCnt) ;
00349
00350 unsigned int *diffNdx = new unsigned int [newCnt];
00351 T* diffVal = new T[newCnt];
00352
00353
00354
00355
00356 const T*oldVal = oldVector->values() ;
00357 const T*newVal = newVector->values() ;
00358 int numberChanged = 0 ;
00359 int i ;
00360 for (i = 0 ; i < oldCnt ; i++) {
00361 if (oldVal[i] != newVal[i]) {
00362 diffNdx[numberChanged] = i ;
00363 diffVal[numberChanged++] = newVal[i] ;
00364 }
00365 }
00366 for ( ; i < newCnt ; i++) {
00367 diffNdx[numberChanged] = i ;
00368 diffVal[numberChanged++] = newVal[i] ;
00369 }
00370
00371
00372
00373 CoinWarmStartVectorDiff<T> *diff =
00374 new CoinWarmStartVectorDiff<T>(numberChanged,diffNdx,diffVal) ;
00375
00376
00377
00378 delete[] diffNdx ;
00379 delete[] diffVal ;
00380
00381 return diff;
00382
00383 }
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393 template <typename T> void
00394 CoinWarmStartVector<T>::applyDiff (const CoinWarmStartDiff *const cwsdDiff)
00395 {
00396
00397
00398
00399 const CoinWarmStartVectorDiff<T>* diff =
00400 dynamic_cast<const CoinWarmStartVectorDiff<T>*>(cwsdDiff) ;
00401 if (!diff) {
00402 throw CoinError("Diff not derived from CoinWarmStartVectorDiff.",
00403 "applyDiff","CoinWarmStartVector") ;
00404 }
00405
00406
00407
00408 const int numberChanges = diff->sze_ ;
00409 const unsigned int *diffNdxs = diff->diffNdxs_ ;
00410 const T* diffVals = diff->diffVals_ ;
00411 T* vals = this->values_ ;
00412
00413 for (int i = 0 ; i < numberChanges ; i++) {
00414 unsigned int diffNdx = diffNdxs[i] ;
00415 T diffVal = diffVals[i] ;
00416 vals[diffNdx] = diffVal ;
00417 }
00418 }
00419
00420
00421
00422
00423
00424
00425 template <typename T> CoinWarmStartVectorDiff<T>&
00426 CoinWarmStartVectorDiff<T>::operator=(const CoinWarmStartVectorDiff<T> &rhs)
00427 {
00428 if (this != &rhs) {
00429 if (sze_ > 0) {
00430 delete[] diffNdxs_ ;
00431 delete[] diffVals_ ;
00432 }
00433 sze_ = rhs.sze_ ;
00434 if (sze_ > 0) {
00435 diffNdxs_ = new unsigned int[sze_] ;
00436 memcpy(diffNdxs_,rhs.diffNdxs_,sze_*sizeof(unsigned int)) ;
00437 diffVals_ = new T[sze_] ;
00438 memcpy(diffVals_,rhs.diffVals_,sze_*sizeof(T)) ;
00439 } else {
00440 diffNdxs_ = 0 ;
00441 diffVals_ = 0 ;
00442 }
00443 }
00444
00445 return (*this) ;
00446 }
00447
00448
00449
00450
00451 template <typename T>
00452 CoinWarmStartVectorDiff<T>::CoinWarmStartVectorDiff(const CoinWarmStartVectorDiff<T> &rhs)
00453 : sze_(rhs.sze_),
00454 diffNdxs_(0),
00455 diffVals_(0)
00456 {
00457 if (sze_ > 0) {
00458 diffNdxs_ = new unsigned int[sze_] ;
00459 memcpy(diffNdxs_,rhs.diffNdxs_,sze_*sizeof(unsigned int)) ;
00460 diffVals_ = new T[sze_] ;
00461 memcpy(diffVals_,rhs.diffVals_,sze_*sizeof(T)) ;
00462 }
00463 }
00464
00466
00467 template <typename T>
00468 CoinWarmStartVectorDiff<T>::CoinWarmStartVectorDiff
00469 (int sze, const unsigned int *const diffNdxs, const T *const diffVals)
00470 : sze_(sze),
00471 diffNdxs_(0),
00472 diffVals_(0)
00473 {
00474 if (sze > 0) {
00475 diffNdxs_ = new unsigned int[sze] ;
00476 memcpy(diffNdxs_,diffNdxs,sze*sizeof(unsigned int)) ;
00477 diffVals_ = new T[sze] ;
00478 memcpy(diffVals_,diffVals,sze*sizeof(T)) ;
00479 }
00480 }
00481
00482 #endif