CoinPackedVector.hpp
Go to the documentation of this file.
1 /* $Id: CoinPackedVector.hpp 1215 2009-11-05 11:03:04Z forrest $ */
2 // Copyright (C) 2000, International Business Machines
3 // Corporation and others. All Rights Reserved.
4 #ifndef CoinPackedVector_H
5 #define CoinPackedVector_H
6 
7 #if defined(_MSC_VER)
8 // Turn off compiler warning about long names
9 # pragma warning(disable:4786)
10 #endif
11 
12 #include <map>
13 
14 #include "CoinPackedVectorBase.hpp"
15 #include "CoinSort.hpp"
16 #ifndef COIN_NOTEST_DUPLICATE
17 #define COIN_DEFAULT_VALUE_FOR_DUPLICATE true
18 #else
19 #define COIN_DEFAULT_VALUE_FOR_DUPLICATE false
20 #endif
21 
119  friend void CoinPackedVectorUnitTest();
120 
121 public:
124  virtual int getNumElements() const { return nElements_; }
127  virtual const int * getIndices() const { return indices_; }
129  virtual const double * getElements() const { return elements_; }
131  int * getIndices() { return indices_; }
133  double * getElements() { return elements_; }
137  const int * getOriginalPosition() const { return origIndices_; }
139 
140  //-------------------------------------------------------------------
141  // Set indices and elements
142  //-------------------------------------------------------------------
145  void clear();
157 
164  void assignVector(int size, int*& inds, double*& elems,
166 
172  void setVector(int size, const int * inds, const double * elems,
174 
176  void setConstant(int size, const int * inds, double elems,
178 
180  void setFull(int size, const double * elems,
182 
185  void setFullNonZero(int size, const double * elems,
187 
191  void setElement(int index, double element);
192 
194  void insert(int index, double element);
196  void append(const CoinPackedVectorBase & caboose);
197 
199  void swap(int i, int j);
200 
203  void truncate(int newSize);
205 
208  void operator+=(double value);
211  void operator-=(double value);
213  void operator*=(double value);
215  void operator/=(double value);
217 
227  template <class CoinCompare3>
228  void sort(const CoinCompare3 & tc)
230  tc); }
231 
235 
239 
243 
247 
248 
253  void sortOriginalOrder();
255 
262  void reserve(int n);
266  int capacity() const { return capacity_; }
268 
276  CoinPackedVector(int size, const int * inds, const double * elems,
283  CoinPackedVector(int capacity, int size, int *&inds, double *&elems,
286  CoinPackedVector(int size, const int * inds, double element,
290  CoinPackedVector(int size, const double * elements,
297  virtual ~CoinPackedVector ();
299 
300 private:
303  void gutsOfSetVector(int size,
305  const int * inds, const double * elems,
307  const char * method);
309  void gutsOfSetConstant(int size,
310  const int * inds, double value,
312  const char * method);
314 
315 private:
318  int * indices_;
321  double * elements_;
329 };
330 
331 //#############################################################################
332 
348 template <class BinaryFunction> void
350  const CoinPackedVectorBase& op1, double value,
351  BinaryFunction bf)
352 {
353  retVal.clear();
354  const int s = op1.getNumElements();
355  if (s > 0) {
356  retVal.reserve(s);
357  const int * inds = op1.getIndices();
358  const double * elems = op1.getElements();
359  for (int i=0; i<s; ++i ) {
360  retVal.insert(inds[i], bf(value, elems[i]));
361  }
362  }
363 }
364 
365 template <class BinaryFunction> inline void
367  double value, const CoinPackedVectorBase& op2,
368  BinaryFunction bf)
369 {
370  binaryOp(retVal, op2, value, bf);
371 }
372 
373 template <class BinaryFunction> void
375  const CoinPackedVectorBase& op1, const CoinPackedVectorBase& op2,
376  BinaryFunction bf)
377 {
378  retVal.clear();
379  const int s1 = op1.getNumElements();
380  const int s2 = op2.getNumElements();
381 /*
382  Replaced || with &&, in response to complaint from Sven deVries, who
383  rightly points out || is not appropriate for additive operations. &&
384  should be ok as long as binaryOp is understood not to create something
385  from nothing. -- lh, 04.06.11
386 */
387  if (s1 == 0 && s2 == 0)
388  return;
389 
390  retVal.reserve(s1+s2);
391 
392  const int * inds1 = op1.getIndices();
393  const double * elems1 = op1.getElements();
394  const int * inds2 = op2.getIndices();
395  const double * elems2 = op2.getElements();
396 
397  int i;
398  // loop once for each element in op1
399  for ( i=0; i<s1; ++i ) {
400  const int index = inds1[i];
401  const int pos2 = op2.findIndex(index);
402  const double val = bf(elems1[i], pos2 == -1 ? 0.0 : elems2[pos2]);
403  // if (val != 0.0) // *THINK* : should we put in only nonzeros?
404  retVal.insert(index, val);
405  }
406  // loop once for each element in operand2
407  for ( i=0; i<s2; ++i ) {
408  const int index = inds2[i];
409  // if index exists in op1, then element was processed in prior loop
410  if ( op1.isExistingIndex(index) )
411  continue;
412  // Index does not exist in op1, so the element value must be zero
413  const double val = bf(0.0, elems2[i]);
414  // if (val != 0.0) // *THINK* : should we put in only nonzeros?
415  retVal.insert(index, val);
416  }
417 }
418 
419 //-----------------------------------------------------------------------------
420 
421 template <class BinaryFunction> CoinPackedVector
422 binaryOp(const CoinPackedVectorBase& op1, double value,
423  BinaryFunction bf)
424 {
425  CoinPackedVector retVal;
426  retVal.setTestForDuplicateIndex(true);
427  binaryOp(retVal, op1, value, bf);
428  return retVal;
429 }
430 
431 template <class BinaryFunction> CoinPackedVector
432 binaryOp(double value, const CoinPackedVectorBase& op2,
433  BinaryFunction bf)
434 {
435  CoinPackedVector retVal;
436  retVal.setTestForDuplicateIndex(true);
437  binaryOp(retVal, op2, value, bf);
438  return retVal;
439 }
440 
441 template <class BinaryFunction> CoinPackedVector
443  BinaryFunction bf)
444 {
445  CoinPackedVector retVal;
446  retVal.setTestForDuplicateIndex(true);
447  binaryOp(retVal, op1, op2, bf);
448  return retVal;
449 }
450 
451 //-----------------------------------------------------------------------------
454  const CoinPackedVectorBase& op2)
455 {
456  CoinPackedVector retVal;
457  retVal.setTestForDuplicateIndex(true);
458  binaryOp(retVal, op1, op2, std::plus<double>());
459  return retVal;
460 }
461 
464  const CoinPackedVectorBase& op2)
465 {
466  CoinPackedVector retVal;
467  retVal.setTestForDuplicateIndex(true);
468  binaryOp(retVal, op1, op2, std::minus<double>());
469  return retVal;
470 }
471 
474  const CoinPackedVectorBase& op2)
475 {
476  CoinPackedVector retVal;
477  retVal.setTestForDuplicateIndex(true);
478  binaryOp(retVal, op1, op2, std::multiplies<double>());
479  return retVal;
480 }
481 
484  const CoinPackedVectorBase& op2)
485 {
486  CoinPackedVector retVal;
487  retVal.setTestForDuplicateIndex(true);
488  binaryOp(retVal, op1, op2, std::divides<double>());
489  return retVal;
490 }
492 
495 inline double sparseDotProduct(const CoinPackedVectorBase& op1,
496  const CoinPackedVectorBase& op2){
497  int len, i;
498  double acc = 0.0;
499  CoinPackedVector retVal;
500 
501  CoinPackedVector retval = op1*op2;
502  len = retval.getNumElements();
503  double * CParray = retval.getElements();
504 
505  for(i = 0; i < len; i++){
506  acc += CParray[i];
507  }
508 return acc;
509 }
510 
511 
515  const CoinPackedVectorBase& op2){
516  int i, j, len1, len2;
517  double acc = 0.0;
518 
519  const double* v1val = op1.getElements();
520  const double* v2val = op2.getElements();
521  const int* v1ind = op1.getIndices();
522  const int* v2ind = op2.getIndices();
523 
524  len1 = op1.getNumElements();
525  len2 = op2.getNumElements();
526 
527  i = 0;
528  j = 0;
529 
530  while(i < len1 && j < len2){
531  if(v1ind[i] == v2ind[j]){
532  acc += v1val[i] * v2val[j];
533  i++;
534  j++;
535  }
536  else if(v2ind[j] < v1ind[i]){
537  j++;
538  }
539  else{
540  i++;
541  } // end if-else-elseif
542  } // end while
543  return acc;
544  }
545 
546 
547 //-----------------------------------------------------------------------------
548 
554 inline CoinPackedVector
556 operator+(const CoinPackedVectorBase& op1, double value)
557 {
558  CoinPackedVector retVal(op1);
559  retVal += value;
560  return retVal;
561 }
562 
564 inline CoinPackedVector
565 operator-(const CoinPackedVectorBase& op1, double value)
566 {
567  CoinPackedVector retVal(op1);
568  retVal -= value;
569  return retVal;
570 }
571 
573 inline CoinPackedVector
574 operator*(const CoinPackedVectorBase& op1, double value)
575 {
576  CoinPackedVector retVal(op1);
577  retVal *= value;
578  return retVal;
579 }
580 
582 inline CoinPackedVector
583 operator/(const CoinPackedVectorBase& op1, double value)
584 {
585  CoinPackedVector retVal(op1);
586  retVal /= value;
587  return retVal;
588 }
589 
590 //-----------------------------------------------------------------------------
591 
593 inline CoinPackedVector
594 operator+(double value, const CoinPackedVectorBase& op1)
595 {
596  CoinPackedVector retVal(op1);
597  retVal += value;
598  return retVal;
599 }
600 
602 inline CoinPackedVector
603 operator-(double value, const CoinPackedVectorBase& op1)
604 {
605  CoinPackedVector retVal(op1);
606  const int size = retVal.getNumElements();
607  double* elems = retVal.getElements();
608  for (int i = 0; i < size; ++i) {
609  elems[i] = value - elems[i];
610  }
611  return retVal;
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 }
636 
637 //#############################################################################
643 void
645 
646 #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.
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
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 "index" 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:371
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:529
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'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...
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 operator/(const CoinPackedVectorBase &op1, const CoinPackedVectorBase &op2)
Return the element-wise ratio of two packed vectors.
CoinPackedVector(bool testForDuplicateIndex=COIN_DEFAULT_VALUE_FOR_DUPLICATE)
Default constructor.
void append(const CoinPackedVectorBase &caboose)
Append a CoinPackedVector to the end.
CoinPackedVector operator+(const CoinPackedVectorBase &op1, const CoinPackedVectorBase &op2)
Return the sum of two packed vectors.
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:382
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.
CoinPackedVector operator-(const CoinPackedVectorBase &op1, const CoinPackedVectorBase &op2)
Return the difference of two packed vectors.
CoinPackedVector operator*(const CoinPackedVectorBase &op1, const CoinPackedVectorBase &op2)
Return the element-wise product of two packed vectors.
int findIndex(int i) const
Return the position of the i'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.