Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | Related Pages

CoinPackedVectorBase.cpp

00001 // Copyright (C) 2000, International Business Machines
00002 // Corporation and others.  All Rights Reserved.
00003 
00004 #if defined(_MSC_VER)
00005 // Turn off compiler warning about long names
00006 #  pragma warning(disable:4786)
00007 #endif
00008 
00009 #include <numeric>
00010 
00011 #include "CoinHelperFunctions.hpp"
00012 #include "CoinPackedVectorBase.hpp"
00013 
00014 //#############################################################################
00015 
00016 double *
00017 CoinPackedVectorBase::denseVector(int denseSize) const throw(CoinError)
00018 {
00019    if (getMaxIndex() >= denseSize)
00020       throw CoinError("Dense vector size is less than max index",
00021                      "denseVector", "CoinPackedVectorBase");
00022 
00023    double * dv = new double[denseSize];
00024    CoinFillN(dv, denseSize, 0.0);
00025    const int s = getNumElements();
00026    const int * inds = getIndices();
00027    const double * elems = getElements();
00028    for (int i = 0; i < s; ++i)
00029       dv[inds[i]] = elems[i];
00030    return dv;
00031 }
00032 
00033 //-----------------------------------------------------------------------------
00034 
00035 double
00036 CoinPackedVectorBase::operator[](int i) const throw (CoinError)
00037 {
00038    if (! testedDuplicateIndex_)
00039       duplicateIndex("operator[]", "CoinPackedVectorBase");
00040 
00041    // Get a reference to a map of full storage indices to 
00042    // packed storage location.
00043    const std::set<int> & sv = *indexSet("operator[]", "CoinPackedVectorBase");
00044 #if 1
00045    if (sv.find(i) == sv.end())
00046       return 0.0;
00047    return getElements()[findIndex(i)];
00048 #else
00049    // LL: suggested change, somthing is wrong with this
00050    const size_t ind = std::distance(sv.begin(), sv.find(i));
00051    return (ind == sv.size()) ? 0.0 : getElements()[ind];
00052 #endif
00053       
00054 }
00055 
00056 //#############################################################################
00057 
00058 void
00059 CoinPackedVectorBase::setTestForDuplicateIndex(bool test) const
00060 {
00061    if (test == true) {
00062       testForDuplicateIndex_ = true;
00063       duplicateIndex("setTestForDuplicateIndex", "CoinPackedVectorBase");
00064    } else {
00065       testForDuplicateIndex_ = false;
00066       testedDuplicateIndex_ = false;
00067    }
00068 }
00069 
00070 //#############################################################################
00071 
00072 int
00073 CoinPackedVectorBase::getMaxIndex() const
00074 {
00075    findMaxMinIndices();
00076    return maxIndex_;
00077 }
00078 
00079 //-----------------------------------------------------------------------------
00080 
00081 int
00082 CoinPackedVectorBase::getMinIndex() const
00083 {
00084    findMaxMinIndices();
00085    return minIndex_;
00086 }
00087 
00088 //-----------------------------------------------------------------------------
00089 
00090 void
00091 CoinPackedVectorBase::duplicateIndex(const char* methodName,
00092                                     const char * className)
00093    const throw(CoinError)
00094 {
00095    if (testForDuplicateIndex())
00096       indexSet(methodName, className);
00097    testedDuplicateIndex_ = true;
00098 }
00099 
00100 //-----------------------------------------------------------------------------
00101 
00102 bool
00103 CoinPackedVectorBase::isExistingIndex(int i) const
00104 {
00105    if (! testedDuplicateIndex_)
00106       duplicateIndex("indexExists", "CoinPackedVectorBase");
00107 
00108    const std::set<int> & sv = *indexSet("indexExists", "CoinPackedVectorBase");
00109    return sv.find(i) != sv.end();
00110 }
00111 
00112 
00113 int
00114 CoinPackedVectorBase::findIndex(int i) const
00115 {   
00116    const int * inds = getIndices();
00117    int retVal = std::find(inds, inds + getNumElements(), i) - inds;
00118    if (retVal == getNumElements() ) retVal = -1;
00119    return retVal;
00120 }
00121 
00122 //#############################################################################
00123 
00124 bool
00125 CoinPackedVectorBase::operator==(const CoinPackedVectorBase& rhs) const
00126 {
00127    return (getNumElements()==rhs.getNumElements() &&
00128            std::equal(getIndices(), getIndices() + getNumElements(),
00129                       rhs.getIndices()) &&
00130            std::equal(getElements(), getElements() + getNumElements(),
00131                       rhs.getElements()));
00132 }
00133 
00134 //-----------------------------------------------------------------------------
00135 
00136 bool
00137 CoinPackedVectorBase::operator!=(const CoinPackedVectorBase& rhs) const
00138 {
00139    return !( (*this)==rhs );
00140 }
00141 
00142 //-----------------------------------------------------------------------------
00143 
00144 double
00145 CoinPackedVectorBase::dotProduct(const double* dense) const
00146 {
00147    const double * elems = getElements();
00148    const int * inds = getIndices();
00149    double dp = 0.0;
00150    for (int i = getNumElements() - 1; i >= 0; --i)
00151       dp += elems[i] * dense[inds[i]];
00152    return dp;
00153 }
00154 
00155 //-----------------------------------------------------------------------------
00156 
00157 double
00158 CoinPackedVectorBase::oneNorm() const
00159 {
00160    register double norm = 0.0;
00161    register const double* elements = getElements();
00162    for (int i = getNumElements() - 1; i >= 0; --i) {
00163       norm += fabs(elements[i]);
00164    }
00165    return norm;
00166 }
00167 
00168 //-----------------------------------------------------------------------------
00169 
00170 double
00171 CoinPackedVectorBase::normSquare() const
00172 {
00173    return std::inner_product(getElements(), getElements() + getNumElements(),
00174                              getElements(), 0.0);
00175 }
00176 
00177 //-----------------------------------------------------------------------------
00178 
00179 double
00180 CoinPackedVectorBase::infNorm() const
00181 {
00182    register double norm = 0.0;
00183    register const double* elements = getElements();
00184    for (int i = getNumElements() - 1; i >= 0; --i) {
00185       norm = CoinMax(norm, fabs(elements[i]));
00186    }
00187    return norm;
00188 }
00189    
00190 //-----------------------------------------------------------------------------
00191 
00192 double
00193 CoinPackedVectorBase::sum() const
00194 {
00195    return std::accumulate(getElements(), getElements() + getNumElements(), 0.0);
00196 }
00197 
00198 //#############################################################################
00199 
00200 CoinPackedVectorBase::CoinPackedVectorBase() :
00201    maxIndex_(/*std::numeric_limits<int>::max()*/INT_MIN/*0*/),
00202    minIndex_(/*std::numeric_limits<int>::min()*/INT_MAX/*0*/),
00203    indexSetPtr_(NULL),
00204    testForDuplicateIndex_(true),
00205    testedDuplicateIndex_(false) {}
00206 
00207 //-----------------------------------------------------------------------------
00208 
00209 CoinPackedVectorBase::~CoinPackedVectorBase()
00210 {
00211    delete indexSetPtr_;
00212 }
00213 
00214 //#############################################################################
00215 //#############################################################################
00216 
00217 void
00218 CoinPackedVectorBase::findMaxMinIndices() const
00219 {
00220    if ( getNumElements()==0 ) 
00221       return;
00222    // if indexSet exists then grab begin and rend to get min & max indices
00223    else if ( indexSetPtr_ != NULL ) {
00224       maxIndex_ = *indexSetPtr_->rbegin();
00225       minIndex_ = *indexSetPtr_-> begin();
00226    } else {
00227       // Have to scan through vector to find min and max.
00228       maxIndex_ = *(std::max_element(getIndices(),
00229                                      getIndices() + getNumElements()));
00230       minIndex_ = *(std::min_element(getIndices(),
00231                                      getIndices() + getNumElements()));
00232    }
00233 }
00234 
00235 //-------------------------------------------------------------------
00236 
00237 std::set<int> *
00238 CoinPackedVectorBase::indexSet(const char* methodName,
00239                               const char * className) const throw(CoinError)
00240 {
00241    testedDuplicateIndex_ = true;
00242    if ( indexSetPtr_ == NULL ) {
00243       // create a set of the indices
00244       indexSetPtr_ = new std::set<int>;
00245       const int s = getNumElements();
00246       const int * inds = getIndices();
00247       for (int j=0; j < s; ++j) {
00248          if (!indexSetPtr_->insert(inds[j]).second) {
00249             testedDuplicateIndex_ = false;
00250             delete indexSetPtr_;
00251             indexSetPtr_ = NULL;
00252             if (methodName != NULL) {
00253                throw CoinError("Duplicate index found", methodName, className);
00254             } else {
00255                throw CoinError("Duplicate index found",
00256                               "indexSet", "CoinPackedVectorBase");
00257             }
00258          }
00259       }
00260    }
00261    return indexSetPtr_;
00262 }
00263 
00264 //-----------------------------------------------------------------------------
00265 
00266 void
00267 CoinPackedVectorBase::clearIndexSet() const
00268 {
00269    delete indexSetPtr_;
00270    indexSetPtr_ = NULL;
00271 }
00272 
00273 //-----------------------------------------------------------------------------
00274 
00275 void
00276 CoinPackedVectorBase::clearBase() const
00277 {
00278    clearIndexSet();
00279    maxIndex_ = /*std::numeric_limits<int>::max()*/INT_MIN/*0*/;
00280    minIndex_ = /*std::numeric_limits<int>::min()*/INT_MAX/*0*/;
00281    testedDuplicateIndex_ = false;
00282 }
00283 
00284 //#############################################################################

Generated on Wed Dec 3 14:34:21 2003 for Coin by doxygen 1.3.5