CoinUtils 2.11.10
Loading...
Searching...
No Matches
CoinPackedVector.hpp
Go to the documentation of this file.
1/* $Id$ */
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"
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
125
126public:
130 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
157 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
220 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
250
256
262
268
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,
319
320private:
324 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
335private:
341 double *elements_;
349};
350
351//#############################################################################
352
368template < 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
385template < class BinaryFunction >
386inline void
388 double value, const CoinPackedVectorBase &op2,
389 BinaryFunction bf)
390{
391 binaryOp(retVal, op2, value, bf);
392}
393
394template < 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
442template < class BinaryFunction >
444binaryOp(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
453template < class BinaryFunction >
455binaryOp(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
464template < 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
519inline 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
577inline CoinPackedVector
578operator+(const CoinPackedVectorBase &op1, double value)
579{
580 CoinPackedVector retVal(op1);
581 retVal += value;
582 return retVal;
583}
584
586inline CoinPackedVector
587operator-(const CoinPackedVectorBase &op1, double value)
588{
589 CoinPackedVector retVal(op1);
590 retVal -= value;
591 return retVal;
592}
593
595inline CoinPackedVector
596operator*(const CoinPackedVectorBase &op1, double value)
597{
598 CoinPackedVector retVal(op1);
599 retVal *= value;
600 return retVal;
601}
602
604inline CoinPackedVector
605operator/(const CoinPackedVectorBase &op1, double value)
606{
607 CoinPackedVector retVal(op1);
608 retVal /= value;
609 return retVal;
610}
611
612//-----------------------------------------------------------------------------
613
615inline CoinPackedVector
616operator+(double value, const CoinPackedVectorBase &op1)
617{
618 CoinPackedVector retVal(op1);
619 retVal += value;
620 return retVal;
621}
622
624inline CoinPackedVector
625operator-(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
637inline CoinPackedVector
638operator*(double value, const CoinPackedVectorBase &op1)
639{
640 CoinPackedVector retVal(op1);
641 retVal *= value;
642 return retVal;
643}
644
646inline CoinPackedVector
647operator/(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*/
CoinPackedVector operator+(const CoinPackedVectorBase &op1, const CoinPackedVectorBase &op2)
Return the sum of two packed vectors.
CoinPackedVector operator/(const CoinPackedVectorBase &op1, const CoinPackedVectorBase &op2)
Return the element-wise ratio of two packed vectors.
void CoinPackedVectorUnitTest()
A function that tests the methods in the CoinPackedVector class.
void binaryOp(CoinPackedVector &retVal, const CoinPackedVectorBase &op1, double value, BinaryFunction bf)
CoinPackedVector operator*(const CoinPackedVectorBase &op1, const CoinPackedVectorBase &op2)
Return the element-wise product of two packed vectors.
#define COIN_DEFAULT_VALUE_FOR_DUPLICATE
double sparseDotProduct(const CoinPackedVectorBase &op1, const CoinPackedVectorBase &op2)
Returns the dot product of two CoinPackedVector objects whose elements are doubles.
CoinPackedVector operator-(const CoinPackedVectorBase &op1, const CoinPackedVectorBase &op2)
Return the difference of two packed vectors.
double sortedSparseDotProduct(const CoinPackedVectorBase &op1, const CoinPackedVectorBase &op2)
Returns the dot product of two sorted CoinPackedVector objects.
void CoinSort_3(S *sfirst, S *slast, T *tfirst, U *ufirst, const CoinCompare3 &tc)
Sort a triple of containers.
Definition CoinSort.hpp:709
Function operator.
Definition CoinSort.hpp:547
Function operator.
Definition CoinSort.hpp:534
Abstract base class for various sparse vectors.
bool testForDuplicateIndex() const
Returns true if the vector should be tested for duplicate indices when they can occur.
int findIndex(int i) const
Return the position of the i'th element of the full storage vector.
virtual int getNumElements() const =0
Get length of indices and elements vectors.
bool isExistingIndex(int i) const
Return true if the i'th element of the full storage vector exists in the packed storage vector.
virtual const double * getElements() const =0
Get element values.
virtual const int * getIndices() const =0
Get indices of elements.
void setTestForDuplicateIndex(bool test) const
Set to the argument value whether to test for duplicate indices in the vector whenever they can occur...
void clear()
Reset the vector (as if were just created an empty vector)
virtual const int * getIndices() const
Get indices of elements.
CoinPackedVector(int size, const int *inds, double element, bool testForDuplicateIndex=COIN_DEFAULT_VALUE_FOR_DUPLICATE)
Alternate Constructors - set elements to same scalar value.
int getVectorNumElements() const
Get the size.
void setVector(int size, const int *inds, const double *elems, bool testForDuplicateIndex=COIN_DEFAULT_VALUE_FOR_DUPLICATE)
Set vector size, indices, and elements.
void append(const CoinPackedVectorBase &caboose)
Append a CoinPackedVector to the end.
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
double * elements_
Vector elements.
int * origIndices_
original unsorted indices
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.
const int * getVectorIndices() 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.
CoinPackedVector(const CoinPackedVectorBase &rhs)
Copy constructor from a PackedVectorBase.
void insert(int index, double element)
Insert an element into the vector.
int capacity_
Amount of memory allocated for indices_, origIndices_, and elements_.
void operator-=(double value)
subtract value from every entry
int * getIndices()
Get indices of elements.
int nElements_
Size of indices and elements vectors.
int capacity() const
capacity returns the size which could be accomodated without having to reallocate storage.
double * getElements()
Get element values.
CoinPackedVector(bool testForDuplicateIndex=COIN_DEFAULT_VALUE_FOR_DUPLICATE)
Default constructor.
void sort(const CoinCompare3 &tc)
Sort the packed storage vector.
CoinPackedVector(int capacity, int size, int *&inds, double *&elems, bool testForDuplicateIndex=COIN_DEFAULT_VALUE_FOR_DUPLICATE)
Alternate Constructors - set elements to vector of doubles.
friend void CoinPackedVectorUnitTest()
A function that tests the methods in the CoinPackedVector class.
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 swap(int i, int j)
Swap values in positions i and j of indices and elements.
CoinPackedVector & operator=(const CoinPackedVector &)
Assignment operator.
void operator/=(double value)
divide every entry by value
void truncate(int newSize)
Resize the packed vector to be the first newSize elements.
CoinPackedVector & operator=(const CoinPackedVectorBase &rhs)
Assignment operator from a CoinPackedVectorBase.
int * indices_
Vector indices.
virtual ~CoinPackedVector()
Destructor.
void gutsOfSetConstant(int size, const int *inds, double value, bool testForDuplicateIndex, const char *method)
virtual const double * getElements() const
Get element values.
const double * getVectorElements() const
Get element values.
CoinPackedVector(const CoinPackedVector &)
Copy constructor.
void gutsOfSetVector(int size, const int *inds, const double *elems, bool testForDuplicateIndex, const char *method)
Copy internal date.
virtual int getNumElements() const
Get the size.
void sortOriginalOrder()
Sort in original order.
const int * getOriginalPosition() const
Get pointer to int * vector of original postions.
void reserve(int n)
Reserve space.
void operator+=(double value)
add value to every entry
void assignVector(int size, int *&inds, double *&elems, bool testForDuplicateIndex=COIN_DEFAULT_VALUE_FOR_DUPLICATE)
Assign the ownership of the arguments to this vector.
CoinPackedVector(int size, const double *elements, bool testForDuplicateIndex=COIN_DEFAULT_VALUE_FOR_DUPLICATE)
Alternate Constructors - construct full storage with indices 0 through size-1.
CoinPackedVector(int size, const int *inds, const double *elems, bool testForDuplicateIndex=COIN_DEFAULT_VALUE_FOR_DUPLICATE)
Alternate Constructors - set elements to vector of doubles.