Cbc  2.10.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CoinWarmStartVector.hpp
Go to the documentation of this file.
1 /* $Id: CoinWarmStartVector.hpp 2083 2019-01-06 19:38:09Z unxusr $ */
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 
24 template < typename T >
25 class CoinWarmStartVector : public virtual CoinWarmStart {
26 protected:
27  inline void gutsOfDestructor()
28  {
29  delete[] values_;
30  }
31  inline void gutsOfCopy(const CoinWarmStartVector< T > &rhs)
32  {
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  {
49  size_ = size;
50  delete[] values_;
51  values_ = vec;
52  vec = NULL;
53  }
54 
56  : size_(0)
57  , values_(NULL)
58  {
59  }
60 
61  CoinWarmStartVector(int size, const T *vec)
62  : size_(size)
63  , values_(new T[size])
64  {
65  CoinDisjointCopyN(vec, size, values_);
66  }
67 
69  {
70  gutsOfCopy(rhs);
71  }
72 
74  {
75  if (this != &rhs) {
77  gutsOfCopy(rhs);
78  }
79  return *this;
80  }
81 
82  inline void swap(CoinWarmStartVector &rhs)
83  {
84  if (this != &rhs) {
85  std::swap(size_, rhs.size_);
86  std::swap(values_, rhs.values_);
87  }
88  }
89 
91  virtual CoinWarmStart *clone() const
92  {
93  return new CoinWarmStartVector(*this);
94  }
95 
97  {
99  }
100 
106  inline void clear()
107  {
108  size_ = 0;
109  delete[] values_;
110  values_ = NULL;
111  }
112 
115 
123  virtual CoinWarmStartDiff *
124  generateDiff(const CoinWarmStart *const oldCWS) const;
125 
132  virtual void applyDiff(const CoinWarmStartDiff *const cwsdDiff);
133 
135 
136 private:
138 
139  int size_;
144 };
145 
146 //=============================================================================
147 
163 template < typename T >
165  friend CoinWarmStartDiff *
166  CoinWarmStartVector< T >::generateDiff(const CoinWarmStart *const oldCWS) const;
167  friend void
169 
170 public:
172  virtual CoinWarmStartDiff *clone() const
173  {
174  return new CoinWarmStartVectorDiff(*this);
175  }
176 
178  virtual CoinWarmStartVectorDiff &
180 
183  {
184  delete[] diffNdxs_;
185  delete[] diffVals_;
186  }
187 
188  inline void swap(CoinWarmStartVectorDiff &rhs)
189  {
190  if (this != &rhs) {
191  std::swap(sze_, rhs.sze_);
192  std::swap(diffNdxs_, rhs.diffNdxs_);
193  std::swap(diffVals_, rhs.diffVals_);
194  }
195  }
196 
200  : sze_(0)
201  , diffNdxs_(0)
202  , diffVals_(NULL)
203  {
204  }
205 
213 
215  CoinWarmStartVectorDiff(int sze, const unsigned int *const diffNdxs,
216  const T *const diffVals);
217 
223  inline void clear()
224  {
225  sze_ = 0;
226  delete[] diffNdxs_;
227  diffNdxs_ = NULL;
228  delete[] diffVals_;
229  diffVals_ = NULL;
230  }
231 
232 private:
236  int sze_;
237 
240  unsigned int *diffNdxs_;
241 
245 };
246 
247 //##############################################################################
248 
249 template < typename T, typename U >
250 class CoinWarmStartVectorPair : public virtual CoinWarmStart {
251 private:
254 
255 public:
256  inline int size0() const { return t_.size(); }
257  inline int size1() const { return u_.size(); }
258  inline const T *values0() const { return t_.values(); }
259  inline const U *values1() const { return u_.values(); }
260 
261  inline void assignVector0(int size, T *&vec) { t_.assignVector(size, vec); }
262  inline void assignVector1(int size, U *&vec) { u_.assignVector(size, vec); }
263 
265  CoinWarmStartVectorPair(int s0, const T *v0, int s1, const U *v1)
266  : t_(s0, v0)
267  , u_(s1, v1)
268  {
269  }
270 
272  : t_(rhs.t_)
273  , u_(rhs.u_)
274  {
275  }
277  {
278  if (this != &rhs) {
279  t_ = rhs.t_;
280  u_ = rhs.u_;
281  }
282  return *this;
283  }
284 
286  {
287  t_.swap(rhs.t_);
288  u_.swap(rhs.u_);
289  }
290 
291  virtual CoinWarmStart *clone() const
292  {
293  return new CoinWarmStartVectorPair(*this);
294  }
295 
297 
298  inline void clear()
299  {
300  t_.clear();
301  u_.clear();
302  }
303 
304  virtual CoinWarmStartDiff *
305  generateDiff(const CoinWarmStart *const oldCWS) const;
306 
307  virtual void applyDiff(const CoinWarmStartDiff *const cwsdDiff);
308 };
309 
310 //=============================================================================
311 
312 template < typename T, typename U >
314  friend CoinWarmStartDiff *
316  friend void
318 
319 private:
322 
323 public:
326  : tdiff_(rhs.tdiff_)
327  , udiff_(rhs.udiff_)
328  {
329  }
331 
334  {
335  if (this != &rhs) {
336  tdiff_ = rhs.tdiff_;
337  udiff_ = rhs.udiff_;
338  }
339  return *this;
340  }
341 
342  virtual CoinWarmStartDiff *clone() const
343  {
344  return new CoinWarmStartVectorPairDiff(*this);
345  }
346 
348  {
349  tdiff_.swap(rhs.tdiff_);
350  udiff_.swap(rhs.udiff_);
351  }
352 
353  inline void clear()
354  {
355  tdiff_.clear();
356  udiff_.clear();
357  }
358 };
359 
360 //##############################################################################
361 //#############################################################################
362 
363 /*
364  Generate a `diff' that can convert the warm start passed as a parameter to
365  the warm start specified by this.
366 
367  The capabilities are limited: the basis passed as a parameter can be no
368  larger than the basis pointed to by this.
369 */
370 
371 template < typename T >
374 {
375  /*
376  Make sure the parameter is CoinWarmStartVector or derived class.
377 */
378  const CoinWarmStartVector< T > *oldVector = dynamic_cast< const CoinWarmStartVector< T > * >(oldCWS);
379  if (!oldVector) {
380  throw CoinError("Old warm start not derived from CoinWarmStartVector.",
381  "generateDiff", "CoinWarmStartVector");
382  }
383  const CoinWarmStartVector< T > *newVector = this;
384  /*
385  Make sure newVector is equal or bigger than oldVector. Calculate the worst
386  case number of diffs and allocate vectors to hold them.
387  */
388  const int oldCnt = oldVector->size();
389  const int newCnt = newVector->size();
390 
391  assert(newCnt >= oldCnt);
392 
393  unsigned int *diffNdx = new unsigned int[newCnt];
394  T *diffVal = new T[newCnt];
395  /*
396  Scan the vector vectors. For the portion of the vectors which overlap,
397  create diffs. Then add any additional entries from newVector.
398  */
399  const T *oldVal = oldVector->values();
400  const T *newVal = newVector->values();
401  int numberChanged = 0;
402  int i;
403  for (i = 0; i < oldCnt; i++) {
404  if (oldVal[i] != newVal[i]) {
405  diffNdx[numberChanged] = i;
406  diffVal[numberChanged++] = newVal[i];
407  }
408  }
409  for (; i < newCnt; i++) {
410  diffNdx[numberChanged] = i;
411  diffVal[numberChanged++] = newVal[i];
412  }
413  /*
414  Create the object of our desire.
415  */
416  CoinWarmStartVectorDiff< T > *diff = new CoinWarmStartVectorDiff< T >(numberChanged, diffNdx, diffVal);
417  /*
418  Clean up and return.
419  */
420  delete[] diffNdx;
421  delete[] diffVal;
422 
423  return diff;
424  // return (dynamic_cast<CoinWarmStartDiff<T>*>(diff)) ;
425 }
426 
427 /*
428  Apply diff to this warm start.
429 
430  Update this warm start by applying diff. It's assumed that the
431  allocated capacity of the warm start is sufficiently large.
432 */
433 
434 template < typename T >
436 {
437  /*
438  Make sure we have a CoinWarmStartVectorDiff
439  */
440  const CoinWarmStartVectorDiff< T > *diff = dynamic_cast< const CoinWarmStartVectorDiff< T > * >(cwsdDiff);
441  if (!diff) {
442  throw CoinError("Diff not derived from CoinWarmStartVectorDiff.",
443  "applyDiff", "CoinWarmStartVector");
444  }
445  /*
446  Application is by straighforward replacement of words in the vector vector.
447  */
448  const int numberChanges = diff->sze_;
449  const unsigned int *diffNdxs = diff->diffNdxs_;
450  const T *diffVals = diff->diffVals_;
451  T *vals = this->values_;
452 
453  for (int i = 0; i < numberChanges; i++) {
454  unsigned int diffNdx = diffNdxs[i];
455  T diffVal = diffVals[i];
456  vals[diffNdx] = diffVal;
457  }
458 }
459 
460 //#############################################################################
461 
462 // Assignment
463 
464 template < typename T >
467 {
468  if (this != &rhs) {
469  if (sze_ > 0) {
470  delete[] diffNdxs_;
471  delete[] diffVals_;
472  }
473  sze_ = rhs.sze_;
474  if (sze_ > 0) {
475  diffNdxs_ = new unsigned int[sze_];
476  memcpy(diffNdxs_, rhs.diffNdxs_, sze_ * sizeof(unsigned int));
477  diffVals_ = new T[sze_];
478  memcpy(diffVals_, rhs.diffVals_, sze_ * sizeof(T));
479  } else {
480  diffNdxs_ = 0;
481  diffVals_ = 0;
482  }
483  }
484 
485  return (*this);
486 }
487 
488 // Copy constructor
489 
490 template < typename T >
492  : sze_(rhs.sze_)
493  , diffNdxs_(0)
494  , diffVals_(0)
495 {
496  if (sze_ > 0) {
497  diffNdxs_ = new unsigned int[sze_];
498  memcpy(diffNdxs_, rhs.diffNdxs_, sze_ * sizeof(unsigned int));
499  diffVals_ = new T[sze_];
500  memcpy(diffVals_, rhs.diffVals_, sze_ * sizeof(T));
501  }
502 }
503 
505 
506 template < typename T >
507 CoinWarmStartVectorDiff< T >::CoinWarmStartVectorDiff(int sze, const unsigned int *const diffNdxs, const T *const diffVals)
508  : sze_(sze)
509  , diffNdxs_(0)
510  , diffVals_(0)
511 {
512  if (sze > 0) {
513  diffNdxs_ = new unsigned int[sze];
514  memcpy(diffNdxs_, diffNdxs, sze * sizeof(unsigned int));
515  diffVals_ = new T[sze];
516  memcpy(diffVals_, diffVals, sze * sizeof(T));
517  }
518 }
519 
520 #endif
521 
522 /* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2
523 */
Error Class thrown by an exception.
Definition: CoinError.hpp:42
A `diff&#39; between two CoinWarmStartVector objects.
void CoinDisjointCopyN(const T *from, const CoinBigIndex size, T *to)
This helper function copies an array to another location.
int size_
the size of the vector
virtual CoinWarmStartDiff * clone() const
`Virtual constructor&#39;
virtual CoinWarmStartVectorDiff & operator=(const CoinWarmStartVectorDiff< T > &rhs)
Assignment.
void assignVector(int size, T *&vec)
Assign the vector to be the warmstart information.
CoinWarmStartVector< T > t_
void clear()
Clear the data.
T * values_
the vector itself
CoinWarmStartVectorPairDiff(const CoinWarmStartVectorPairDiff< T, U > &rhs)
T * diffVals_
Array of diff values.
virtual CoinWarmStartDiff * generateDiff(const CoinWarmStart *const oldCWS) const
virtual void applyDiff(const CoinWarmStartDiff *const cwsdDiff)
void assignVector0(int size, T *&vec)
CoinWarmStartVector & operator=(const CoinWarmStartVector &rhs)
void gutsOfCopy(const CoinWarmStartVector< T > &rhs)
CoinWarmStartVector(int size, const T *vec)
virtual CoinWarmStart * clone() const
`Virtual constructor&#39;
virtual CoinWarmStartVectorPairDiff & operator=(const CoinWarmStartVectorPairDiff< T, U > &rhs)
CoinWarmStartVectorDiff< U > udiff_
unsigned int * diffNdxs_
Array of diff indices.
CoinWarmStartVector< U > u_
CoinWarmStartVectorPair & operator=(const CoinWarmStartVectorPair< T, U > &rhs)
CoinWarmStartVector(const CoinWarmStartVector &rhs)
CoinWarmStartVectorPair(int s0, const T *v0, int s1, const U *v1)
Copyright (C) 2000 – 2003, International Business Machines Corporation and others.
void swap(CoinWarmStartVectorDiff &rhs)
void swap(CoinWarmStartVectorPair< T, U > &rhs)
virtual CoinWarmStart * clone() const
`Virtual constructor&#39;
void assignVector1(int size, U *&vec)
void clear()
Clear the data.
Abstract base class for warm start `diff&#39; objects.
CoinWarmStartVectorPair(const CoinWarmStartVectorPair< T, U > &rhs)
WarmStart information that is only a vector.
CoinWarmStartVectorDiff< T > tdiff_
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 void applyDiff(const CoinWarmStartDiff *const cwsdDiff)
Apply diff to this warm start.
virtual ~CoinWarmStartVectorDiff()
Destructor.
int size() const
return the size of the vector
void swap(CoinWarmStartVector &rhs)
const T * values() const
return a pointer to the array of vectors
void swap(CoinWarmStartVectorPairDiff< T, U > &rhs)
Abstract base class for warm start information.
int sze_
Number of entries (and allocated capacity), in units of T.
CoinWarmStartVectorDiff()
Default constructor.
virtual CoinWarmStartDiff * clone() const
`Virtual constructor&#39;