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

CoinPackedVector.cpp

00001 // Copyright (C) 2000, International Business Machines
00002 // Corporation and others.  All Rights Reserved.
00003 #if defined(_MSC_VER)
00004 // Turn off compiler warning about long names
00005 #  pragma warning(disable:4786)
00006 #endif
00007 
00008 #include <cassert>
00009 
00010 #include "CoinHelperFunctions.hpp"
00011 #include "CoinPackedVector.hpp"
00012 
00013 //#############################################################################
00014 
00015 void
00016 CoinPackedVector::clear()
00017 {
00018    nElements_ = 0;
00019    clearBase();
00020 }
00021 
00022 //#############################################################################
00023 
00024 CoinPackedVector &
00025 CoinPackedVector::operator=(const CoinPackedVector & rhs)
00026 {
00027    if (this != &rhs) {
00028       clear();
00029       gutsOfSetVector(rhs.getNumElements(), rhs.getIndices(), rhs.getElements(),
00030                       CoinPackedVectorBase::testForDuplicateIndex(),
00031                       "operator=");
00032    }
00033    return *this;
00034 }
00035 
00036 //#############################################################################
00037 
00038 CoinPackedVector &
00039 CoinPackedVector::operator=(const CoinPackedVectorBase & rhs)
00040 {
00041    if (this != &rhs) {
00042       clear();
00043       gutsOfSetVector(rhs.getNumElements(), rhs.getIndices(), rhs.getElements(),
00044                       CoinPackedVectorBase::testForDuplicateIndex(),
00045                       "operator= from base");
00046    }
00047    return *this;
00048 }
00049 
00050 //#############################################################################
00051 #if 0
00052 void
00053 CoinPackedVector::assignVector(int size, int*& inds, double*& elems,
00054                               bool testForDuplicateIndex)
00055 {
00056    clear();
00057    // Allocate storage
00058    if ( size != 0 ) {
00059       reserve(size);
00060       nElements_ = size;
00061       indices_ = inds;    inds = NULL;
00062       elements_ = elems;  elems = NULL;
00063       CoinIotaN(origIndices_, size, 0);
00064    }
00065    try {
00066       CoinPackedVectorBase::setTestForDuplicateIndex(testForDuplicateIndex);
00067    }
00068    catch (CoinError e) {
00069       throw CoinError("duplicate index", "assignVector", "CoinPackedVector");
00070    }
00071 }
00072 #else
00073 void
00074 CoinPackedVector::assignVector(int size, int*& inds, double*& elems,
00075                               bool testForDuplicateIndex)
00076 {
00077   clear();
00078   // Allocate storage
00079   if ( size != 0 ) {
00080                   //reserve(size); //This is a BUG!!!
00081     nElements_ = size;
00082     if (indices_ != NULL) delete[] indices_;
00083     indices_ = inds;    inds = NULL;
00084     if (elements_ != NULL) delete[] elements_;
00085     elements_ = elems;  elems = NULL;
00086     if (origIndices_ != NULL) delete[] origIndices_;
00087     origIndices_ = new int[size];
00088     CoinIotaN(origIndices_, size, 0);
00089     capacity_ = size;
00090   }
00091   try {    
00092     CoinPackedVectorBase::setTestForDuplicateIndex(testForDuplicateIndex);
00093   }
00094   catch (CoinError e) {
00095     throw CoinError("duplicate index", "assignVector",
00096       "CoinPackedVector");
00097   }
00098 }
00099 #endif
00100 
00101 //#############################################################################
00102 
00103 void
00104 CoinPackedVector::setVector(int size, const int * inds, const double * elems,
00105                            bool testForDuplicateIndex)
00106    throw(CoinError)
00107 {
00108    clear();
00109    gutsOfSetVector(size, inds, elems, testForDuplicateIndex, "setVector");
00110 }
00111 
00112 //#############################################################################
00113 
00114 void
00115 CoinPackedVector::setConstant(int size, const int * inds, double value,
00116                              bool testForDuplicateIndex)
00117    throw(CoinError)
00118 {
00119    clear();
00120    gutsOfSetConstant(size, inds, value, testForDuplicateIndex, "setConstant");
00121 }
00122 
00123 //#############################################################################
00124 
00125 void
00126 CoinPackedVector::setFull(int size, const double * elems,
00127                          bool testForDuplicateIndex) 
00128 {
00129   // Clear out any values presently stored
00130   clear();
00131   
00132   // Allocate storage
00133   if ( size!=0 ) {
00134     reserve(size);  
00135     nElements_ = size;
00136 
00137     CoinIotaN(origIndices_, size, 0);
00138     CoinIotaN(indices_, size, 0);
00139     CoinDisjointCopyN(elems, size, elements_);
00140   }
00141   CoinPackedVectorBase::setTestForDuplicateIndex(testForDuplicateIndex);
00142 }
00143 
00144 //#############################################################################
00145 /* Indices are not specified and are taken to be 0,1,...,size-1,
00146     but only where non zero*/
00147 
00148 void
00149 CoinPackedVector::setFullNonZero(int size, const double * elems,
00150                          bool testForDuplicateIndex) 
00151 {
00152   // Clear out any values presently stored
00153   clear();
00154 
00155   // For now waste space
00156   // Allocate storage
00157   if ( size!=0 ) {
00158     reserve(size);  
00159     nElements_ = 0;
00160     int i;
00161     for (i=0;i<size;i++) {
00162       if (elems[i]) {
00163         origIndices_[nElements_]= i;
00164         indices_[nElements_]= i;
00165         elements_[nElements_++] = elems[i];
00166       }
00167     }
00168   }
00169   CoinPackedVectorBase::setTestForDuplicateIndex(testForDuplicateIndex);
00170 }
00171 
00172 
00173 //#############################################################################
00174 
00175 void
00176 CoinPackedVector::setElement(int index, double element) throw(CoinError)
00177 {
00178    if ( index >= nElements_ ) 
00179       throw CoinError("index >= size()", "setElement", "CoinPackedVector");
00180    if ( index < 0 ) 
00181       throw CoinError("index < 0" , "setElement", "CoinPackedVector");
00182    elements_[index] = element;
00183 }
00184 
00185 //#############################################################################
00186 
00187 void
00188 CoinPackedVector::insert( int index, double element ) throw(CoinError)
00189 {
00190    const int s = nElements_;
00191    if (testForDuplicateIndex()) {
00192       std::set<int>& is = *indexSet("insert", "CoinPackedVector");
00193       if (! is.insert(index).second)
00194          throw CoinError("Index already exists", "insert", "CoinPackedVector");
00195    }
00196 
00197    if( capacity_ <= s ) {
00198       reserve( CoinMax(5, 2*capacity_) );
00199       assert( capacity_ > s );
00200    }
00201    indices_[s] = index;
00202    elements_[s] = element;
00203    origIndices_[s] = s;
00204    ++nElements_;
00205 }
00206 
00207 //#############################################################################
00208 
00209 void
00210 CoinPackedVector::append(const CoinPackedVectorBase & caboose) throw(CoinError)
00211 {
00212    const int s = nElements_;
00213    const int cs = caboose.getNumElements();
00214    // Make sure there is enough room for the caboose
00215    if ( capacity_ < s + cs)
00216       reserve(CoinMax(s + cs, 2 * capacity_));
00217 
00218    const int * cind = caboose.getIndices();
00219    const double * celem = caboose.getElements();
00220    CoinDisjointCopyN(cind, cs, indices_ + s);
00221    CoinDisjointCopyN(celem, cs, elements_ + s);
00222    CoinIotaN(origIndices_ + s, cs, s);
00223    nElements_ += cs;
00224    if (testForDuplicateIndex()) {
00225       std::set<int>& is = *indexSet("append", "CoinPackedVector");
00226       for (int i = 0; i < cs; ++i) {
00227          if (!is.insert(cind[i]).second)
00228             throw CoinError("duplicate index", "append", "CoinPackedVector");
00229       }
00230    }
00231 }
00232 
00233 //#############################################################################
00234 
00235 void
00236 CoinPackedVector::swap(int i, int j) throw(CoinError)
00237 {
00238    if ( i >= nElements_ ) 
00239       throw CoinError("index i >= size()","swap","CoinPackedVector");
00240    if ( i < 0 ) 
00241       throw CoinError("index i < 0" ,"swap","CoinPackedVector");
00242    if ( i >= nElements_ ) 
00243       throw CoinError("index j >= size()","swap","CoinPackedVector");
00244    if ( i < 0 ) 
00245       throw CoinError("index j < 0" ,"swap","CoinPackedVector");
00246 
00247    // Swap positions i and j of the
00248    // indices and elements arrays
00249    std::swap(indices_[i], indices_[j]);
00250    std::swap(elements_[i], elements_[j]);
00251 }
00252 
00253 //#############################################################################
00254 
00255 void
00256 CoinPackedVector::truncate( int n ) throw(CoinError)
00257 {
00258    if ( n > nElements_ ) 
00259       throw CoinError("n > size()","truncate","CoinPackedVector");
00260    if ( n < 0 ) 
00261       throw CoinError("n < 0","truncate","CoinPackedVector");
00262    nElements_ = n;
00263    clearBase();
00264 }
00265 
00266 //#############################################################################
00267 
00268 void
00269 CoinPackedVector::operator+=(double value) 
00270 {
00271    std::transform(elements_, elements_ + nElements_, elements_,
00272                   std::bind2nd(std::plus<double>(), value) );
00273 }
00274 
00275 //-----------------------------------------------------------------------------
00276 
00277 void
00278 CoinPackedVector::operator-=(double value) 
00279 {
00280    std::transform(elements_, elements_ + nElements_, elements_,
00281                   std::bind2nd(std::minus<double>(), value) );
00282 }
00283 
00284 //-----------------------------------------------------------------------------
00285 
00286 void
00287 CoinPackedVector::operator*=(double value) 
00288 {
00289    std::transform(elements_, elements_ + nElements_, elements_,
00290                   std::bind2nd(std::multiplies<double>(), value) );
00291 }
00292 
00293 //-----------------------------------------------------------------------------
00294 
00295 void
00296 CoinPackedVector::operator/=(double value) 
00297 {
00298    std::transform(elements_, elements_ + nElements_, elements_,
00299                   std::bind2nd(std::divides<double>(), value) );
00300 }
00301 
00302 //#############################################################################
00303 
00304 void
00305 CoinPackedVector::sortOriginalOrder() {
00306   CoinSort_3(origIndices_, origIndices_ + nElements_, indices_, elements_);
00307 }
00308 
00309 //#############################################################################
00310 
00311 void
00312 CoinPackedVector::reserve(int n)
00313 {
00314    // don't make allocated space smaller
00315    if ( n <= capacity_ )
00316       return;
00317    capacity_ = n;
00318 
00319    // save pointers to existing data
00320    int * tempIndices = indices_;
00321    int * tempOrigIndices = origIndices_;
00322    double * tempElements = elements_;
00323 
00324    // allocate new space
00325    indices_ = new int [capacity_];
00326    origIndices_ = new int [capacity_];
00327    elements_ = new double [capacity_];
00328 
00329    // copy data to new space
00330    if (nElements_ > 0) {
00331       CoinDisjointCopyN(tempIndices, nElements_, indices_);
00332       CoinDisjointCopyN(tempOrigIndices, nElements_, origIndices_);
00333       CoinDisjointCopyN(tempElements, nElements_, elements_);
00334    }
00335 
00336    // free old data
00337    delete [] tempElements;
00338    delete [] tempOrigIndices;
00339    delete [] tempIndices;
00340 }
00341 
00342 //#############################################################################
00343 
00344 CoinPackedVector::CoinPackedVector (bool testForDuplicateIndex) :
00345    CoinPackedVectorBase(),
00346    indices_(NULL),
00347    elements_(NULL),
00348    nElements_(0),
00349    origIndices_(NULL),
00350    capacity_(0)
00351 {
00352    // This won't fail, the packed vector is empty. There can't be duplicate
00353    // indices.
00354    CoinPackedVectorBase::setTestForDuplicateIndex(testForDuplicateIndex);
00355 }
00356 
00357 //-----------------------------------------------------------------------------
00358 
00359 CoinPackedVector::CoinPackedVector(int size,
00360                                  const int * inds, const double * elems,
00361                                  bool testForDuplicateIndex) :
00362    CoinPackedVectorBase(),
00363    indices_(NULL),
00364    elements_(NULL),
00365    nElements_(0),
00366    origIndices_(NULL),
00367    capacity_(0)
00368 {
00369    gutsOfSetVector(size, inds, elems, testForDuplicateIndex,
00370                    "constructor for array value");
00371 }
00372 
00373 //-----------------------------------------------------------------------------
00374 
00375 CoinPackedVector::CoinPackedVector(int size,
00376                                  const int * inds, double value,
00377                                  bool testForDuplicateIndex) :
00378    CoinPackedVectorBase(),
00379    indices_(NULL),
00380    elements_(NULL),
00381    nElements_(0),
00382    origIndices_(NULL),
00383    capacity_(0)
00384 {
00385    gutsOfSetConstant(size, inds, value, testForDuplicateIndex,
00386                      "constructor for constant value");
00387 }
00388 
00389 //-----------------------------------------------------------------------------
00390 
00391 CoinPackedVector::CoinPackedVector(int size, const double * element,
00392                                  bool testForDuplicateIndex) :
00393    CoinPackedVectorBase(),
00394    indices_(NULL),
00395    elements_(NULL),
00396    nElements_(0),
00397    origIndices_(NULL),
00398    capacity_(0)
00399 {
00400    setFull(size, element, testForDuplicateIndex);
00401 }
00402 
00403 //-----------------------------------------------------------------------------
00404 
00405 CoinPackedVector::CoinPackedVector(const CoinPackedVectorBase & rhs) :
00406    CoinPackedVectorBase(),
00407    indices_(NULL),
00408    elements_(NULL),
00409    nElements_(0),
00410    origIndices_(NULL),
00411    capacity_(0)
00412 {  
00413    gutsOfSetVector(rhs.getNumElements(), rhs.getIndices(), rhs.getElements(),
00414                    rhs.testForDuplicateIndex(), "copy constructor from base");
00415 }
00416 
00417 //-----------------------------------------------------------------------------
00418 
00419 CoinPackedVector::CoinPackedVector(const CoinPackedVector & rhs) :
00420    CoinPackedVectorBase(),
00421    indices_(NULL),
00422    elements_(NULL),
00423    nElements_(0),
00424    origIndices_(NULL),
00425    capacity_(0)
00426 {  
00427    gutsOfSetVector(rhs.getNumElements(), rhs.getIndices(), rhs.getElements(),
00428                    rhs.testForDuplicateIndex(), "copy constructor");
00429 }
00430 
00431 //-----------------------------------------------------------------------------
00432 
00433 CoinPackedVector::~CoinPackedVector ()
00434 {
00435    delete [] indices_;
00436    delete [] origIndices_;
00437    delete [] elements_;
00438 }
00439 
00440 //#############################################################################
00441 
00442 void
00443 CoinPackedVector::gutsOfSetVector(int size,
00444                                  const int * inds, const double * elems,
00445                                  bool testForDuplicateIndex,
00446                                  const char * method)
00447 {
00448    if ( size != 0 ) {
00449       reserve(size);
00450       nElements_ = size;
00451       CoinDisjointCopyN(inds, size, indices_);
00452       CoinDisjointCopyN(elems, size, elements_);
00453       CoinIotaN(origIndices_, size, 0);
00454    }
00455    try {
00456       CoinPackedVectorBase::setTestForDuplicateIndex(testForDuplicateIndex);
00457    }
00458    catch (CoinError e) {
00459       throw CoinError("duplicate index", method, "CoinPackedVector");
00460    }
00461 }
00462 
00463 //-----------------------------------------------------------------------------
00464 
00465 void
00466 CoinPackedVector::gutsOfSetConstant(int size,
00467                                    const int * inds, double value,
00468                                    bool testForDuplicateIndex,
00469                                    const char * method)
00470 {
00471    if ( size != 0 ) {
00472       reserve(size);
00473       nElements_ = size;
00474       CoinDisjointCopyN(inds, size, indices_);
00475       CoinFillN(elements_, size, value);
00476       CoinIotaN(origIndices_, size, 0);
00477    }
00478    try {
00479       CoinPackedVectorBase::setTestForDuplicateIndex(testForDuplicateIndex);
00480    }
00481    catch (CoinError e) {
00482       throw CoinError("duplicate index", method, "CoinPackedVector");
00483    }
00484 }
00485 
00486 //#############################################################################

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