/home/coin/SVN-release/CoinAll-1.1.0/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

Generated on Sun Nov 14 14:06:32 2010 for Coin-All by  doxygen 1.4.7