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

- File List
- File Members

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

Go to the documentation of this file.

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