CoinWarmStartVector.hpp
Go to the documentation of this file.
1 /* $Id: CoinWarmStartVector.hpp 1498 2011-11-02 15:25:35Z mjs $ */
2 // Copyright (C) 2000, International Business Machines
3 // Corporation and others. All Rights Reserved.
4 // This code is licensed under the terms of the Eclipse Public License (EPL).
5 
6 #ifndef CoinWarmStartVector_H
7 #define CoinWarmStartVector_H
8 
9 #if defined(_MSC_VER)
10 // Turn off compiler warning about long names
11 # pragma warning(disable:4786)
12 #endif
13 
14 #include <cassert>
15 #include <cmath>
16 
17 #include "CoinHelperFunctions.hpp"
18 #include "CoinWarmStart.hpp"
19 
20 
21 //#############################################################################
22 
25 template <typename T>
26 class CoinWarmStartVector : public virtual CoinWarmStart
27 {
28 protected:
29  inline void gutsOfDestructor() {
30  delete[] values_;
31  }
32  inline void gutsOfCopy(const CoinWarmStartVector<T>& rhs) {
33  size_ = rhs.size_;
34  values_ = new T[size_];
36  }
37 
38 public:
40  int size() const { return size_; }
42  const T* values() const { return values_; }
43 
47  void assignVector(int size, T*& vec) {
48  size_ = size;
49  delete[] values_;
50  values_ = vec;
51  vec = NULL;
52  }
53 
55 
56  CoinWarmStartVector(int size, const T* vec) :
57  size_(size), values_(new T[size]) {
58  CoinDisjointCopyN(vec, size, values_);
59  }
60 
62  gutsOfCopy(rhs);
63  }
64 
66  if (this != &rhs) {
68  gutsOfCopy(rhs);
69  }
70  return *this;
71  }
72 
73  inline void swap(CoinWarmStartVector& rhs) {
74  if (this != &rhs) {
75  std::swap(size_, rhs.size_);
76  std::swap(values_, rhs.values_);
77  }
78  }
79 
81  virtual CoinWarmStart *clone() const {
82  return new CoinWarmStartVector(*this);
83  }
84 
87  }
88 
94  inline void clear() {
95  size_ = 0;
96  delete[] values_;
97  values_ = NULL;
98  }
99 
102 
110  virtual CoinWarmStartDiff*
111  generateDiff (const CoinWarmStart *const oldCWS) const ;
112 
119  virtual void applyDiff (const CoinWarmStartDiff *const cwsdDiff) ;
120 
122 
123 private:
125 
126  int size_;
131 };
132 
133 //=============================================================================
134 
150 template <typename T>
152 {
153  friend CoinWarmStartDiff*
154  CoinWarmStartVector<T>::generateDiff(const CoinWarmStart *const oldCWS) const;
155  friend void
157 
158 public:
159 
161  virtual CoinWarmStartDiff * clone() const {
162  return new CoinWarmStartVectorDiff(*this) ;
163  }
164 
166  virtual CoinWarmStartVectorDiff &
168 
171  delete[] diffNdxs_ ;
172  delete[] diffVals_ ;
173  }
174 
175  inline void swap(CoinWarmStartVectorDiff& rhs) {
176  if (this != &rhs) {
177  std::swap(sze_, rhs.sze_);
178  std::swap(diffNdxs_, rhs.diffNdxs_);
179  std::swap(diffVals_, rhs.diffVals_);
180  }
181  }
182 
186 
194 
196  CoinWarmStartVectorDiff(int sze, const unsigned int* const diffNdxs,
197  const T* const diffVals) ;
198 
204  inline void clear() {
205  sze_ = 0;
206  delete[] diffNdxs_; diffNdxs_ = NULL;
207  delete[] diffVals_; diffVals_ = NULL;
208  }
209 
210 private:
211 
215  int sze_ ;
216 
219  unsigned int* diffNdxs_ ;
220 
224 };
225 
226 //##############################################################################
227 
228 template <typename T, typename U>
229 class CoinWarmStartVectorPair : public virtual CoinWarmStart
230 {
231 private:
234 
235 public:
236  inline int size0() const { return t_.size(); }
237  inline int size1() const { return u_.size(); }
238  inline const T* values0() const { return t_.values(); }
239  inline const U* values1() const { return u_.values(); }
240 
241  inline void assignVector0(int size, T*& vec) { t_.assignVector(size, vec); }
242  inline void assignVector1(int size, U*& vec) { u_.assignVector(size, vec); }
243 
245  CoinWarmStartVectorPair(int s0, const T* v0, int s1, const U* v1) :
246  t_(s0, v0), u_(s1, v1) {}
247 
249  t_(rhs.t_), u_(rhs.u_) {}
251  if (this != &rhs) {
252  t_ = rhs.t_;
253  u_ = rhs.u_;
254  }
255  return *this;
256  }
257 
258  inline void swap(CoinWarmStartVectorPair<T,U>& rhs) {
259  t_.swap(rhs.t_);
260  u_.swap(rhs.u_);
261  }
262 
263  virtual CoinWarmStart *clone() const {
264  return new CoinWarmStartVectorPair(*this);
265  }
266 
268 
269  inline void clear() {
270  t_.clear();
271  u_.clear();
272  }
273 
274  virtual CoinWarmStartDiff*
275  generateDiff (const CoinWarmStart *const oldCWS) const ;
276 
277  virtual void applyDiff (const CoinWarmStartDiff *const cwsdDiff) ;
278 };
279 
280 //=============================================================================
281 
282 template <typename T, typename U>
284 {
285  friend CoinWarmStartDiff*
287  friend void
289 
290 private:
293 
294 public:
297  tdiff_(rhs.tdiff_), udiff_(rhs.udiff_) {}
299 
302  if (this != &rhs) {
303  tdiff_ = rhs.tdiff_;
304  udiff_ = rhs.udiff_;
305  }
306  return *this;
307  }
308 
309  virtual CoinWarmStartDiff * clone() const {
310  return new CoinWarmStartVectorPairDiff(*this) ;
311  }
312 
314  tdiff_.swap(rhs.tdiff_);
315  udiff_.swap(rhs.udiff_);
316  }
317 
318  inline void clear() {
319  tdiff_.clear();
320  udiff_.clear();
321  }
322 };
323 
324 //##############################################################################
325 //#############################################################################
326 
327 /*
328  Generate a `diff' that can convert the warm start passed as a parameter to
329  the warm start specified by this.
330 
331  The capabilities are limited: the basis passed as a parameter can be no
332  larger than the basis pointed to by this.
333 */
334 
335 template <typename T> CoinWarmStartDiff*
337 {
338 /*
339  Make sure the parameter is CoinWarmStartVector or derived class.
340 */
341  const CoinWarmStartVector<T>* oldVector =
342  dynamic_cast<const CoinWarmStartVector<T>*>(oldCWS);
343  if (!oldVector)
344  { throw CoinError("Old warm start not derived from CoinWarmStartVector.",
345  "generateDiff","CoinWarmStartVector") ; }
346  const CoinWarmStartVector<T>* newVector = this ;
347  /*
348  Make sure newVector is equal or bigger than oldVector. Calculate the worst
349  case number of diffs and allocate vectors to hold them.
350  */
351  const int oldCnt = oldVector->size() ;
352  const int newCnt = newVector->size() ;
353 
354  assert(newCnt >= oldCnt) ;
355 
356  unsigned int *diffNdx = new unsigned int [newCnt];
357  T* diffVal = new T[newCnt];
358  /*
359  Scan the vector vectors. For the portion of the vectors which overlap,
360  create diffs. Then add any additional entries from newVector.
361  */
362  const T*oldVal = oldVector->values() ;
363  const T*newVal = newVector->values() ;
364  int numberChanged = 0 ;
365  int i ;
366  for (i = 0 ; i < oldCnt ; i++) {
367  if (oldVal[i] != newVal[i]) {
368  diffNdx[numberChanged] = i ;
369  diffVal[numberChanged++] = newVal[i] ;
370  }
371  }
372  for ( ; i < newCnt ; i++) {
373  diffNdx[numberChanged] = i ;
374  diffVal[numberChanged++] = newVal[i] ;
375  }
376  /*
377  Create the object of our desire.
378  */
380  new CoinWarmStartVectorDiff<T>(numberChanged,diffNdx,diffVal) ;
381  /*
382  Clean up and return.
383  */
384  delete[] diffNdx ;
385  delete[] diffVal ;
386 
387  return diff;
388  // return (dynamic_cast<CoinWarmStartDiff<T>*>(diff)) ;
389 }
390 
391 
392 /*
393  Apply diff to this warm start.
394 
395  Update this warm start by applying diff. It's assumed that the
396  allocated capacity of the warm start is sufficiently large.
397 */
398 
399 template <typename T> void
401 {
402  /*
403  Make sure we have a CoinWarmStartVectorDiff
404  */
405  const CoinWarmStartVectorDiff<T>* diff =
406  dynamic_cast<const CoinWarmStartVectorDiff<T>*>(cwsdDiff) ;
407  if (!diff) {
408  throw CoinError("Diff not derived from CoinWarmStartVectorDiff.",
409  "applyDiff","CoinWarmStartVector") ;
410  }
411  /*
412  Application is by straighforward replacement of words in the vector vector.
413  */
414  const int numberChanges = diff->sze_ ;
415  const unsigned int *diffNdxs = diff->diffNdxs_ ;
416  const T* diffVals = diff->diffVals_ ;
417  T* vals = this->values_ ;
418 
419  for (int i = 0 ; i < numberChanges ; i++) {
420  unsigned int diffNdx = diffNdxs[i] ;
421  T diffVal = diffVals[i] ;
422  vals[diffNdx] = diffVal ;
423  }
424 }
425 
426 //#############################################################################
427 
428 
429 // Assignment
430 
431 template <typename T> CoinWarmStartVectorDiff<T>&
433 {
434  if (this != &rhs) {
435  if (sze_ > 0) {
436  delete[] diffNdxs_ ;
437  delete[] diffVals_ ;
438  }
439  sze_ = rhs.sze_ ;
440  if (sze_ > 0) {
441  diffNdxs_ = new unsigned int[sze_] ;
442  memcpy(diffNdxs_,rhs.diffNdxs_,sze_*sizeof(unsigned int)) ;
443  diffVals_ = new T[sze_] ;
444  memcpy(diffVals_,rhs.diffVals_,sze_*sizeof(T)) ;
445  } else {
446  diffNdxs_ = 0 ;
447  diffVals_ = 0 ;
448  }
449  }
450 
451  return (*this) ;
452 }
453 
454 
455 // Copy constructor
456 
457 template <typename T>
459  : sze_(rhs.sze_),
460  diffNdxs_(0),
461  diffVals_(0)
462 {
463  if (sze_ > 0) {
464  diffNdxs_ = new unsigned int[sze_] ;
465  memcpy(diffNdxs_,rhs.diffNdxs_,sze_*sizeof(unsigned int)) ;
466  diffVals_ = new T[sze_] ;
467  memcpy(diffVals_,rhs.diffVals_,sze_*sizeof(T)) ;
468  }
469 }
470 
472 
473 template <typename T>
475 (int sze, const unsigned int *const diffNdxs, const T *const diffVals)
476  : sze_(sze),
477  diffNdxs_(0),
478  diffVals_(0)
479 {
480  if (sze > 0) {
481  diffNdxs_ = new unsigned int[sze] ;
482  memcpy(diffNdxs_,diffNdxs,sze*sizeof(unsigned int)) ;
483  diffVals_ = new T[sze] ;
484  memcpy(diffVals_,diffVals,sze*sizeof(T)) ;
485  }
486 }
487 
488 #endif
CoinWarmStartVector & operator=(const CoinWarmStartVector &rhs)
void clear()
Clear the data.
T * diffVals_
Array of diff values.
CoinWarmStartVector(const CoinWarmStartVector &rhs)
void gutsOfCopy(const CoinWarmStartVector< T > &rhs)
int size() const
return the size of the vector
virtual CoinWarmStartDiff * generateDiff(const CoinWarmStart *const oldCWS) const
void CoinDisjointCopyN(register const T *from, const int size, register T *to)
This helper function copies an array to another location.
const T * values() const
return a pointer to the array of vectors
Abstract base class for warm start `diff&#39; objects.
CoinWarmStartVectorPair(const CoinWarmStartVectorPair< T, U > &rhs)
int sze_
Number of entries (and allocated capacity), in units of T.
virtual CoinWarmStart * clone() const
`Virtual constructor&#39;
virtual ~CoinWarmStartVectorDiff()
Destructor.
T * values_
the vector itself
int size_
the size of the vector
virtual void applyDiff(const CoinWarmStartDiff *const cwsdDiff)
void swap(CoinWarmStartVector &rhs)
void assignVector0(int size, T *&vec)
virtual CoinWarmStartVectorPairDiff & operator=(const CoinWarmStartVectorPairDiff< T, U > &rhs)
CoinWarmStartVector< U > u_
CoinWarmStartVectorPairDiff(const CoinWarmStartVectorPairDiff< T, U > &rhs)
WarmStart information that is only a vector.
Declaration of the generic simplex (basis-oriented) warm start class. Also contains a basis diff clas...
CoinWarmStartVector(int size, const T *vec)
void swap(CoinWarmStartVectorDiff &rhs)
CoinWarmStartVectorDiff()
Default constructor.
CoinWarmStartVectorPair(int s0, const T *v0, int s1, const U *v1)
virtual CoinWarmStart * clone() const
`Virtual constructor&#39;
void assignVector(int size, T *&vec)
Assign the vector to be the warmstart information.
virtual CoinWarmStartVectorDiff & operator=(const CoinWarmStartVectorDiff< T > &rhs)
Assignment.
void swap(CoinWarmStartVectorPairDiff< T, U > &rhs)
void assignVector1(int size, U *&vec)
virtual CoinWarmStartDiff * clone() const
`Virtual constructor&#39;
virtual void applyDiff(const CoinWarmStartDiff *const cwsdDiff)
Apply diff to this warm start.
virtual CoinWarmStartDiff * generateDiff(const CoinWarmStart *const oldCWS) const
Generate a `diff&#39; that can convert the warm start passed as a parameter to the warm start specified b...
virtual CoinWarmStartDiff * clone() const
`Virtual constructor&#39;
Abstract base class for warm start information.
Error Class thrown by an exception.
Definition: CoinError.hpp:42
CoinWarmStartVectorDiff< U > udiff_
CoinWarmStartVector< T > t_
A `diff&#39; between two CoinWarmStartVector objects.
CoinWarmStartVectorDiff< T > tdiff_
CoinWarmStartVectorPair & operator=(const CoinWarmStartVectorPair< T, U > &rhs)
unsigned int * diffNdxs_
Array of diff indices.
void clear()
Clear the data.
void swap(CoinWarmStartVectorPair< T, U > &rhs)