00001
00002
00003
00004
00005
00006 #ifndef CoinWarmStartVector_H
00007 #define CoinWarmStartVector_H
00008
00009 #if defined(_MSC_VER)
00010
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
00329
00330
00331
00332
00333
00334
00335 template <typename T> CoinWarmStartDiff*
00336 CoinWarmStartVector<T>::generateDiff(const CoinWarmStart *const oldCWS) const
00337 {
00338
00339
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
00349
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
00360
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
00378
00379 CoinWarmStartVectorDiff<T> *diff =
00380 new CoinWarmStartVectorDiff<T>(numberChanged,diffNdx,diffVal) ;
00381
00382
00383
00384 delete[] diffNdx ;
00385 delete[] diffVal ;
00386
00387 return diff;
00388
00389 }
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399 template <typename T> void
00400 CoinWarmStartVector<T>::applyDiff (const CoinWarmStartDiff *const cwsdDiff)
00401 {
00402
00403
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
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
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
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