CoinPackedVector.hpp
Go to the documentation of this file.
1 /* $Id: CoinPackedVector.hpp 1509 2011-12-05 13:50:48Z forrest $ */
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)
241  tc); }
242 
246 
250 
254 
258 
259 
264  void sortOriginalOrder();
266 
273  void reserve(int n);
277  int capacity() const { return capacity_; }
279 
287  CoinPackedVector(int size, const int * inds, const double * elems,
294  CoinPackedVector(int capacity, int size, int *&inds, double *&elems,
297  CoinPackedVector(int size, const int * inds, double element,
301  CoinPackedVector(int size, const double * elements,
308  virtual ~CoinPackedVector ();
310 
311 private:
314  void gutsOfSetVector(int size,
316  const int * inds, const double * elems,
318  const char * method);
320  void gutsOfSetConstant(int size,
321  const int * inds, double value,
323  const char * method);
325 
326 private:
329  int * indices_;
332  double * elements_;
340 };
341 
342 //#############################################################################
343 
359 template <class BinaryFunction> void
361  const CoinPackedVectorBase& op1, double value,
362  BinaryFunction bf)
363 {
364  retVal.clear();
365  const int s = op1.getNumElements();
366  if (s > 0) {
367  retVal.reserve(s);
368  const int * inds = op1.getIndices();
369  const double * elems = op1.getElements();
370  for (int i=0; i<s; ++i ) {
371  retVal.insert(inds[i], bf(value, elems[i]));
372  }
373  }
374 }
375 
376 template <class BinaryFunction> inline void
378  double value, const CoinPackedVectorBase& op2,
379  BinaryFunction bf)
380 {
381  binaryOp(retVal, op2, value, bf);
382 }
383 
384 template <class BinaryFunction> void
386  const CoinPackedVectorBase& op1, const CoinPackedVectorBase& op2,
387  BinaryFunction bf)
388 {
389  retVal.clear();
390  const int s1 = op1.getNumElements();
391  const int s2 = op2.getNumElements();
392 /*
393  Replaced || with &&, in response to complaint from Sven deVries, who
394  rightly points out || is not appropriate for additive operations. &&
395  should be ok as long as binaryOp is understood not to create something
396  from nothing. -- lh, 04.06.11
397 */
398  if (s1 == 0 && s2 == 0)
399  return;
400 
401  retVal.reserve(s1+s2);
402 
403  const int * inds1 = op1.getIndices();
404  const double * elems1 = op1.getElements();
405  const int * inds2 = op2.getIndices();
406  const double * elems2 = op2.getElements();
407 
408  int i;
409  // loop once for each element in op1
410  for ( i=0; i<s1; ++i ) {
411  const int index = inds1[i];
412  const int pos2 = op2.findIndex(index);
413  const double val = bf(elems1[i], pos2 == -1 ? 0.0 : elems2[pos2]);
414  // if (val != 0.0) // *THINK* : should we put in only nonzeros?
415  retVal.insert(index, val);
416  }
417  // loop once for each element in operand2
418  for ( i=0; i<s2; ++i ) {
419  const int index = inds2[i];
420  // if index exists in op1, then element was processed in prior loop
421  if ( op1.isExistingIndex(index) )
422  continue;
423  // Index does not exist in op1, so the element value must be zero
424  const double val = bf(0.0, elems2[i]);
425  // if (val != 0.0) // *THINK* : should we put in only nonzeros?
426  retVal.insert(index, val);
427  }
428 }
429 
430 //-----------------------------------------------------------------------------
431 
432 template <class BinaryFunction> CoinPackedVector
433 binaryOp(const CoinPackedVectorBase& op1, double value,
434  BinaryFunction bf)
435 {
436  CoinPackedVector retVal;
437  retVal.setTestForDuplicateIndex(true);
438  binaryOp(retVal, op1, value, bf);
439  return retVal;
440 }
441 
442 template <class BinaryFunction> CoinPackedVector
443 binaryOp(double value, const CoinPackedVectorBase& op2,
444  BinaryFunction bf)
445 {
446  CoinPackedVector retVal;
447  retVal.setTestForDuplicateIndex(true);
448  binaryOp(retVal, op2, value, bf);
449  return retVal;
450 }
451 
452 template <class BinaryFunction> CoinPackedVector
454  BinaryFunction bf)
455 {
456  CoinPackedVector retVal;
457  retVal.setTestForDuplicateIndex(true);
458  binaryOp(retVal, op1, op2, bf);
459  return retVal;
460 }
461 
462 //-----------------------------------------------------------------------------
465  const CoinPackedVectorBase& op2)
466 {
467  CoinPackedVector retVal;
468  retVal.setTestForDuplicateIndex(true);
469  binaryOp(retVal, op1, op2, std::plus<double>());
470  return retVal;
471 }
472 
475  const CoinPackedVectorBase& op2)
476 {
477  CoinPackedVector retVal;
478  retVal.setTestForDuplicateIndex(true);
479  binaryOp(retVal, op1, op2, std::minus<double>());
480  return retVal;
481 }
482 
485  const CoinPackedVectorBase& op2)
486 {
487  CoinPackedVector retVal;
488  retVal.setTestForDuplicateIndex(true);
489  binaryOp(retVal, op1, op2, std::multiplies<double>());
490  return retVal;
491 }
492 
495  const CoinPackedVectorBase& op2)
496 {
497  CoinPackedVector retVal;
498  retVal.setTestForDuplicateIndex(true);
499  binaryOp(retVal, op1, op2, std::divides<double>());
500  return retVal;
501 }
503 
506 inline double sparseDotProduct(const CoinPackedVectorBase& op1,
507  const CoinPackedVectorBase& op2){
508  int len, i;
509  double acc = 0.0;
510  CoinPackedVector retVal;
511 
512  CoinPackedVector retval = op1*op2;
513  len = retval.getNumElements();
514  double * CParray = retval.getElements();
515 
516  for(i = 0; i < len; i++){
517  acc += CParray[i];
518  }
519 return acc;
520 }
521 
522 
526  const CoinPackedVectorBase& op2){
527  int i, j, len1, len2;
528  double acc = 0.0;
529 
530  const double* v1val = op1.getElements();
531  const double* v2val = op2.getElements();
532  const int* v1ind = op1.getIndices();
533  const int* v2ind = op2.getIndices();
534 
535  len1 = op1.getNumElements();
536  len2 = op2.getNumElements();
537 
538  i = 0;
539  j = 0;
540 
541  while(i < len1 && j < len2){
542  if(v1ind[i] == v2ind[j]){
543  acc += v1val[i] * v2val[j];
544  i++;
545  j++;
546  }
547  else if(v2ind[j] < v1ind[i]){
548  j++;
549  }
550  else{
551  i++;
552  } // end if-else-elseif
553  } // end while
554  return acc;
555  }
556 
557 
558 //-----------------------------------------------------------------------------
559 
565 inline CoinPackedVector
567 operator+(const CoinPackedVectorBase& op1, double value)
568 {
569  CoinPackedVector retVal(op1);
570  retVal += value;
571  return retVal;
572 }
573 
575 inline CoinPackedVector
576 operator-(const CoinPackedVectorBase& op1, double value)
577 {
578  CoinPackedVector retVal(op1);
579  retVal -= value;
580  return retVal;
581 }
582 
584 inline CoinPackedVector
585 operator*(const CoinPackedVectorBase& op1, double value)
586 {
587  CoinPackedVector retVal(op1);
588  retVal *= value;
589  return retVal;
590 }
591 
593 inline CoinPackedVector
594 operator/(const CoinPackedVectorBase& op1, double value)
595 {
596  CoinPackedVector retVal(op1);
597  retVal /= value;
598  return retVal;
599 }
600 
601 //-----------------------------------------------------------------------------
602 
604 inline CoinPackedVector
605 operator+(double value, const CoinPackedVectorBase& op1)
606 {
607  CoinPackedVector retVal(op1);
608  retVal += value;
609  return retVal;
610 }
611 
613 inline CoinPackedVector
614 operator-(double value, const CoinPackedVectorBase& op1)
615 {
616  CoinPackedVector retVal(op1);
617  const int size = retVal.getNumElements();
618  double* elems = retVal.getElements();
619  for (int i = 0; i < size; ++i) {
620  elems[i] = value - elems[i];
621  }
622  return retVal;
623 }
624 
626 inline CoinPackedVector
627 operator*(double value, const CoinPackedVectorBase& op1)
628 {
629  CoinPackedVector retVal(op1);
630  retVal *= value;
631  return retVal;
632 }
633 
635 inline CoinPackedVector
636 operator/(double value, const CoinPackedVectorBase& op1)
637 {
638  CoinPackedVector retVal(op1);
639  const int size = retVal.getNumElements();
640  double* elems = retVal.getElements();
641  for (int i = 0; i < size; ++i) {
642  elems[i] = value / elems[i];
643  }
644  return retVal;
645 }
647 
648 //#############################################################################
654 void
656 
657 #endif
void setConstant(int size, const int *inds, double elems, bool testForDuplicateIndex=COIN_DEFAULT_VALUE_FOR_DUPLICATE)
Elements set to have the same scalar value.
CoinDenseVector< T > operator*(const CoinDenseVector< T > &op1, const CoinDenseVector< T > &op2)
Return the element-wise product of two dense vectors.
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.
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.
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.
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:478
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:636
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...
CoinDenseVector< T > operator-(const CoinDenseVector< T > &op1, const CoinDenseVector< T > &op2)
Return the difference of two dense vectors.
#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.
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:489
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.
CoinDenseVector< T > operator/(const CoinDenseVector< T > &op1, const CoinDenseVector< T > &op2)
Return the element-wise ratio of two dense vectors.
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.
CoinDenseVector< T > operator+(const CoinDenseVector< T > &op1, const CoinDenseVector< T > &op2)
Return the sum of two dense vectors.
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.