00001
00002
00003 #ifndef CoinPackedVector_H
00004 #define CoinPackedVector_H
00005
00006 #if defined(_MSC_VER)
00007
00008 # pragma warning(disable:4786)
00009 #endif
00010
00011 #include <map>
00012
00013 #include "CoinPackedVectorBase.hpp"
00014 #include "CoinSort.hpp"
00015 #ifndef COIN_NOTEST_DUPLICATE
00016 #define COIN_DEFAULT_VALUE_FOR_DUPLICATE true
00017 #else
00018 #define COIN_DEFAULT_VALUE_FOR_DUPLICATE false
00019 #endif
00020
00117 class CoinPackedVector : public CoinPackedVectorBase {
00118 friend void CoinPackedVectorUnitTest();
00119
00120 public:
00123
00124 virtual int getNumElements() const { return nElements_; }
00126 virtual const int * getIndices() const { return indices_; }
00128 virtual const double * getElements() const { return elements_; }
00130 int * getIndices() { return indices_; }
00132 double * getElements() { return elements_; }
00136 const int * getOriginalPosition() const { return origIndices_; }
00138
00139
00140
00141
00144
00145 void clear();
00150 CoinPackedVector & operator=(const CoinPackedVector &);
00155 CoinPackedVector & operator=(const CoinPackedVectorBase & rhs);
00156
00163 void assignVector(int size, int*& inds, double*& elems,
00164 bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
00165
00171 void setVector(int size, const int * inds, const double * elems,
00172 bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
00173
00175 void setConstant(int size, const int * inds, double elems,
00176 bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
00177
00179 void setFull(int size, const double * elems,
00180 bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
00181
00184 void setFullNonZero(int size, const double * elems,
00185 bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
00186
00190 void setElement(int index, double element);
00191
00193 void insert(int index, double element);
00195 void append(const CoinPackedVectorBase & caboose);
00196
00198 void swap(int i, int j);
00199
00202 void truncate(int newSize);
00204
00207
00208 void operator+=(double value);
00210 void operator-=(double value);
00212 void operator*=(double value);
00214 void operator/=(double value);
00216
00226 template <class CoinCompare3>
00227 void sort(const CoinCompare3 & tc)
00228 { CoinSort_3(indices_, indices_ + nElements_, origIndices_, elements_,
00229 tc); }
00230
00231 void sortIncrIndex()
00232 { CoinSort_3(indices_, indices_ + nElements_, origIndices_, elements_,
00233 CoinFirstLess_3<int, int, double>()); }
00234
00235 void sortDecrIndex()
00236 { CoinSort_3(indices_, indices_ + nElements_, origIndices_, elements_,
00237 CoinFirstGreater_3<int, int, double>()); }
00238
00239 void sortIncrElement()
00240 { CoinSort_3(elements_, elements_ + nElements_, origIndices_, indices_,
00241 CoinFirstLess_3<double, int, int>()); }
00242
00243 void sortDecrElement()
00244 { CoinSort_3(elements_, elements_ + nElements_, origIndices_, indices_,
00245 CoinFirstGreater_3<double, int, int>()); }
00246
00247
00252 void sortOriginalOrder();
00254
00261 void reserve(int n);
00265 int capacity() const { return capacity_; }
00267
00270 CoinPackedVector(bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
00275 CoinPackedVector(int size, const int * inds, const double * elems,
00276 bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
00282 CoinPackedVector(int capacity, int size, int *&inds, double *&elems,
00283 bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
00285 CoinPackedVector(int size, const int * inds, double element,
00286 bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
00289 CoinPackedVector(int size, const double * elements,
00290 bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
00292 CoinPackedVector(const CoinPackedVector &);
00294 CoinPackedVector(const CoinPackedVectorBase & rhs);
00296 virtual ~CoinPackedVector ();
00298
00299 private:
00302
00303 void gutsOfSetVector(int size,
00304 const int * inds, const double * elems,
00305 bool testForDuplicateIndex,
00306 const char * method);
00308 void gutsOfSetConstant(int size,
00309 const int * inds, double value,
00310 bool testForDuplicateIndex,
00311 const char * method);
00313
00314 private:
00317
00318 int * indices_;
00320 double * elements_;
00322 int nElements_;
00324 int * origIndices_;
00326 int capacity_;
00328 };
00329
00330
00331
00347 template <class BinaryFunction> void
00348 binaryOp(CoinPackedVector& retVal,
00349 const CoinPackedVectorBase& op1, double value,
00350 BinaryFunction bf)
00351 {
00352 retVal.clear();
00353 const int s = op1.getNumElements();
00354 if (s > 0) {
00355 retVal.reserve(s);
00356 const int * inds = op1.getIndices();
00357 const double * elems = op1.getElements();
00358 for (int i=0; i<s; ++i ) {
00359 retVal.insert(inds[i], bf(value, elems[i]));
00360 }
00361 }
00362 }
00363
00364 template <class BinaryFunction> inline void
00365 binaryOp(CoinPackedVector& retVal,
00366 double value, const CoinPackedVectorBase& op2,
00367 BinaryFunction bf)
00368 {
00369 binaryOp(retVal, op2, value, bf);
00370 }
00371
00372 template <class BinaryFunction> void
00373 binaryOp(CoinPackedVector& retVal,
00374 const CoinPackedVectorBase& op1, const CoinPackedVectorBase& op2,
00375 BinaryFunction bf)
00376 {
00377 retVal.clear();
00378 const int s1 = op1.getNumElements();
00379 const int s2 = op2.getNumElements();
00380
00381
00382
00383
00384
00385
00386 if (s1 == 0 && s2 == 0)
00387 return;
00388
00389 retVal.reserve(s1+s2);
00390
00391 const int * inds1 = op1.getIndices();
00392 const double * elems1 = op1.getElements();
00393 const int * inds2 = op2.getIndices();
00394 const double * elems2 = op2.getElements();
00395
00396 int i;
00397
00398 for ( i=0; i<s1; ++i ) {
00399 const int index = inds1[i];
00400 const int pos2 = op2.findIndex(index);
00401 const double val = bf(elems1[i], pos2 == -1 ? 0.0 : elems2[pos2]);
00402
00403 retVal.insert(index, val);
00404 }
00405
00406 for ( i=0; i<s2; ++i ) {
00407 const int index = inds2[i];
00408
00409 if ( op1.isExistingIndex(index) )
00410 continue;
00411
00412 const double val = bf(0.0, elems2[i]);
00413
00414 retVal.insert(index, val);
00415 }
00416 }
00417
00418
00419
00420 template <class BinaryFunction> CoinPackedVector
00421 binaryOp(const CoinPackedVectorBase& op1, double value,
00422 BinaryFunction bf)
00423 {
00424 CoinPackedVector retVal;
00425 retVal.setTestForDuplicateIndex(true);
00426 binaryOp(retVal, op1, value, bf);
00427 return retVal;
00428 }
00429
00430 template <class BinaryFunction> CoinPackedVector
00431 binaryOp(double value, const CoinPackedVectorBase& op2,
00432 BinaryFunction bf)
00433 {
00434 CoinPackedVector retVal;
00435 retVal.setTestForDuplicateIndex(true);
00436 binaryOp(retVal, op2, value, bf);
00437 return retVal;
00438 }
00439
00440 template <class BinaryFunction> CoinPackedVector
00441 binaryOp(const CoinPackedVectorBase& op1, const CoinPackedVectorBase& op2,
00442 BinaryFunction bf)
00443 {
00444 CoinPackedVector retVal;
00445 retVal.setTestForDuplicateIndex(true);
00446 binaryOp(retVal, op1, op2, bf);
00447 return retVal;
00448 }
00449
00450
00452 inline CoinPackedVector operator+(const CoinPackedVectorBase& op1,
00453 const CoinPackedVectorBase& op2)
00454 {
00455 CoinPackedVector retVal;
00456 retVal.setTestForDuplicateIndex(true);
00457 binaryOp(retVal, op1, op2, std::plus<double>());
00458 return retVal;
00459 }
00460
00462 inline CoinPackedVector operator-(const CoinPackedVectorBase& op1,
00463 const CoinPackedVectorBase& op2)
00464 {
00465 CoinPackedVector retVal;
00466 retVal.setTestForDuplicateIndex(true);
00467 binaryOp(retVal, op1, op2, std::minus<double>());
00468 return retVal;
00469 }
00470
00472 inline CoinPackedVector operator*(const CoinPackedVectorBase& op1,
00473 const CoinPackedVectorBase& op2)
00474 {
00475 CoinPackedVector retVal;
00476 retVal.setTestForDuplicateIndex(true);
00477 binaryOp(retVal, op1, op2, std::multiplies<double>());
00478 return retVal;
00479 }
00480
00482 inline CoinPackedVector operator/(const CoinPackedVectorBase& op1,
00483 const CoinPackedVectorBase& op2)
00484 {
00485 CoinPackedVector retVal;
00486 retVal.setTestForDuplicateIndex(true);
00487 binaryOp(retVal, op1, op2, std::divides<double>());
00488 return retVal;
00489 }
00491
00494 inline double sparseDotProduct(const CoinPackedVectorBase& op1,
00495 const CoinPackedVectorBase& op2){
00496 int len, i;
00497 double acc = 0.0;
00498 CoinPackedVector retVal;
00499
00500 CoinPackedVector retval = op1*op2;
00501 len = retval.getNumElements();
00502 double * CParray = retval.getElements();
00503
00504 for(i = 0; i < len; i++){
00505 acc += CParray[i];
00506 }
00507 return acc;
00508 }
00509
00510
00513 inline double sortedSparseDotProduct(const CoinPackedVectorBase& op1,
00514 const CoinPackedVectorBase& op2){
00515 int i, j, len1, len2;
00516 double acc = 0.0;
00517
00518 const double* v1val = op1.getElements();
00519 const double* v2val = op2.getElements();
00520 const int* v1ind = op1.getIndices();
00521 const int* v2ind = op2.getIndices();
00522
00523 len1 = op1.getNumElements();
00524 len2 = op2.getNumElements();
00525
00526 i = 0;
00527 j = 0;
00528
00529 while(i < len1 && j < len2){
00530 if(v1ind[i] == v2ind[j]){
00531 acc += v1val[i] * v2val[j];
00532 i++;
00533 j++;
00534 }
00535 else if(v2ind[j] < v1ind[i]){
00536 j++;
00537 }
00538 else{
00539 i++;
00540 }
00541 }
00542 return acc;
00543 }
00544
00545
00546
00547
00553
00554 inline CoinPackedVector
00555 operator+(const CoinPackedVectorBase& op1, double value)
00556 {
00557 CoinPackedVector retVal(op1);
00558 retVal += value;
00559 return retVal;
00560 }
00561
00563 inline CoinPackedVector
00564 operator-(const CoinPackedVectorBase& op1, double value)
00565 {
00566 CoinPackedVector retVal(op1);
00567 retVal -= value;
00568 return retVal;
00569 }
00570
00572 inline CoinPackedVector
00573 operator*(const CoinPackedVectorBase& op1, double value)
00574 {
00575 CoinPackedVector retVal(op1);
00576 retVal *= value;
00577 return retVal;
00578 }
00579
00581 inline CoinPackedVector
00582 operator/(const CoinPackedVectorBase& op1, double value)
00583 {
00584 CoinPackedVector retVal(op1);
00585 retVal /= value;
00586 return retVal;
00587 }
00588
00589
00590
00592 inline CoinPackedVector
00593 operator+(double value, const CoinPackedVectorBase& op1)
00594 {
00595 CoinPackedVector retVal(op1);
00596 retVal += value;
00597 return retVal;
00598 }
00599
00601 inline CoinPackedVector
00602 operator-(double value, const CoinPackedVectorBase& op1)
00603 {
00604 CoinPackedVector retVal(op1);
00605 const int size = retVal.getNumElements();
00606 double* elems = retVal.getElements();
00607 for (int i = 0; i < size; ++i) {
00608 elems[i] = value - elems[i];
00609 }
00610 return retVal;
00611 }
00612
00614 inline CoinPackedVector
00615 operator*(double value, const CoinPackedVectorBase& op1)
00616 {
00617 CoinPackedVector retVal(op1);
00618 retVal *= value;
00619 return retVal;
00620 }
00621
00623 inline CoinPackedVector
00624 operator/(double value, const CoinPackedVectorBase& op1)
00625 {
00626 CoinPackedVector retVal(op1);
00627 const int size = retVal.getNumElements();
00628 double* elems = retVal.getElements();
00629 for (int i = 0; i < size; ++i) {
00630 elems[i] = value / elems[i];
00631 }
00632 return retVal;
00633 }
00635
00636
00642 void
00643 CoinPackedVectorUnitTest();
00644
00645 #endif