CoinWarmStartVector.hpp
Go to the documentation of this file.
1 /* $Id: CoinWarmStartVector.hpp 1191 2009-07-25 08:38:12Z forrest $ */
2 // Copyright (C) 2000, International Business Machines
3 // Corporation and others. All Rights Reserved.
4 
5 #ifndef CoinWarmStartVector_H
6 #define CoinWarmStartVector_H
7 
8 #if defined(_MSC_VER)
9 // Turn off compiler warning about long names
10 # pragma warning(disable:4786)
11 #endif
12 
13 #include <cassert>
14 #include <cmath>
15 
16 #include "CoinHelperFunctions.hpp"
17 #include "CoinWarmStart.hpp"
18 
19 
20 //#############################################################################
21 
24 template <typename T>
25 class CoinWarmStartVector : public virtual CoinWarmStart
26 {
27 protected:
28  inline void gutsOfDestructor() {
29  delete[] values_;
30  }
31  inline void gutsOfCopy(const CoinWarmStartVector<T>& rhs) {
32  size_ = rhs.size_;
33  values_ = new T[size_];
35  }
36 
37 public:
39  int size() const { return size_; }
41  const T* values() const { return values_; }
42 
46  void assignVector(int size, T*& vec) {
47  size_ = size;
48  delete[] values_;
49  values_ = vec;
50  vec = NULL;
51  }
52 
54 
55  CoinWarmStartVector(int size, const T* vec) :
56  size_(size), values_(new T[size]) {
57  CoinDisjointCopyN(vec, size, values_);
58  }
59 
61  gutsOfCopy(rhs);
62  }
63 
65  if (this != &rhs) {
67  gutsOfCopy(rhs);
68  }
69  return *this;
70  }
71 
72  inline void swap(CoinWarmStartVector& rhs) {
73  if (this != &rhs) {
74  std::swap(size_, rhs.size_);
75  std::swap(values_, rhs.values_);
76  }
77  }
78 
80  virtual CoinWarmStart *clone() const {
81  return new CoinWarmStartVector(*this);
82  }
83 
86  }
87 
93  inline void clear() {
94  size_ = 0;
95  delete[] values_;
96  values_ = NULL;
97  }
98 
101 
109  virtual CoinWarmStartDiff*
110  generateDiff (const CoinWarmStart *const oldCWS) const ;
111 
118  virtual void applyDiff (const CoinWarmStartDiff *const cwsdDiff) ;
119 
121 
122 private:
124 
125  int size_;
130 };
131 
132 //=============================================================================
133 
149 template <typename T>
151 {
152  friend CoinWarmStartDiff*
153  CoinWarmStartVector<T>::generateDiff(const CoinWarmStart *const oldCWS) const;
154  friend void
156 
157 public:
158 
160  virtual CoinWarmStartDiff * clone() const {
161  return new CoinWarmStartVectorDiff(*this) ;
162  }
163 
165  virtual CoinWarmStartVectorDiff &
167 
170  delete[] diffNdxs_ ;
171  delete[] diffVals_ ;
172  }
173 
174  inline void swap(CoinWarmStartVectorDiff& rhs) {
175  if (this != &rhs) {
176  std::swap(sze_, rhs.sze_);
177  std::swap(diffNdxs_, rhs.diffNdxs_);
178  std::swap(diffVals_, rhs.diffVals_);
179  }
180  }
181 
185 
193 
195  CoinWarmStartVectorDiff(int sze, const unsigned int* const diffNdxs,
196  const T* const diffVals) ;
197 
203  inline void clear() {
204  sze_ = 0;
205  delete[] diffNdxs_; diffNdxs_ = NULL;
206  delete[] diffVals_; diffVals_ = NULL;
207  }
208 
209 private:
210 
214  int sze_ ;
215 
218  unsigned int* diffNdxs_ ;
219 
223 };
224 
225 //##############################################################################
226 
227 template <typename T, typename U>
228 class CoinWarmStartVectorPair : public virtual CoinWarmStart
229 {
230 private:
233 
234 public:
235  inline int size0() const { return t_.size(); }
236  inline int size1() const { return u_.size(); }
237  inline const T* values0() const { return t_.values(); }
238  inline const U* values1() const { return u_.values(); }
239 
240  inline void assignVector0(int size, T*& vec) { t_.assignVector(size, vec); }
241  inline void assignVector1(int size, U*& vec) { u_.assignVector(size, vec); }
242 
244  CoinWarmStartVectorPair(int s0, const T* v0, int s1, const U* v1) :
245  t_(s0, v0), u_(s1, v1) {}
246 
248  t_(rhs.t_), u_(rhs.u_) {}
250  if (this != &rhs) {
251  t_ = rhs.t_;
252  u_ = rhs.u_;
253  }
254  }
255 
256  inline void swap(CoinWarmStartVectorPair<T,U>& rhs) {
257  t_.swap(rhs.t_);
258  u_.swap(rhs.u_);
259  }
260 
261  virtual CoinWarmStart *clone() const {
262  return new CoinWarmStartVectorPair(*this);
263  }
264 
266 
267  inline void clear() {
268  t_.clear();
269  u_.clear();
270  }
271 
272  virtual CoinWarmStartDiff*
273  generateDiff (const CoinWarmStart *const oldCWS) const ;
274 
275  virtual void applyDiff (const CoinWarmStartDiff *const cwsdDiff) ;
276 };
277 
278 //=============================================================================
279 
280 template <typename T, typename U>
282 {
283  friend CoinWarmStartDiff*
285  friend void
287 
288 private:
291 
292 public:
295  tdiff_(rhs.tdiff_), udiff_(rhs.udiff_) {}
297 
300  tdiff_ = rhs.tdiff_;
301  udiff_ = rhs.udiff_;
302  }
303 
304  virtual CoinWarmStartDiff * clone() const {
305  return new CoinWarmStartVectorPairDiff(*this) ;
306  }
307 
309  tdiff_.swap(rhs.tdiff_);
310  udiff_.swap(rhs.udiff_);
311  }
312 
313  inline void clear() {
314  tdiff_.clear();
315  udiff_.clear();
316  }
317 };
318 
319 //##############################################################################
320 //#############################################################################
321 
322 /*
323  Generate a `diff' that can convert the warm start passed as a parameter to
324  the warm start specified by this.
325 
326  The capabilities are limited: the basis passed as a parameter can be no
327  larger than the basis pointed to by this.
328 */
329 
330 template <typename T> CoinWarmStartDiff*
332 {
333 /*
334  Make sure the parameter is CoinWarmStartVector or derived class.
335 */
336  const CoinWarmStartVector<T>* oldVector =
337  dynamic_cast<const CoinWarmStartVector<T>*>(oldCWS);
338  if (!oldVector)
339  { throw CoinError("Old warm start not derived from CoinWarmStartVector.",
340  "generateDiff","CoinWarmStartVector") ; }
341  const CoinWarmStartVector<T>* newVector = this ;
342  /*
343  Make sure newVector is equal or bigger than oldVector. Calculate the worst
344  case number of diffs and allocate vectors to hold them.
345  */
346  const int oldCnt = oldVector->size() ;
347  const int newCnt = newVector->size() ;
348 
349  assert(newCnt >= oldCnt) ;
350 
351  unsigned int *diffNdx = new unsigned int [newCnt];
352  T* diffVal = new T[newCnt];
353  /*
354  Scan the vector vectors. For the portion of the vectors which overlap,
355  create diffs. Then add any additional entries from newVector.
356  */
357  const T*oldVal = oldVector->values() ;
358  const T*newVal = newVector->values() ;
359  int numberChanged = 0 ;
360  int i ;
361  for (i = 0 ; i < oldCnt ; i++) {
362  if (oldVal[i] != newVal[i]) {
363  diffNdx[numberChanged] = i ;
364  diffVal[numberChanged++] = newVal[i] ;
365  }
366  }
367  for ( ; i < newCnt ; i++) {
368  diffNdx[numberChanged] = i ;
369  diffVal[numberChanged++] = newVal[i] ;
370  }
371  /*
372  Create the object of our desire.
373  */
375  new CoinWarmStartVectorDiff<T>(numberChanged,diffNdx,diffVal) ;
376  /*
377  Clean up and return.
378  */
379  delete[] diffNdx ;
380  delete[] diffVal ;
381 
382  return diff;
383  // return (dynamic_cast<CoinWarmStartDiff<T>*>(diff)) ;
384 }
385 
386 
387 /*
388  Apply diff to this warm start.
389 
390  Update this warm start by applying diff. It's assumed that the
391  allocated capacity of the warm start is sufficiently large.
392 */
393 
394 template <typename T> void
396 {
397  /*
398  Make sure we have a CoinWarmStartVectorDiff
399  */
400  const CoinWarmStartVectorDiff<T>* diff =
401  dynamic_cast<const CoinWarmStartVectorDiff<T>*>(cwsdDiff) ;
402  if (!diff) {
403  throw CoinError("Diff not derived from CoinWarmStartVectorDiff.",
404  "applyDiff","CoinWarmStartVector") ;
405  }
406  /*
407  Application is by straighforward replacement of words in the vector vector.
408  */
409  const int numberChanges = diff->sze_ ;
410  const unsigned int *diffNdxs = diff->diffNdxs_ ;
411  const T* diffVals = diff->diffVals_ ;
412  T* vals = this->values_ ;
413 
414  for (int i = 0 ; i < numberChanges ; i++) {
415  unsigned int diffNdx = diffNdxs[i] ;
416  T diffVal = diffVals[i] ;
417  vals[diffNdx] = diffVal ;
418  }
419 }
420 
421 //#############################################################################
422 
423 
424 // Assignment
425 
426 template <typename T> CoinWarmStartVectorDiff<T>&
428 {
429  if (this != &rhs) {
430  if (sze_ > 0) {
431  delete[] diffNdxs_ ;
432  delete[] diffVals_ ;
433  }
434  sze_ = rhs.sze_ ;
435  if (sze_ > 0) {
436  diffNdxs_ = new unsigned int[sze_] ;
437  memcpy(diffNdxs_,rhs.diffNdxs_,sze_*sizeof(unsigned int)) ;
438  diffVals_ = new T[sze_] ;
439  memcpy(diffVals_,rhs.diffVals_,sze_*sizeof(T)) ;
440  } else {
441  diffNdxs_ = 0 ;
442  diffVals_ = 0 ;
443  }
444  }
445 
446  return (*this) ;
447 }
448 
449 
450 // Copy constructor
451 
452 template <typename T>
454  : sze_(rhs.sze_),
455  diffNdxs_(0),
456  diffVals_(0)
457 {
458  if (sze_ > 0) {
459  diffNdxs_ = new unsigned int[sze_] ;
460  memcpy(diffNdxs_,rhs.diffNdxs_,sze_*sizeof(unsigned int)) ;
461  diffVals_ = new T[sze_] ;
462  memcpy(diffVals_,rhs.diffVals_,sze_*sizeof(T)) ;
463  }
464 }
465 
467 
468 template <typename T>
470 (int sze, const unsigned int *const diffNdxs, const T *const diffVals)
471  : sze_(sze),
472  diffNdxs_(0),
473  diffVals_(0)
474 {
475  if (sze > 0) {
476  diffNdxs_ = new unsigned int[sze] ;
477  memcpy(diffNdxs_,diffNdxs,sze*sizeof(unsigned int)) ;
478  diffVals_ = new T[sze] ;
479  memcpy(diffVals_,diffVals,sze*sizeof(T)) ;
480  }
481 }
482 
483 #endif