coin-Bcp
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 setConstant(int size, const int *inds, double elems, bool testForDuplicateIndex=COIN_DEFAULT_VALUE_FOR_DUPLICATE)
Elements set to have the same scalar value.
void operator*=(double value)
multiply every entry by value
int capacity_
Amount of memory allocated for indices_, origIndices_, and elements_.
void gutsOfSetVector(int size, const int *inds, const double *elems, bool testForDuplicateIndex, const char *method)
Copy internal date.
int nElements_
Size of indices and elements vectors.
virtual const int * getIndices() const
Get indices of 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.
CoinDenseVector< T > operator*(const CoinDenseVector< T > &op1, const CoinDenseVector< T > &op2)
Return the element-wise product of two dense vectors.
virtual const double * getElements() const
Get element values.
void setVector(int size, const int *inds, const double *elems, bool testForDuplicateIndex=COIN_DEFAULT_VALUE_FOR_DUPLICATE)
Set vector size, indices, and elements.
virtual int getNumElements() const =0
Get length of indices and elements vectors.
int * indices_
Vector indices.
CoinPackedVector & operator=(const CoinPackedVector &)
Assignment operator.
void insert(int index, double element)
Insert an element into the vector.
CoinDenseVector< T > operator/(const CoinDenseVector< T > &op1, const CoinDenseVector< T > &op2)
Return the element-wise ratio of two dense vectors.
void sortIncrIndex()
Sort the packed storage vector.
int * origIndices_
original unsorted indices
const int * getVectorIndices() const
Get indices of elements.
int getVectorNumElements() const
Get the size.
void clear()
Reset the vector (as if were just created an empty vector)
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...
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.
CoinDenseVector< T > operator+(const CoinDenseVector< T > &op1, const CoinDenseVector< T > &op2)
Return the sum of two dense vectors.
void setTestForDuplicateIndex(bool test) const
Set to the argument value whether to test for duplicate indices in the vector whenever they can occur...
Function operator.
Definition: CoinSort.hpp:534
double * elements_
Vector elements.
Abstract base class for various sparse vectors.
virtual int getNumElements() const
Get the size.
double * getElements()
Get element values.
void sortIncrElement()
Sort the packed storage vector.
void CoinSort_3(S *sfirst, S *slast, T *tfirst, U *ufirst, const CoinCompare3 &tc)
Sort a triple of containers.
Definition: CoinSort.hpp:709
void sortOriginalOrder()
Sort in original order.
double sparseDotProduct(const CoinPackedVectorBase &op1, const CoinPackedVectorBase &op2)
Returns the dot product of two CoinPackedVector objects whose elements are doubles.
bool isExistingIndex(int i) const
Return true if the i&#39;th element of the full storage vector exists in the packed storage vector...
#define COIN_DEFAULT_VALUE_FOR_DUPLICATE
void gutsOfSetConstant(int size, const int *inds, double value, bool testForDuplicateIndex, const char *method)
Copy internal date.
void operator-=(double value)
subtract value from every entry
int capacity() const
capacity returns the size which could be accomodated without having to reallocate storage...
const double * getVectorElements() const
Get element values.
void sortDecrElement()
Sort the packed storage vector.
void truncate(int newSize)
Resize the packed vector to be the first newSize elements.
virtual const double * getElements() const =0
Get element values.
CoinDenseVector< T > operator-(const CoinDenseVector< T > &op1, const CoinDenseVector< T > &op2)
Return the difference of two dense vectors.
virtual ~CoinPackedVector()
Destructor.
CoinPackedVector(bool testForDuplicateIndex=COIN_DEFAULT_VALUE_FOR_DUPLICATE)
Default constructor.
void append(const CoinPackedVectorBase &caboose)
Append a CoinPackedVector to the end.
bool testForDuplicateIndex() const
Returns true if the vector should be tested for duplicate indices when they can occur.
int * getIndices()
Get indices of elements.
friend void CoinPackedVectorUnitTest()
A function that tests the methods in the CoinPackedVector class.
Sparse Vector.
Function operator.
Definition: CoinSort.hpp:547
void operator/=(double value)
divide every entry by value
void CoinPackedVectorUnitTest()
A function that tests the methods in the CoinPackedVector class.
void operator+=(double value)
add value to every entry
void reserve(int n)
Reserve space.
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.
double sortedSparseDotProduct(const CoinPackedVectorBase &op1, const CoinPackedVectorBase &op2)
Returns the dot product of two sorted CoinPackedVector objects.
void sortDecrIndex()
Sort the packed storage vector.
void assignVector(int size, int *&inds, double *&elems, bool testForDuplicateIndex=COIN_DEFAULT_VALUE_FOR_DUPLICATE)
Assign the ownership of the arguments to this vector.
const int * getOriginalPosition() const
Get pointer to int * vector of original postions.
void swap(int i, int j)
Swap values in positions i and j of indices and elements.
void sort(const CoinCompare3 &tc)
Sort the packed storage vector.
void binaryOp(CoinPackedVector &retVal, const CoinPackedVectorBase &op1, double value, BinaryFunction bf)
Return the sum of two packed vectors.