• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

/build/buildd/coinutils-2.6.4/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

Generated on Fri Oct 15 2010 18:21:02 by  doxygen 1.7.1