# CoinPackedVector.hpp

Go to the documentation of this file.

    00001 /* $Id: CoinPackedVector.hpp 1509 2011-12-05 13:50:48Z forrest $ */
    00002 // Copyright (C) 2000, International Business Machines
    00003 // Corporation and others.  All Rights Reserved.
    00004 // This code is licensed under the terms of the Eclipse Public License (EPL).
    00005
    00006 #ifndef CoinPackedVector_H
    00007 #define CoinPackedVector_H
    00008
    00009 #include <map>
    00010
    00011 #include "CoinPragma.hpp"
    00012 #include "CoinPackedVectorBase.hpp"
    00013 #include "CoinSort.hpp"
    00014
    00015 #ifdef COIN_FAST_CODE
    00016 #ifndef COIN_NOTEST_DUPLICATE
    00017 #define COIN_NOTEST_DUPLICATE
    00018 #endif
    00019 #endif
    00020
    00021 #ifndef COIN_NOTEST_DUPLICATE
    00022 #define COIN_DEFAULT_VALUE_FOR_DUPLICATE true
    00023 #else
    00024 #define COIN_DEFAULT_VALUE_FOR_DUPLICATE false
    00025 #endif
    00026
    00123 class CoinPackedVector : public CoinPackedVectorBase {
    00124    friend void CoinPackedVectorUnitTest();
    00125
    00126 public:
    00129
    00130    virtual int getNumElements() const { return nElements_; }
    00132    virtual const int * getIndices() const { return indices_; }
    00134    virtual const double * getElements() const { return elements_; }
    00136    int * getIndices() { return indices_; }
    00138    inline int getVectorNumElements() const { return nElements_; }
    00140    inline const int * getVectorIndices() const { return indices_; }
    00142    inline const double * getVectorElements() const { return elements_; }
    00144    double * getElements() { return elements_; }
    00148    const int * getOriginalPosition() const { return origIndices_; }
    00150
    00151    //-------------------------------------------------------------------
    00152    // Set indices and elements
    00153    //-------------------------------------------------------------------
    00156
    00157    void clear();
    00162    CoinPackedVector & operator=(const CoinPackedVector &);
    00167    CoinPackedVector & operator=(const CoinPackedVectorBase & rhs);
    00168
    00175    void assignVector(int size, int*& inds, double*& elems,
    00176                      bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
    00177
    00183    void setVector(int size, const int * inds, const double * elems,
    00184                   bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
    00185
    00187    void setConstant(int size, const int * inds, double elems,
    00188                     bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
    00189
    00191    void setFull(int size, const double * elems,
    00192                 bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
    00193
    00196    void setFullNonZero(int size, const double * elems,
    00197                 bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
    00198
    00202    void setElement(int index, double element);
    00203
    00205    void insert(int index, double element);
    00207    void append(const CoinPackedVectorBase & caboose);
    00208
    00210    void swap(int i, int j);
    00211
    00214    void truncate(int newSize);
    00216
    00219
    00220    void operator+=(double value);
    00222    void operator-=(double value);
    00224    void operator*=(double value);
    00226    void operator/=(double value);
    00228
    00238    template <class CoinCompare3>
    00239    void sort(const CoinCompare3 & tc)
    00240    { CoinSort_3(indices_, indices_ + nElements_, origIndices_, elements_,
    00241                 tc); }
    00242
    00243    void sortIncrIndex()
    00244    { CoinSort_3(indices_, indices_ + nElements_, origIndices_, elements_,
    00245                 CoinFirstLess_3<int, int, double>()); }
    00246
    00247    void sortDecrIndex()
    00248    { CoinSort_3(indices_, indices_ + nElements_, origIndices_, elements_,
    00249                 CoinFirstGreater_3<int, int, double>()); }
    00250
    00251    void sortIncrElement()
    00252    { CoinSort_3(elements_, elements_ + nElements_, origIndices_, indices_,
    00253                 CoinFirstLess_3<double, int, int>()); }
    00254
    00255    void sortDecrElement()
    00256    { CoinSort_3(elements_, elements_ + nElements_, origIndices_, indices_,
    00257                 CoinFirstGreater_3<double, int, int>()); }
    00258
    00259
    00264    void sortOriginalOrder();
    00266
    00273    void reserve(int n);
    00277    int capacity() const { return capacity_; }
    00279
    00282    CoinPackedVector(bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
    00287    CoinPackedVector(int size, const int * inds, const double * elems,
    00288                    bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
    00294    CoinPackedVector(int capacity, int size, int *&inds, double *&elems,
    00295                     bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
    00297    CoinPackedVector(int size, const int * inds, double element,
    00298                    bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
    00301    CoinPackedVector(int size, const double * elements,
    00302                    bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE);
    00304    CoinPackedVector(const CoinPackedVector &);
    00306    CoinPackedVector(const CoinPackedVectorBase & rhs);
    00308    virtual ~CoinPackedVector ();
    00310
    00311 private:
    00314
    00315    void gutsOfSetVector(int size,
    00316                         const int * inds, const double * elems,
    00317                         bool testForDuplicateIndex,
    00318                         const char * method);
    00320    void gutsOfSetConstant(int size,
    00321                           const int * inds, double value,
    00322                           bool testForDuplicateIndex,
    00323                           const char * method);
    00325
    00326 private:
    00329
    00330    int * indices_;
    00332    double * elements_;
    00334    int nElements_;
    00336    int * origIndices_;
    00338    int capacity_;
    00340 };
    00341
    00342 //#############################################################################
    00343
    00359 template <class BinaryFunction> void
    00360 binaryOp(CoinPackedVector& retVal,
    00361          const CoinPackedVectorBase& op1, double value,
    00362          BinaryFunction bf)
    00363 {
    00364    retVal.clear();
    00365    const int s = op1.getNumElements();
    00366    if (s > 0) {
    00367       retVal.reserve(s);
    00368       const int * inds = op1.getIndices();
    00369       const double * elems = op1.getElements();
    00370       for (int i=0; i<s; ++i ) {
    00371          retVal.insert(inds[i], bf(value, elems[i]));
    00372       }
    00373    }
    00374 }
    00375
    00376 template <class BinaryFunction> inline void
    00377 binaryOp(CoinPackedVector& retVal,
    00378          double value, const CoinPackedVectorBase& op2,
    00379          BinaryFunction bf)
    00380 {
    00381    binaryOp(retVal, op2, value, bf);
    00382 }
    00383
    00384 template <class BinaryFunction> void
    00385 binaryOp(CoinPackedVector& retVal,
    00386          const CoinPackedVectorBase& op1, const CoinPackedVectorBase& op2,
    00387          BinaryFunction bf)
    00388 {
    00389    retVal.clear();
    00390    const int s1 = op1.getNumElements();
    00391    const int s2 = op2.getNumElements();
    00392 /*
    00393   Replaced || with &&, in response to complaint from Sven deVries, who
    00394   rightly points out || is not appropriate for additive operations. &&
    00395   should be ok as long as binaryOp is understood not to create something
    00396   from nothing.         -- lh, 04.06.11
    00397 */
    00398    if (s1 == 0 && s2 == 0)
    00399       return;
    00400
    00401    retVal.reserve(s1+s2);
    00402
    00403    const int * inds1 = op1.getIndices();
    00404    const double * elems1 = op1.getElements();
    00405    const int * inds2 = op2.getIndices();
    00406    const double * elems2 = op2.getElements();
    00407
    00408    int i;
    00409    // loop once for each element in op1
    00410    for ( i=0; i<s1; ++i ) {
    00411       const int index = inds1[i];
    00412       const int pos2 = op2.findIndex(index);
    00413       const double val = bf(elems1[i], pos2 == -1 ? 0.0 : elems2[pos2]);
    00414       // if (val != 0.0) // *THINK* : should we put in only nonzeros?
    00415       retVal.insert(index, val);
    00416    }
    00417    // loop once for each element in operand2
    00418    for ( i=0; i<s2; ++i ) {
    00419       const int index = inds2[i];
    00420       // if index exists in op1, then element was processed in prior loop
    00421       if ( op1.isExistingIndex(index) )
    00422          continue;
    00423       // Index does not exist in op1, so the element value must be zero
    00424       const double val = bf(0.0, elems2[i]);
    00425       // if (val != 0.0) // *THINK* : should we put in only nonzeros?
    00426       retVal.insert(index, val);
    00427    }
    00428 }
    00429
    00430 //-----------------------------------------------------------------------------
    00431
    00432 template <class BinaryFunction> CoinPackedVector
    00433 binaryOp(const CoinPackedVectorBase& op1, double value,
    00434          BinaryFunction bf)
    00435 {
    00436    CoinPackedVector retVal;
    00437    retVal.setTestForDuplicateIndex(true);
    00438    binaryOp(retVal, op1, value, bf);
    00439    return retVal;
    00440 }
    00441
    00442 template <class BinaryFunction> CoinPackedVector
    00443 binaryOp(double value, const CoinPackedVectorBase& op2,
    00444          BinaryFunction bf)
    00445 {
    00446    CoinPackedVector retVal;
    00447    retVal.setTestForDuplicateIndex(true);
    00448    binaryOp(retVal, op2, value, bf);
    00449    return retVal;
    00450 }
    00451
    00452 template <class BinaryFunction> CoinPackedVector
    00453 binaryOp(const CoinPackedVectorBase& op1, const CoinPackedVectorBase& op2,
    00454          BinaryFunction bf)
    00455 {
    00456    CoinPackedVector retVal;
    00457    retVal.setTestForDuplicateIndex(true);
    00458    binaryOp(retVal, op1, op2, bf);
    00459    return retVal;
    00460 }
    00461
    00462 //-----------------------------------------------------------------------------
    00464 inline CoinPackedVector operator+(const CoinPackedVectorBase& op1,
    00465                                   const CoinPackedVectorBase& op2)
    00466 {
    00467    CoinPackedVector retVal;
    00468    retVal.setTestForDuplicateIndex(true);
    00469    binaryOp(retVal, op1, op2, std::plus<double>());
    00470    return retVal;
    00471 }
    00472
    00474 inline CoinPackedVector operator-(const CoinPackedVectorBase& op1,
    00475                                  const CoinPackedVectorBase& op2)
    00476 {
    00477    CoinPackedVector retVal;
    00478    retVal.setTestForDuplicateIndex(true);
    00479    binaryOp(retVal, op1, op2, std::minus<double>());
    00480    return retVal;
    00481 }
    00482
    00484 inline CoinPackedVector operator*(const CoinPackedVectorBase& op1,
    00485                                   const CoinPackedVectorBase& op2)
    00486 {
    00487    CoinPackedVector retVal;
    00488    retVal.setTestForDuplicateIndex(true);
    00489    binaryOp(retVal, op1, op2, std::multiplies<double>());
    00490    return retVal;
    00491 }
    00492
    00494 inline CoinPackedVector operator/(const CoinPackedVectorBase& op1,
    00495                                   const CoinPackedVectorBase& op2)
    00496 {
    00497    CoinPackedVector retVal;
    00498    retVal.setTestForDuplicateIndex(true);
    00499    binaryOp(retVal, op1, op2, std::divides<double>());
    00500    return retVal;
    00501 }
    00503
    00506 inline double sparseDotProduct(const CoinPackedVectorBase& op1,
    00507                         const CoinPackedVectorBase& op2){
    00508   int len, i;
    00509   double acc = 0.0;
    00510   CoinPackedVector retVal;
    00511
    00512   CoinPackedVector retval = op1*op2;
    00513   len = retval.getNumElements();
    00514   double * CParray = retval.getElements();
    00515
    00516   for(i = 0; i < len; i++){
    00517     acc += CParray[i];
    00518   }
    00519 return acc;
    00520 }
    00521
    00522
    00525 inline double sortedSparseDotProduct(const CoinPackedVectorBase& op1,
    00526                         const CoinPackedVectorBase& op2){
    00527   int i, j, len1, len2;
    00528   double acc = 0.0;
    00529
    00530   const double* v1val = op1.getElements();
    00531   const double* v2val = op2.getElements();
    00532   const int* v1ind = op1.getIndices();
    00533   const int* v2ind = op2.getIndices();
    00534
    00535   len1 = op1.getNumElements();
    00536   len2 = op2.getNumElements();
    00537
    00538   i = 0;
    00539   j = 0;
    00540
    00541   while(i < len1 && j < len2){
    00542     if(v1ind[i] == v2ind[j]){
    00543       acc += v1val[i] * v2val[j];
    00544       i++;
    00545       j++;
    00546    }
    00547     else if(v2ind[j] < v1ind[i]){
    00548       j++;
    00549     }
    00550     else{
    00551       i++;
    00552     } // end if-else-elseif
    00553   } // end while
    00554   return acc;
    00555  }
    00556
    00557
    00558 //-----------------------------------------------------------------------------
    00559
    00565
    00566 inline CoinPackedVector
    00567 operator+(const CoinPackedVectorBase& op1, double value)
    00568 {
    00569    CoinPackedVector retVal(op1);
    00570    retVal += value;
    00571    return retVal;
    00572 }
    00573
    00575 inline CoinPackedVector
    00576 operator-(const CoinPackedVectorBase& op1, double value)
    00577 {
    00578    CoinPackedVector retVal(op1);
    00579    retVal -= value;
    00580    return retVal;
    00581 }
    00582
    00584 inline CoinPackedVector
    00585 operator*(const CoinPackedVectorBase& op1, double value)
    00586 {
    00587    CoinPackedVector retVal(op1);
    00588    retVal *= value;
    00589    return retVal;
    00590 }
    00591
    00593 inline CoinPackedVector
    00594 operator/(const CoinPackedVectorBase& op1, double value)
    00595 {
    00596    CoinPackedVector retVal(op1);
    00597    retVal /= value;
    00598    return retVal;
    00599 }
    00600
    00601 //-----------------------------------------------------------------------------
    00602
    00604 inline CoinPackedVector
    00605 operator+(double value, const CoinPackedVectorBase& op1)
    00606 {
    00607    CoinPackedVector retVal(op1);
    00608    retVal += value;
    00609    return retVal;
    00610 }
    00611
    00613 inline CoinPackedVector
    00614 operator-(double value, const CoinPackedVectorBase& op1)
    00615 {
    00616    CoinPackedVector retVal(op1);
    00617    const int size = retVal.getNumElements();
    00618    double* elems = retVal.getElements();
    00619    for (int i = 0; i < size; ++i) {
    00620       elems[i] = value - elems[i];
    00621    }
    00622    return retVal;
    00623 }
    00624
    00626 inline CoinPackedVector
    00627 operator*(double value, const CoinPackedVectorBase& op1)
    00628 {
    00629    CoinPackedVector retVal(op1);
    00630    retVal *= value;
    00631    return retVal;
    00632 }
    00633
    00635 inline CoinPackedVector
    00636 operator/(double value, const CoinPackedVectorBase& op1)
    00637 {
    00638    CoinPackedVector retVal(op1);
    00639    const int size = retVal.getNumElements();
    00640    double* elems = retVal.getElements();
    00641    for (int i = 0; i < size; ++i) {
    00642       elems[i] = value / elems[i];
    00643    }
    00644    return retVal;
    00645 }
    00647
    00648 //#############################################################################
    00654 void
    00655 CoinPackedVectorUnitTest();
    00656
    00657 #endif

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines