00001
00002
00003
00004 #ifndef CoinPackedVector_H
00005 #define CoinPackedVector_H
00006
00007 #if defined(_MSC_VER)
00008
00009 # pragma warning(disable:4786)
00010 #endif
00011
00012 #include <map>
00013
00014 #include "CoinPackedVectorBase.hpp"
00015 #include "CoinSort.hpp"
00016 #ifndef COIN_NOTEST_DUPLICATE
00017 #define COIN_DEFAULT_VALUE_FOR_DUPLICATE true
00018 #else
00019 #define COIN_DEFAULT_VALUE_FOR_DUPLICATE false
00020 #endif
00021
00118 class CoinPackedVector : public CoinPackedVectorBase {
00119 friend void CoinPackedVectorUnitTest();
00120
00121 public:
00124
00125 virtual int getNumElements() const { return nElements_; }
00127 virtual const int * getIndices() const { return indices_; }
00129 virtual const double * getElements() const { return elements_; }
00131 int * getIndices() { return indices_; }
00133 double * getElements() { return elements_; }
00137 const int * getOriginalPosition() const { return origIndices_; }
00139
00140
00141
00142
00145
00146 void clear();
00151 CoinPackedVector & operator=(const CoinPackedVector &);
00156 CoinPackedVector & operator=(const CoinPackedVectorBase & rhs);
00157
00164 void assignVector(int size, int*& inds, double*& elems,
00165 bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
00166
00172 void setVector(int size, const int * inds, const double * elems,
00173 bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
00174
00176 void setConstant(int size, const int * inds, double elems,
00177 bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
00178
00180 void setFull(int size, const double * elems,
00181 bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
00182
00185 void setFullNonZero(int size, const double * elems,
00186 bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
00187
00191 void setElement(int index, double element);
00192
00194 void insert(int index, double element);
00196 void append(const CoinPackedVectorBase & caboose);
00197
00199 void swap(int i, int j);
00200
00203 void truncate(int newSize);
00205
00208
00209 void operator+=(double value);
00211 void operator-=(double value);
00213 void operator*=(double value);
00215 void operator/=(double value);
00217
00227 template <class CoinCompare3>
00228 void sort(const CoinCompare3 & tc)
00229 { CoinSort_3(indices_, indices_ + nElements_, origIndices_, elements_,
00230 tc); }
00231
00232 void sortIncrIndex()
00233 { CoinSort_3(indices_, indices_ + nElements_, origIndices_, elements_,
00234 CoinFirstLess_3<int, int, double>()); }
00235
00236 void sortDecrIndex()
00237 { CoinSort_3(indices_, indices_ + nElements_, origIndices_, elements_,
00238 CoinFirstGreater_3<int, int, double>()); }
00239
00240 void sortIncrElement()
00241 { CoinSort_3(elements_, elements_ + nElements_, origIndices_, indices_,
00242 CoinFirstLess_3<double, int, int>()); }
00243
00244 void sortDecrElement()
00245 { CoinSort_3(elements_, elements_ + nElements_, origIndices_, indices_,
00246 CoinFirstGreater_3<double, int, int>()); }
00247
00248
00253 void sortOriginalOrder();
00255
00262 void reserve(int n);
00266 int capacity() const { return capacity_; }
00268
00271 CoinPackedVector(bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
00276 CoinPackedVector(int size, const int * inds, const double * elems,
00277 bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
00283 CoinPackedVector(int capacity, int size, int *&inds, double *&elems,
00284 bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
00286 CoinPackedVector(int size, const int * inds, double element,
00287 bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
00290 CoinPackedVector(int size, const double * elements,
00291 bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
00293 CoinPackedVector(const CoinPackedVector &);
00295 CoinPackedVector(const CoinPackedVectorBase & rhs);
00297 virtual ~CoinPackedVector ();
00299
00300 private:
00303
00304 void gutsOfSetVector(int size,
00305 const int * inds, const double * elems,
00306 bool testForDuplicateIndex,
00307 const char * method);
00309 void gutsOfSetConstant(int size,
00310 const int * inds, double value,
00311 bool testForDuplicateIndex,
00312 const char * method);
00314
00315 private:
00318
00319 int * indices_;
00321 double * elements_;
00323 int nElements_;
00325 int * origIndices_;
00327 int capacity_;
00329 };
00330
00331
00332
00348 template <class BinaryFunction> void
00349 binaryOp(CoinPackedVector& retVal,
00350 const CoinPackedVectorBase& op1, double value,
00351 BinaryFunction bf)
00352 {
00353 retVal.clear();
00354 const int s = op1.getNumElements();
00355 if (s > 0) {
00356 retVal.reserve(s);
00357 const int * inds = op1.getIndices();
00358 const double * elems = op1.getElements();
00359 for (int i=0; i<s; ++i ) {
00360 retVal.insert(inds[i], bf(value, elems[i]));
00361 }
00362 }
00363 }
00364
00365 template <class BinaryFunction> inline void
00366 binaryOp(CoinPackedVector& retVal,
00367 double value, const CoinPackedVectorBase& op2,
00368 BinaryFunction bf)
00369 {
00370 binaryOp(retVal, op2, value, bf);
00371 }
00372
00373 template <class BinaryFunction> void
00374 binaryOp(CoinPackedVector& retVal,
00375 const CoinPackedVectorBase& op1, const CoinPackedVectorBase& op2,
00376 BinaryFunction bf)
00377 {
00378 retVal.clear();
00379 const int s1 = op1.getNumElements();
00380 const int s2 = op2.getNumElements();
00381
00382
00383
00384
00385
00386
00387 if (s1 == 0 && s2 == 0)
00388 return;
00389
00390 retVal.reserve(s1+s2);
00391
00392 const int * inds1 = op1.getIndices();
00393 const double * elems1 = op1.getElements();
00394 const int * inds2 = op2.getIndices();
00395 const double * elems2 = op2.getElements();
00396
00397 int i;
00398
00399 for ( i=0; i<s1; ++i ) {
00400 const int index = inds1[i];
00401 const int pos2 = op2.findIndex(index);
00402 const double val = bf(elems1[i], pos2 == -1 ? 0.0 : elems2[pos2]);
00403
00404 retVal.insert(index, val);
00405 }
00406
00407 for ( i=0; i<s2; ++i ) {
00408 const int index = inds2[i];
00409
00410 if ( op1.isExistingIndex(index) )
00411 continue;
00412
00413 const double val = bf(0.0, elems2[i]);
00414
00415 retVal.insert(index, val);
00416 }
00417 }
00418
00419
00420
00421 template <class BinaryFunction> CoinPackedVector
00422 binaryOp(const CoinPackedVectorBase& op1, double value,
00423 BinaryFunction bf)
00424 {
00425 CoinPackedVector retVal;
00426 retVal.setTestForDuplicateIndex(true);
00427 binaryOp(retVal, op1, value, bf);
00428 return retVal;
00429 }
00430
00431 template <class BinaryFunction> CoinPackedVector
00432 binaryOp(double value, const CoinPackedVectorBase& op2,
00433 BinaryFunction bf)
00434 {
00435 CoinPackedVector retVal;
00436 retVal.setTestForDuplicateIndex(true);
00437 binaryOp(retVal, op2, value, bf);
00438 return retVal;
00439 }
00440
00441 template <class BinaryFunction> CoinPackedVector
00442 binaryOp(const CoinPackedVectorBase& op1, const CoinPackedVectorBase& op2,
00443 BinaryFunction bf)
00444 {
00445 CoinPackedVector retVal;
00446 retVal.setTestForDuplicateIndex(true);
00447 binaryOp(retVal, op1, op2, bf);
00448 return retVal;
00449 }
00450
00451
00453 inline CoinPackedVector operator+(const CoinPackedVectorBase& op1,
00454 const CoinPackedVectorBase& op2)
00455 {
00456 CoinPackedVector retVal;
00457 retVal.setTestForDuplicateIndex(true);
00458 binaryOp(retVal, op1, op2, std::plus<double>());
00459 return retVal;
00460 }
00461
00463 inline CoinPackedVector operator-(const CoinPackedVectorBase& op1,
00464 const CoinPackedVectorBase& op2)
00465 {
00466 CoinPackedVector retVal;
00467 retVal.setTestForDuplicateIndex(true);
00468 binaryOp(retVal, op1, op2, std::minus<double>());
00469 return retVal;
00470 }
00471
00473 inline CoinPackedVector operator*(const CoinPackedVectorBase& op1,
00474 const CoinPackedVectorBase& op2)
00475 {
00476 CoinPackedVector retVal;
00477 retVal.setTestForDuplicateIndex(true);
00478 binaryOp(retVal, op1, op2, std::multiplies<double>());
00479 return retVal;
00480 }
00481
00483 inline CoinPackedVector operator/(const CoinPackedVectorBase& op1,
00484 const CoinPackedVectorBase& op2)
00485 {
00486 CoinPackedVector retVal;
00487 retVal.setTestForDuplicateIndex(true);
00488 binaryOp(retVal, op1, op2, std::divides<double>());
00489 return retVal;
00490 }
00492
00495 inline double sparseDotProduct(const CoinPackedVectorBase& op1,
00496 const CoinPackedVectorBase& op2){
00497 int len, i;
00498 double acc = 0.0;
00499 CoinPackedVector retVal;
00500
00501 CoinPackedVector retval = op1*op2;
00502 len = retval.getNumElements();
00503 double * CParray = retval.getElements();
00504
00505 for(i = 0; i < len; i++){
00506 acc += CParray[i];
00507 }
00508 return acc;
00509 }
00510
00511
00514 inline double sortedSparseDotProduct(const CoinPackedVectorBase& op1,
00515 const CoinPackedVectorBase& op2){
00516 int i, j, len1, len2;
00517 double acc = 0.0;
00518
00519 const double* v1val = op1.getElements();
00520 const double* v2val = op2.getElements();
00521 const int* v1ind = op1.getIndices();
00522 const int* v2ind = op2.getIndices();
00523
00524 len1 = op1.getNumElements();
00525 len2 = op2.getNumElements();
00526
00527 i = 0;
00528 j = 0;
00529
00530 while(i < len1 && j < len2){
00531 if(v1ind[i] == v2ind[j]){
00532 acc += v1val[i] * v2val[j];
00533 i++;
00534 j++;
00535 }
00536 else if(v2ind[j] < v1ind[i]){
00537 j++;
00538 }
00539 else{
00540 i++;
00541 }
00542 }
00543 return acc;
00544 }
00545
00546
00547
00548
00554
00555 inline CoinPackedVector
00556 operator+(const CoinPackedVectorBase& op1, double value)
00557 {
00558 CoinPackedVector retVal(op1);
00559 retVal += value;
00560 return retVal;
00561 }
00562
00564 inline CoinPackedVector
00565 operator-(const CoinPackedVectorBase& op1, double value)
00566 {
00567 CoinPackedVector retVal(op1);
00568 retVal -= value;
00569 return retVal;
00570 }
00571
00573 inline CoinPackedVector
00574 operator*(const CoinPackedVectorBase& op1, double value)
00575 {
00576 CoinPackedVector retVal(op1);
00577 retVal *= value;
00578 return retVal;
00579 }
00580
00582 inline CoinPackedVector
00583 operator/(const CoinPackedVectorBase& op1, double value)
00584 {
00585 CoinPackedVector retVal(op1);
00586 retVal /= value;
00587 return retVal;
00588 }
00589
00590
00591
00593 inline CoinPackedVector
00594 operator+(double value, const CoinPackedVectorBase& op1)
00595 {
00596 CoinPackedVector retVal(op1);
00597 retVal += value;
00598 return retVal;
00599 }
00600
00602 inline CoinPackedVector
00603 operator-(double value, const CoinPackedVectorBase& op1)
00604 {
00605 CoinPackedVector retVal(op1);
00606 const int size = retVal.getNumElements();
00607 double* elems = retVal.getElements();
00608 for (int i = 0; i < size; ++i) {
00609 elems[i] = value - elems[i];
00610 }
00611 return retVal;
00612 }
00613
00615 inline CoinPackedVector
00616 operator*(double value, const CoinPackedVectorBase& op1)
00617 {
00618 CoinPackedVector retVal(op1);
00619 retVal *= value;
00620 return retVal;
00621 }
00622
00624 inline CoinPackedVector
00625 operator/(double value, const CoinPackedVectorBase& op1)
00626 {
00627 CoinPackedVector retVal(op1);
00628 const int size = retVal.getNumElements();
00629 double* elems = retVal.getElements();
00630 for (int i = 0; i < size; ++i) {
00631 elems[i] = value / elems[i];
00632 }
00633 return retVal;
00634 }
00636
00637
00643 void
00644 CoinPackedVectorUnitTest();
00645
00646 #endif