- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages

- File List
- File Members

# /home/coin/SVN-release/Cgl-0.53.1/CoinUtils/src/CoinPackedVector.hpp

Go to the documentation of this file.

    00001 // Copyright (C) 2000, International Business Machines
    00002 // Corporation and others.  All Rights Reserved.
    00003 #ifndef CoinPackedVector_H
    00004 #define CoinPackedVector_H
    00005
    00006 #if defined(_MSC_VER)
    00007 // Turn off compiler warning about long names
    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    // Set indices and elements
    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   Replaced || with &&, in response to complaint from Sven deVries, who
    00382   rightly points out || is not appropriate for additive operations. &&
    00383   should be ok as long as binaryOp is understood not to create something
    00384   from nothing.         -- lh, 04.06.11
    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    // loop once for each element in op1
    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       // if (val != 0.0) // *THINK* : should we put in only nonzeros?
    00403       retVal.insert(index, val);
    00404    }
    00405    // loop once for each element in operand2
    00406    for ( i=0; i<s2; ++i ) {
    00407       const int index = inds2[i];
    00408       // if index exists in op1, then element was processed in prior loop
    00409       if ( op1.isExistingIndex(index) )
    00410          continue;
    00411       // Index does not exist in op1, so the element value must be zero
    00412       const double val = bf(0.0, elems2[i]);
    00413       // if (val != 0.0) // *THINK* : should we put in only nonzeros?
    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     } // end if-else-elseif
    00541   } // end while
    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