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
00113 class CoinPackedVector : public CoinPackedVectorBase {
00114 friend void CoinPackedVectorUnitTest();
00115
00116 public:
00119
00120 virtual int getNumElements() const { return nElements_; }
00122 virtual const int * getIndices() const { return indices_; }
00124 virtual const double * getElements() const { return elements_; }
00126 int * getIndices() { return indices_; }
00128 double * getElements() { return elements_; }
00132 const int * getOriginalPosition() const { return origIndices_; }
00134
00135
00136
00137
00140
00141 void clear();
00146 CoinPackedVector & operator=(const CoinPackedVector &);
00151 CoinPackedVector & operator=(const CoinPackedVectorBase & rhs);
00152
00159 void assignVector(int size, int*& inds, double*& elems,
00160 bool testForDuplicateIndex = true);
00161
00167 void setVector(int size, const int * inds, const double * elems,
00168 bool testForDuplicateIndex = true) throw(CoinError);
00169
00171 void setConstant(int size, const int * inds, double elems,
00172 bool testForDuplicateIndex = true) throw(CoinError);
00173
00175 void setFull(int size, const double * elems,
00176 bool testForDuplicateIndex = true);
00177
00180 void setFullNonZero(int size, const double * elems,
00181 bool testForDuplicateIndex = true);
00182
00186 void setElement(int index, double element) throw(CoinError);
00187
00189 void insert(int index, double element) throw(CoinError);
00191 void append(const CoinPackedVectorBase & caboose) throw(CoinError);
00192
00194 void swap(int i, int j) throw(CoinError);
00195
00198 void truncate(int newSize) throw(CoinError);
00200
00203
00204 void operator+=(double value);
00206 void operator-=(double value);
00208 void operator*=(double value);
00210 void operator/=(double value);
00212
00222 template <class CoinCompare3>
00223 void sort(const CoinCompare3 & tc)
00224 { CoinSort_3(indices_, indices_ + nElements_, origIndices_, elements_,
00225 tc); }
00226
00227 void sortIncrIndex()
00228 { CoinSort_3(indices_, indices_ + nElements_, origIndices_, elements_,
00229 CoinFirstLess_3<int, int, double>()); }
00230
00231 void sortDecrIndex()
00232 { CoinSort_3(indices_, indices_ + nElements_, origIndices_, elements_,
00233 CoinFirstGreater_3<int, int, double>()); }
00234
00235 void sortIncrElement()
00236 { CoinSort_3(elements_, elements_ + nElements_, origIndices_, indices_,
00237 CoinFirstLess_3<double, int, int>()); }
00238
00239 void sortDecrElement()
00240 { CoinSort_3(elements_, elements_ + nElements_, origIndices_, indices_,
00241 CoinFirstGreater_3<double, int, int>()); }
00242
00243
00248 void sortOriginalOrder();
00250
00257 void reserve(int n);
00261 int capacity() const { return capacity_; }
00263
00267 CoinPackedVector(bool testForDuplicateIndex = true);
00269 CoinPackedVector(int size, const int * inds, const double * elems,
00270 bool testForDuplicateIndex = true);
00272 CoinPackedVector(int size, const int * inds, double element,
00273 bool testForDuplicateIndex = true);
00276 CoinPackedVector(int size, const double * elements,
00277 bool testForDuplicateIndex = true);
00279 CoinPackedVector(const CoinPackedVector &);
00281 CoinPackedVector(const CoinPackedVectorBase & rhs);
00283 virtual ~CoinPackedVector ();
00285
00286 private:
00289
00290 void gutsOfSetVector(int size,
00291 const int * inds, const double * elems,
00292 bool testForDuplicateIndex,
00293 const char * method);
00295 void gutsOfSetConstant(int size,
00296 const int * inds, double value,
00297 bool testForDuplicateIndex,
00298 const char * method);
00300
00301 private:
00304
00305 int * indices_;
00307 double * elements_;
00309 int nElements_;
00311 int * origIndices_;
00313 int capacity_;
00315 };
00316
00317
00318
00334 template <class BinaryFunction> void
00335 binaryOp(CoinPackedVector& retVal,
00336 const CoinPackedVectorBase& op1, double value,
00337 BinaryFunction bf)
00338 {
00339 retVal.clear();
00340 const int s = op1.getNumElements();
00341 if (s > 0) {
00342 retVal.reserve(s);
00343 const int * inds = op1.getIndices();
00344 const double * elems = op1.getElements();
00345 for (int i=0; i<s; ++i ) {
00346 retVal.insert(inds[i], bf(value, elems[i]));
00347 }
00348 }
00349 }
00350
00351 template <class BinaryFunction> inline void
00352 binaryOp(CoinPackedVector& retVal,
00353 double value, const CoinPackedVectorBase& op2,
00354 BinaryFunction bf)
00355 {
00356 binaryOp(retVal, op2, value, bf);
00357 }
00358
00359 template <class BinaryFunction> void
00360 binaryOp(CoinPackedVector& retVal,
00361 const CoinPackedVectorBase& op1, const CoinPackedVectorBase& op2,
00362 BinaryFunction bf)
00363 {
00364 retVal.clear();
00365 const int s1 = op1.getNumElements();
00366 const int s2 = op2.getNumElements();
00367 if (s1 == 0 || s2 == 0)
00368 return;
00369
00370 retVal.reserve(s1+s2);
00371
00372 const int * inds1 = op1.getIndices();
00373 const double * elems1 = op1.getElements();
00374 const int * inds2 = op2.getIndices();
00375 const double * elems2 = op2.getElements();
00376
00377 int i;
00378
00379 for ( i=0; i<s1; ++i ) {
00380 const int index = inds1[i];
00381 const int pos2 = op2.findIndex(index);
00382 const double val = bf(elems1[i], pos2 == -1 ? 0.0 : elems2[pos2]);
00383
00384 retVal.insert(index, val);
00385 }
00386
00387 for ( i=0; i<s2; ++i ) {
00388 const int index = inds2[i];
00389
00390 if ( op1.isExistingIndex(index) )
00391 continue;
00392
00393 const double val = bf(0.0, elems2[i]);
00394
00395 retVal.insert(index, val);
00396 }
00397 }
00398
00399
00400
00401 template <class BinaryFunction> CoinPackedVector
00402 binaryOp(const CoinPackedVectorBase& op1, double value,
00403 BinaryFunction bf)
00404 {
00405 CoinPackedVector retVal;
00406 retVal.setTestForDuplicateIndex(true);
00407 binaryOp(retVal, op1, value, bf);
00408 return retVal;
00409 }
00410
00411 template <class BinaryFunction> CoinPackedVector
00412 binaryOp(double value, const CoinPackedVectorBase& op2,
00413 BinaryFunction bf)
00414 {
00415 CoinPackedVector retVal;
00416 retVal.setTestForDuplicateIndex(true);
00417 binaryOp(retVal, op2, value, bf);
00418 return retVal;
00419 }
00420
00421 template <class BinaryFunction> CoinPackedVector
00422 binaryOp(const CoinPackedVectorBase& op1, const CoinPackedVectorBase& op2,
00423 BinaryFunction bf)
00424 {
00425 CoinPackedVector retVal;
00426 retVal.setTestForDuplicateIndex(true);
00427 binaryOp(retVal, op1, op2, bf);
00428 return retVal;
00429 }
00430
00431
00433 inline CoinPackedVector operator+(const CoinPackedVectorBase& op1,
00434 const CoinPackedVectorBase& op2)
00435 {
00436 CoinPackedVector retVal;
00437 retVal.setTestForDuplicateIndex(true);
00438 binaryOp(retVal, op1, op2, std::plus<double>());
00439 return retVal;
00440 }
00441
00443 inline CoinPackedVector operator-(const CoinPackedVectorBase& op1,
00444 const CoinPackedVectorBase& op2)
00445 {
00446 CoinPackedVector retVal;
00447 retVal.setTestForDuplicateIndex(true);
00448 binaryOp(retVal, op1, op2, std::minus<double>());
00449 return retVal;
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::multiplies<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::divides<double>());
00469 return retVal;
00470 }
00472
00473
00474
00480
00481 inline CoinPackedVector
00482 operator+(const CoinPackedVectorBase& op1, double value)
00483 {
00484 CoinPackedVector retVal(op1);
00485 retVal += value;
00486 return retVal;
00487 }
00488
00490 inline CoinPackedVector
00491 operator-(const CoinPackedVectorBase& op1, double value)
00492 {
00493 CoinPackedVector retVal(op1);
00494 retVal -= value;
00495 return retVal;
00496 }
00497
00499 inline CoinPackedVector
00500 operator*(const CoinPackedVectorBase& op1, double value)
00501 {
00502 CoinPackedVector retVal(op1);
00503 retVal *= value;
00504 return retVal;
00505 }
00506
00508 inline CoinPackedVector
00509 operator/(const CoinPackedVectorBase& op1, double value)
00510 {
00511 CoinPackedVector retVal(op1);
00512 retVal /= value;
00513 return retVal;
00514 }
00515
00516
00517
00519 inline CoinPackedVector
00520 operator+(double value, const CoinPackedVectorBase& op1)
00521 {
00522 CoinPackedVector retVal(op1);
00523 retVal += value;
00524 return retVal;
00525 }
00526
00528 inline CoinPackedVector
00529 operator-(double value, const CoinPackedVectorBase& op1)
00530 {
00531 CoinPackedVector retVal(op1);
00532 retVal -= value;
00533 return retVal;
00534 }
00535
00537 inline CoinPackedVector
00538 operator*(double value, const CoinPackedVectorBase& op1)
00539 {
00540 CoinPackedVector retVal(op1);
00541 retVal *= value;
00542 return retVal;
00543 }
00544
00546 inline CoinPackedVector
00547 operator/(double value, const CoinPackedVectorBase& op1)
00548 {
00549 CoinPackedVector retVal(op1);
00550 retVal /= value;
00551 return retVal;
00552 }
00554
00555
00561 void
00562 CoinPackedVectorUnitTest();
00563
00564 #endif