00001
00002
00003 #if defined(_MSC_VER)
00004
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
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
00079 if ( size != 0 ) {
00080
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
00130 clear();
00131
00132
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
00146
00147
00148 void
00149 CoinPackedVector::setFullNonZero(int size, const double * elems,
00150 bool testForDuplicateIndex)
00151 {
00152
00153 clear();
00154
00155
00156
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
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
00248
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
00315 if ( n <= capacity_ )
00316 return;
00317 capacity_ = n;
00318
00319
00320 int * tempIndices = indices_;
00321 int * tempOrigIndices = origIndices_;
00322 double * tempElements = elements_;
00323
00324
00325 indices_ = new int [capacity_];
00326 origIndices_ = new int [capacity_];
00327 elements_ = new double [capacity_];
00328
00329
00330 if (nElements_ > 0) {
00331 CoinDisjointCopyN(tempIndices, nElements_, indices_);
00332 CoinDisjointCopyN(tempOrigIndices, nElements_, origIndices_);
00333 CoinDisjointCopyN(tempElements, nElements_, elements_);
00334 }
00335
00336
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
00353
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