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 
125  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 
146  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 
209  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 
304  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 
319  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 
555 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