Cbc  2.10.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CoinPackedVector.hpp
Go to the documentation of this file.
1 /* $Id: CoinPackedVector.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 CoinPackedVector_H
7 #define CoinPackedVector_H
8 
9 #include <map>
10 
11 #include "CoinPragma.hpp"
12 #include "CoinPackedVectorBase.hpp"
13 #include "CoinSort.hpp"
14 
15 #ifdef COIN_FAST_CODE
16 #ifndef COIN_NOTEST_DUPLICATE
17 #define COIN_NOTEST_DUPLICATE
18 #endif
19 #endif
20 
21 #ifndef COIN_NOTEST_DUPLICATE
22 #define COIN_DEFAULT_VALUE_FOR_DUPLICATE true
23 #else
24 #define COIN_DEFAULT_VALUE_FOR_DUPLICATE false
25 #endif
26 
124  friend void CoinPackedVectorUnitTest();
125 
126 public:
129  virtual int getNumElements() const { return nElements_; }
132  virtual const int *getIndices() const { return indices_; }
134  virtual const double *getElements() const { return elements_; }
136  int *getIndices() { return indices_; }
138  inline int getVectorNumElements() const { return nElements_; }
140  inline const int *getVectorIndices() const { return indices_; }
142  inline const double *getVectorElements() const { return elements_; }
144  double *getElements() { return elements_; }
148  const int *getOriginalPosition() const { return origIndices_; }
150 
151  //-------------------------------------------------------------------
152  // Set indices and elements
153  //-------------------------------------------------------------------
156  void clear();
168 
175  void assignVector(int size, int *&inds, double *&elems,
177 
183  void setVector(int size, const int *inds, const double *elems,
185 
187  void setConstant(int size, const int *inds, double elems,
189 
191  void setFull(int size, const double *elems,
193 
196  void setFullNonZero(int size, const double *elems,
198 
202  void setElement(int index, double element);
203 
205  void insert(int index, double element);
207  void append(const CoinPackedVectorBase &caboose);
208 
210  void swap(int i, int j);
211 
214  void truncate(int newSize);
216 
219  void operator+=(double value);
222  void operator-=(double value);
224  void operator*=(double value);
226  void operator/=(double value);
228 
238  template < class CoinCompare3 >
239  void sort(const CoinCompare3 &tc)
240  {
242  tc);
243  }
244 
246  {
249  }
250 
252  {
255  }
256 
258  {
261  }
262 
264  {
267  }
268 
273  void sortOriginalOrder();
275 
282  void reserve(int n);
286  int capacity() const { return capacity_; }
288 
296  CoinPackedVector(int size, const int *inds, const double *elems,
303  CoinPackedVector(int capacity, int size, int *&inds, double *&elems,
306  CoinPackedVector(int size, const int *inds, double element,
310  CoinPackedVector(int size, const double *elements,
317  virtual ~CoinPackedVector();
319 
320 private:
323  void gutsOfSetVector(int size,
325  const int *inds, const double *elems,
327  const char *method);
329  void gutsOfSetConstant(int size,
330  const int *inds, double value,
332  const char *method);
334 
335 private:
338  int *indices_;
341  double *elements_;
349 };
350 
351 //#############################################################################
352 
368 template < class BinaryFunction >
370  const CoinPackedVectorBase &op1, double value,
371  BinaryFunction bf)
372 {
373  retVal.clear();
374  const int s = op1.getNumElements();
375  if (s > 0) {
376  retVal.reserve(s);
377  const int *inds = op1.getIndices();
378  const double *elems = op1.getElements();
379  for (int i = 0; i < s; ++i) {
380  retVal.insert(inds[i], bf(value, elems[i]));
381  }
382  }
383 }
384 
385 template < class BinaryFunction >
386 inline void
388  double value, const CoinPackedVectorBase &op2,
389  BinaryFunction bf)
390 {
391  binaryOp(retVal, op2, value, bf);
392 }
393 
394 template < class BinaryFunction >
396  const CoinPackedVectorBase &op1, const CoinPackedVectorBase &op2,
397  BinaryFunction bf)
398 {
399  retVal.clear();
400  const int s1 = op1.getNumElements();
401  const int s2 = op2.getNumElements();
402  /*
403  Replaced || with &&, in response to complaint from Sven deVries, who
404  rightly points out || is not appropriate for additive operations. &&
405  should be ok as long as binaryOp is understood not to create something
406  from nothing. -- lh, 04.06.11
407 */
408  if (s1 == 0 && s2 == 0)
409  return;
410 
411  retVal.reserve(s1 + s2);
412 
413  const int *inds1 = op1.getIndices();
414  const double *elems1 = op1.getElements();
415  const int *inds2 = op2.getIndices();
416  const double *elems2 = op2.getElements();
417 
418  int i;
419  // loop once for each element in op1
420  for (i = 0; i < s1; ++i) {
421  const int index = inds1[i];
422  const int pos2 = op2.findIndex(index);
423  const double val = bf(elems1[i], pos2 == -1 ? 0.0 : elems2[pos2]);
424  // if (val != 0.0) // *THINK* : should we put in only nonzeros?
425  retVal.insert(index, val);
426  }
427  // loop once for each element in operand2
428  for (i = 0; i < s2; ++i) {
429  const int index = inds2[i];
430  // if index exists in op1, then element was processed in prior loop
431  if (op1.isExistingIndex(index))
432  continue;
433  // Index does not exist in op1, so the element value must be zero
434  const double val = bf(0.0, elems2[i]);
435  // if (val != 0.0) // *THINK* : should we put in only nonzeros?
436  retVal.insert(index, val);
437  }
438 }
439 
440 //-----------------------------------------------------------------------------
441 
442 template < class BinaryFunction >
444 binaryOp(const CoinPackedVectorBase &op1, double value,
445  BinaryFunction bf)
446 {
447  CoinPackedVector retVal;
448  retVal.setTestForDuplicateIndex(true);
449  binaryOp(retVal, op1, value, bf);
450  return retVal;
451 }
452 
453 template < class BinaryFunction >
455 binaryOp(double value, const CoinPackedVectorBase &op2,
456  BinaryFunction bf)
457 {
458  CoinPackedVector retVal;
459  retVal.setTestForDuplicateIndex(true);
460  binaryOp(retVal, op2, value, bf);
461  return retVal;
462 }
463 
464 template < class BinaryFunction >
467  BinaryFunction bf)
468 {
469  CoinPackedVector retVal;
470  retVal.setTestForDuplicateIndex(true);
471  binaryOp(retVal, op1, op2, bf);
472  return retVal;
473 }
474 
475 //-----------------------------------------------------------------------------
478  const CoinPackedVectorBase &op2)
479 {
480  CoinPackedVector retVal;
481  retVal.setTestForDuplicateIndex(true);
482  binaryOp(retVal, op1, op2, std::plus< double >());
483  return retVal;
484 }
485 
488  const CoinPackedVectorBase &op2)
489 {
490  CoinPackedVector retVal;
491  retVal.setTestForDuplicateIndex(true);
492  binaryOp(retVal, op1, op2, std::minus< double >());
493  return retVal;
494 }
495 
498  const CoinPackedVectorBase &op2)
499 {
500  CoinPackedVector retVal;
501  retVal.setTestForDuplicateIndex(true);
502  binaryOp(retVal, op1, op2, std::multiplies< double >());
503  return retVal;
504 }
505 
508  const CoinPackedVectorBase &op2)
509 {
510  CoinPackedVector retVal;
511  retVal.setTestForDuplicateIndex(true);
512  binaryOp(retVal, op1, op2, std::divides< double >());
513  return retVal;
514 }
516 
519 inline double sparseDotProduct(const CoinPackedVectorBase &op1,
520  const CoinPackedVectorBase &op2)
521 {
522  int len, i;
523  double acc = 0.0;
524  CoinPackedVector retVal;
525 
526  CoinPackedVector retval = op1 * op2;
527  len = retval.getNumElements();
528  double *CParray = retval.getElements();
529 
530  for (i = 0; i < len; i++) {
531  acc += CParray[i];
532  }
533  return acc;
534 }
535 
539  const CoinPackedVectorBase &op2)
540 {
541  int i, j, len1, len2;
542  double acc = 0.0;
543 
544  const double *v1val = op1.getElements();
545  const double *v2val = op2.getElements();
546  const int *v1ind = op1.getIndices();
547  const int *v2ind = op2.getIndices();
548 
549  len1 = op1.getNumElements();
550  len2 = op2.getNumElements();
551 
552  i = 0;
553  j = 0;
554 
555  while (i < len1 && j < len2) {
556  if (v1ind[i] == v2ind[j]) {
557  acc += v1val[i] * v2val[j];
558  i++;
559  j++;
560  } else if (v2ind[j] < v1ind[i]) {
561  j++;
562  } else {
563  i++;
564  } // end if-else-elseif
565  } // end while
566  return acc;
567 }
568 
569 //-----------------------------------------------------------------------------
570 
576 inline CoinPackedVector
578 operator+(const CoinPackedVectorBase &op1, double value)
579 {
580  CoinPackedVector retVal(op1);
581  retVal += value;
582  return retVal;
583 }
584 
586 inline CoinPackedVector
587 operator-(const CoinPackedVectorBase &op1, double value)
588 {
589  CoinPackedVector retVal(op1);
590  retVal -= value;
591  return retVal;
592 }
593 
595 inline CoinPackedVector
596 operator*(const CoinPackedVectorBase &op1, double value)
597 {
598  CoinPackedVector retVal(op1);
599  retVal *= value;
600  return retVal;
601 }
602 
604 inline CoinPackedVector
605 operator/(const CoinPackedVectorBase &op1, double value)
606 {
607  CoinPackedVector retVal(op1);
608  retVal /= value;
609  return retVal;
610 }
611 
612 //-----------------------------------------------------------------------------
613 
615 inline CoinPackedVector
616 operator+(double value, const CoinPackedVectorBase &op1)
617 {
618  CoinPackedVector retVal(op1);
619  retVal += value;
620  return retVal;
621 }
622 
624 inline CoinPackedVector
625 operator-(double value, const CoinPackedVectorBase &op1)
626 {
627  CoinPackedVector retVal(op1);
628  const int size = retVal.getNumElements();
629  double *elems = retVal.getElements();
630  for (int i = 0; i < size; ++i) {
631  elems[i] = value - elems[i];
632  }
633  return retVal;
634 }
635 
637 inline CoinPackedVector
638 operator*(double value, const CoinPackedVectorBase &op1)
639 {
640  CoinPackedVector retVal(op1);
641  retVal *= value;
642  return retVal;
643 }
644 
646 inline CoinPackedVector
647 operator/(double value, const CoinPackedVectorBase &op1)
648 {
649  CoinPackedVector retVal(op1);
650  const int size = retVal.getNumElements();
651  double *elems = retVal.getElements();
652  for (int i = 0; i < size; ++i) {
653  elems[i] = value / elems[i];
654  }
655  return retVal;
656 }
658 
659 //#############################################################################
666 
667 #endif
668 
669 /* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2
670 */
void clear()
Reset the vector (as if were just created an empty vector)
CoinPackedVector & operator=(const CoinPackedVector &)
Assignment operator.
void truncate(int newSize)
Resize the packed vector to be the first newSize elements.
double * getElements()
Get element values.
void setTestForDuplicateIndex(bool test) const
Set to the argument value whether to test for duplicate indices in the vector whenever they can occur...
void gutsOfSetVector(int size, const int *inds, const double *elems, bool testForDuplicateIndex, const char *method)
Copy internal date.
CoinPackedVector(bool testForDuplicateIndex=COIN_DEFAULT_VALUE_FOR_DUPLICATE)
Default constructor.
int nElements_
Size of indices and elements vectors.
void binaryOp(CoinPackedVector &retVal, const CoinPackedVectorBase &op1, double value, BinaryFunction bf)
void setElement(int index, double element)
Set an existing element in the packed vector The first argument is the &quot;index&quot; into the elements() ar...
bool isExistingIndex(int i) const
Return true if the i&#39;th element of the full storage vector exists in the packed storage vector...
virtual int getNumElements() const
Get the size.
void gutsOfSetConstant(int size, const int *inds, double value, bool testForDuplicateIndex, const char *method)
void CoinPackedVectorUnitTest()
A function that tests the methods in the CoinPackedVector class.
const int * getVectorIndices() const
Get indices of elements.
virtual const double * getElements() const
Get element values.
void operator+=(double value)
add value to every entry
const int * getOriginalPosition() const
Get pointer to int * vector of original postions.
void operator-=(double value)
subtract value from every entry
Function operator.
Definition: CoinSort.hpp:547
CoinDenseVector< T > operator+(const CoinDenseVector< T > &op1, const CoinDenseVector< T > &op2)
Return the sum of two dense vectors.
void operator/=(double value)
divide every entry by value
Abstract base class for various sparse vectors.
virtual const double * getElements() const =0
Get element values.
void operator*=(double value)
multiply every entry by value
int * indices_
Vector indices.
CoinDenseVector< T > operator-(const CoinDenseVector< T > &op1, const CoinDenseVector< T > &op2)
Return the difference of two dense vectors.
bool testForDuplicateIndex() const
Returns true if the vector should be tested for duplicate indices when they can occur.
virtual ~CoinPackedVector()
Destructor.
int getVectorNumElements() const
Get the size.
#define COIN_DEFAULT_VALUE_FOR_DUPLICATE
void assignVector(int size, int *&inds, double *&elems, bool testForDuplicateIndex=COIN_DEFAULT_VALUE_FOR_DUPLICATE)
Assign the ownership of the arguments to this vector.
void setVector(int size, const int *inds, const double *elems, bool testForDuplicateIndex=COIN_DEFAULT_VALUE_FOR_DUPLICATE)
Set vector size, indices, and elements.
void sort(const CoinCompare3 &tc)
Sort the packed storage vector.
virtual int getNumElements() const =0
Get length of indices and elements vectors.
CoinDenseVector< T > operator/(const CoinDenseVector< T > &op1, const CoinDenseVector< T > &op2)
Return the element-wise ratio of two dense vectors.
void insert(int index, double element)
Insert an element into the vector.
const double * getVectorElements() const
Get element values.
int capacity() const
capacity returns the size which could be accomodated without having to reallocate storage...
friend void CoinPackedVectorUnitTest()
A function that tests the methods in the CoinPackedVector class.
CoinDenseVector< T > operator*(const CoinDenseVector< T > &op1, const CoinDenseVector< T > &op2)
Return the element-wise product of two dense vectors.
int * origIndices_
original unsorted indices
void reserve(int n)
Reserve space.
double sortedSparseDotProduct(const CoinPackedVectorBase &op1, const CoinPackedVectorBase &op2)
Returns the dot product of two sorted CoinPackedVector objects.
Function operator.
Definition: CoinSort.hpp:534
void setFull(int size, const double *elems, bool testForDuplicateIndex=COIN_DEFAULT_VALUE_FOR_DUPLICATE)
Indices are not specified and are taken to be 0,1,...,size-1.
void sortOriginalOrder()
Sort in original order.
void CoinSort_3(S *sfirst, S *slast, T *tfirst, U *ufirst, const CoinCompare3 &tc)
Sort a triple of containers.
Definition: CoinSort.hpp:709
int * getIndices()
Get indices of elements.
double sparseDotProduct(const CoinPackedVectorBase &op1, const CoinPackedVectorBase &op2)
Returns the dot product of two CoinPackedVector objects whose elements are doubles.
void setConstant(int size, const int *inds, double elems, bool testForDuplicateIndex=COIN_DEFAULT_VALUE_FOR_DUPLICATE)
Elements set to have the same scalar value.
virtual const int * getIndices() const =0
Get indices of elements.
int findIndex(int i) const
Return the position of the i&#39;th element of the full storage vector.
virtual const int * getIndices() const
Get indices of elements.
void append(const CoinPackedVectorBase &caboose)
Append a CoinPackedVector to the end.
Sparse Vector.
int capacity_
Amount of memory allocated for indices_, origIndices_, and elements_.
void setFullNonZero(int size, const double *elems, bool testForDuplicateIndex=COIN_DEFAULT_VALUE_FOR_DUPLICATE)
Indices are not specified and are taken to be 0,1,...,size-1, but only where non zero.
double * elements_
Vector elements.
void swap(int i, int j)
Swap values in positions i and j of indices and elements.