00001
00002
00003
00004
00005
00006 #ifndef CoinPackedVector_H
00007 #define CoinPackedVector_H
00008
00009 #include <map>
00010
00011 #include "CoinPragma.hpp"
00012 #include "CoinPackedVectorBase.hpp"
00013 #include "CoinSort.hpp"
00014
00015 #ifdef COIN_FAST_CODE
00016 #ifndef COIN_NOTEST_DUPLICATE
00017 #define COIN_NOTEST_DUPLICATE
00018 #endif
00019 #endif
00020
00021 #ifndef COIN_NOTEST_DUPLICATE
00022 #define COIN_DEFAULT_VALUE_FOR_DUPLICATE true
00023 #else
00024 #define COIN_DEFAULT_VALUE_FOR_DUPLICATE false
00025 #endif
00026
00123 class CoinPackedVector : public CoinPackedVectorBase {
00124 friend void CoinPackedVectorUnitTest();
00125
00126 public:
00129
00130 virtual int getNumElements() const { return nElements_; }
00132 virtual const int * getIndices() const { return indices_; }
00134 virtual const double * getElements() const { return elements_; }
00136 int * getIndices() { return indices_; }
00138 inline int getVectorNumElements() const { return nElements_; }
00140 inline const int * getVectorIndices() const { return indices_; }
00142 inline const double * getVectorElements() const { return elements_; }
00144 double * getElements() { return elements_; }
00148 const int * getOriginalPosition() const { return origIndices_; }
00150
00151
00152
00153
00156
00157 void clear();
00162 CoinPackedVector & operator=(const CoinPackedVector &);
00167 CoinPackedVector & operator=(const CoinPackedVectorBase & rhs);
00168
00175 void assignVector(int size, int*& inds, double*& elems,
00176 bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
00177
00183 void setVector(int size, const int * inds, const double * elems,
00184 bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
00185
00187 void setConstant(int size, const int * inds, double elems,
00188 bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
00189
00191 void setFull(int size, const double * elems,
00192 bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
00193
00196 void setFullNonZero(int size, const double * elems,
00197 bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
00198
00202 void setElement(int index, double element);
00203
00205 void insert(int index, double element);
00207 void append(const CoinPackedVectorBase & caboose);
00208
00210 void swap(int i, int j);
00211
00214 void truncate(int newSize);
00216
00219
00220 void operator+=(double value);
00222 void operator-=(double value);
00224 void operator*=(double value);
00226 void operator/=(double value);
00228
00238 template <class CoinCompare3>
00239 void sort(const CoinCompare3 & tc)
00240 { CoinSort_3(indices_, indices_ + nElements_, origIndices_, elements_,
00241 tc); }
00242
00243 void sortIncrIndex()
00244 { CoinSort_3(indices_, indices_ + nElements_, origIndices_, elements_,
00245 CoinFirstLess_3<int, int, double>()); }
00246
00247 void sortDecrIndex()
00248 { CoinSort_3(indices_, indices_ + nElements_, origIndices_, elements_,
00249 CoinFirstGreater_3<int, int, double>()); }
00250
00251 void sortIncrElement()
00252 { CoinSort_3(elements_, elements_ + nElements_, origIndices_, indices_,
00253 CoinFirstLess_3<double, int, int>()); }
00254
00255 void sortDecrElement()
00256 { CoinSort_3(elements_, elements_ + nElements_, origIndices_, indices_,
00257 CoinFirstGreater_3<double, int, int>()); }
00258
00259
00264 void sortOriginalOrder();
00266
00273 void reserve(int n);
00277 int capacity() const { return capacity_; }
00279
00282 CoinPackedVector(bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
00287 CoinPackedVector(int size, const int * inds, const double * elems,
00288 bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
00294 CoinPackedVector(int capacity, int size, int *&inds, double *&elems,
00295 bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
00297 CoinPackedVector(int size, const int * inds, double element,
00298 bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
00301 CoinPackedVector(int size, const double * elements,
00302 bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
00304 CoinPackedVector(const CoinPackedVector &);
00306 CoinPackedVector(const CoinPackedVectorBase & rhs);
00308 virtual ~CoinPackedVector ();
00310
00311 private:
00314
00315 void gutsOfSetVector(int size,
00316 const int * inds, const double * elems,
00317 bool testForDuplicateIndex,
00318 const char * method);
00320 void gutsOfSetConstant(int size,
00321 const int * inds, double value,
00322 bool testForDuplicateIndex,
00323 const char * method);
00325
00326 private:
00329
00330 int * indices_;
00332 double * elements_;
00334 int nElements_;
00336 int * origIndices_;
00338 int capacity_;
00340 };
00341
00342
00343
00359 template <class BinaryFunction> void
00360 binaryOp(CoinPackedVector& retVal,
00361 const CoinPackedVectorBase& op1, double value,
00362 BinaryFunction bf)
00363 {
00364 retVal.clear();
00365 const int s = op1.getNumElements();
00366 if (s > 0) {
00367 retVal.reserve(s);
00368 const int * inds = op1.getIndices();
00369 const double * elems = op1.getElements();
00370 for (int i=0; i<s; ++i ) {
00371 retVal.insert(inds[i], bf(value, elems[i]));
00372 }
00373 }
00374 }
00375
00376 template <class BinaryFunction> inline void
00377 binaryOp(CoinPackedVector& retVal,
00378 double value, const CoinPackedVectorBase& op2,
00379 BinaryFunction bf)
00380 {
00381 binaryOp(retVal, op2, value, bf);
00382 }
00383
00384 template <class BinaryFunction> void
00385 binaryOp(CoinPackedVector& retVal,
00386 const CoinPackedVectorBase& op1, const CoinPackedVectorBase& op2,
00387 BinaryFunction bf)
00388 {
00389 retVal.clear();
00390 const int s1 = op1.getNumElements();
00391 const int s2 = op2.getNumElements();
00392
00393
00394
00395
00396
00397
00398 if (s1 == 0 && s2 == 0)
00399 return;
00400
00401 retVal.reserve(s1+s2);
00402
00403 const int * inds1 = op1.getIndices();
00404 const double * elems1 = op1.getElements();
00405 const int * inds2 = op2.getIndices();
00406 const double * elems2 = op2.getElements();
00407
00408 int i;
00409
00410 for ( i=0; i<s1; ++i ) {
00411 const int index = inds1[i];
00412 const int pos2 = op2.findIndex(index);
00413 const double val = bf(elems1[i], pos2 == -1 ? 0.0 : elems2[pos2]);
00414
00415 retVal.insert(index, val);
00416 }
00417
00418 for ( i=0; i<s2; ++i ) {
00419 const int index = inds2[i];
00420
00421 if ( op1.isExistingIndex(index) )
00422 continue;
00423
00424 const double val = bf(0.0, elems2[i]);
00425
00426 retVal.insert(index, val);
00427 }
00428 }
00429
00430
00431
00432 template <class BinaryFunction> CoinPackedVector
00433 binaryOp(const CoinPackedVectorBase& op1, double value,
00434 BinaryFunction bf)
00435 {
00436 CoinPackedVector retVal;
00437 retVal.setTestForDuplicateIndex(true);
00438 binaryOp(retVal, op1, value, bf);
00439 return retVal;
00440 }
00441
00442 template <class BinaryFunction> CoinPackedVector
00443 binaryOp(double value, const CoinPackedVectorBase& op2,
00444 BinaryFunction bf)
00445 {
00446 CoinPackedVector retVal;
00447 retVal.setTestForDuplicateIndex(true);
00448 binaryOp(retVal, op2, value, bf);
00449 return retVal;
00450 }
00451
00452 template <class BinaryFunction> CoinPackedVector
00453 binaryOp(const CoinPackedVectorBase& op1, const CoinPackedVectorBase& op2,
00454 BinaryFunction bf)
00455 {
00456 CoinPackedVector retVal;
00457 retVal.setTestForDuplicateIndex(true);
00458 binaryOp(retVal, op1, op2, bf);
00459 return retVal;
00460 }
00461
00462
00464 inline CoinPackedVector operator+(const CoinPackedVectorBase& op1,
00465 const CoinPackedVectorBase& op2)
00466 {
00467 CoinPackedVector retVal;
00468 retVal.setTestForDuplicateIndex(true);
00469 binaryOp(retVal, op1, op2, std::plus<double>());
00470 return retVal;
00471 }
00472
00474 inline CoinPackedVector operator-(const CoinPackedVectorBase& op1,
00475 const CoinPackedVectorBase& op2)
00476 {
00477 CoinPackedVector retVal;
00478 retVal.setTestForDuplicateIndex(true);
00479 binaryOp(retVal, op1, op2, std::minus<double>());
00480 return retVal;
00481 }
00482
00484 inline CoinPackedVector operator*(const CoinPackedVectorBase& op1,
00485 const CoinPackedVectorBase& op2)
00486 {
00487 CoinPackedVector retVal;
00488 retVal.setTestForDuplicateIndex(true);
00489 binaryOp(retVal, op1, op2, std::multiplies<double>());
00490 return retVal;
00491 }
00492
00494 inline CoinPackedVector operator/(const CoinPackedVectorBase& op1,
00495 const CoinPackedVectorBase& op2)
00496 {
00497 CoinPackedVector retVal;
00498 retVal.setTestForDuplicateIndex(true);
00499 binaryOp(retVal, op1, op2, std::divides<double>());
00500 return retVal;
00501 }
00503
00506 inline double sparseDotProduct(const CoinPackedVectorBase& op1,
00507 const CoinPackedVectorBase& op2){
00508 int len, i;
00509 double acc = 0.0;
00510 CoinPackedVector retVal;
00511
00512 CoinPackedVector retval = op1*op2;
00513 len = retval.getNumElements();
00514 double * CParray = retval.getElements();
00515
00516 for(i = 0; i < len; i++){
00517 acc += CParray[i];
00518 }
00519 return acc;
00520 }
00521
00522
00525 inline double sortedSparseDotProduct(const CoinPackedVectorBase& op1,
00526 const CoinPackedVectorBase& op2){
00527 int i, j, len1, len2;
00528 double acc = 0.0;
00529
00530 const double* v1val = op1.getElements();
00531 const double* v2val = op2.getElements();
00532 const int* v1ind = op1.getIndices();
00533 const int* v2ind = op2.getIndices();
00534
00535 len1 = op1.getNumElements();
00536 len2 = op2.getNumElements();
00537
00538 i = 0;
00539 j = 0;
00540
00541 while(i < len1 && j < len2){
00542 if(v1ind[i] == v2ind[j]){
00543 acc += v1val[i] * v2val[j];
00544 i++;
00545 j++;
00546 }
00547 else if(v2ind[j] < v1ind[i]){
00548 j++;
00549 }
00550 else{
00551 i++;
00552 }
00553 }
00554 return acc;
00555 }
00556
00557
00558
00559
00565
00566 inline CoinPackedVector
00567 operator+(const CoinPackedVectorBase& op1, double value)
00568 {
00569 CoinPackedVector retVal(op1);
00570 retVal += value;
00571 return retVal;
00572 }
00573
00575 inline CoinPackedVector
00576 operator-(const CoinPackedVectorBase& op1, double value)
00577 {
00578 CoinPackedVector retVal(op1);
00579 retVal -= value;
00580 return retVal;
00581 }
00582
00584 inline CoinPackedVector
00585 operator*(const CoinPackedVectorBase& op1, double value)
00586 {
00587 CoinPackedVector retVal(op1);
00588 retVal *= value;
00589 return retVal;
00590 }
00591
00593 inline CoinPackedVector
00594 operator/(const CoinPackedVectorBase& op1, double value)
00595 {
00596 CoinPackedVector retVal(op1);
00597 retVal /= value;
00598 return retVal;
00599 }
00600
00601
00602
00604 inline CoinPackedVector
00605 operator+(double value, const CoinPackedVectorBase& op1)
00606 {
00607 CoinPackedVector retVal(op1);
00608 retVal += value;
00609 return retVal;
00610 }
00611
00613 inline CoinPackedVector
00614 operator-(double value, const CoinPackedVectorBase& op1)
00615 {
00616 CoinPackedVector retVal(op1);
00617 const int size = retVal.getNumElements();
00618 double* elems = retVal.getElements();
00619 for (int i = 0; i < size; ++i) {
00620 elems[i] = value - elems[i];
00621 }
00622 return retVal;
00623 }
00624
00626 inline CoinPackedVector
00627 operator*(double value, const CoinPackedVectorBase& op1)
00628 {
00629 CoinPackedVector retVal(op1);
00630 retVal *= value;
00631 return retVal;
00632 }
00633
00635 inline CoinPackedVector
00636 operator/(double value, const CoinPackedVectorBase& op1)
00637 {
00638 CoinPackedVector retVal(op1);
00639 const int size = retVal.getNumElements();
00640 double* elems = retVal.getElements();
00641 for (int i = 0; i < size; ++i) {
00642 elems[i] = value / elems[i];
00643 }
00644 return retVal;
00645 }
00647
00648
00654 void
00655 CoinPackedVectorUnitTest();
00656
00657 #endif