Cbc  2.9.9
 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 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 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.
CoinDenseVector< T > operator*(const CoinDenseVector< T > &op1, const CoinDenseVector< T > &op2)
Return the element-wise product of two dense 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
CoinDenseVector< T > operator+(const CoinDenseVector< T > &op1, const CoinDenseVector< T > &op2)
Return the sum of two dense vectors.
CoinDenseVector< T > operator-(const CoinDenseVector< T > &op1, const CoinDenseVector< T > &op2)
Return the difference of two dense vectors.
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:489
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.
bool testForDuplicateIndex() const
Returns true if the vector should be tested for duplicate indices when they can occur.
CoinDenseVector< T > operator/(const CoinDenseVector< T > &op1, const CoinDenseVector< T > &op2)
Return the element-wise ratio of two dense vectors.
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.
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.
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:478
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:636
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.