/* $Id$ */ // Copyright (C) 2000, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). #if defined(_MSC_VER) // Turn off compiler warning about long names # pragma warning(disable:4786) #endif #include #include #include "CoinTypes.hpp" #include "CoinFloatEqual.hpp" #include "CoinHelperFunctions.hpp" #include "CoinIndexedVector.hpp" #include "CoinTypes.hpp" //############################################################################# #define WARN_USELESS 0 void CoinIndexedVector::clear() { #if WARN_USELESS int nNonZero=0; for (int i=0;i1 if (nNonZero!=nElements_) printf("Vector said it had %d nonzeros - only had %d\n", nElements_,nNonZero); #endif if (!nNonZero&&nElements_) printf("Vector said it had %d nonzeros - but is already empty\n", nElements_); #endif if (!packedMode_) { if (3*nElements_=COIN_INDEXED_TINY_ELEMENT) { elements_[indexValue]=elems[i]; indices_[nElements_++]=indexValue; } } } //############################################################################# /** Access the i'th element of the full storage vector. */ double & CoinIndexedVector::operator[](int index) const { assert (!packedMode_); #ifndef COIN_FAST_CODE if ( index >= capacity_ ) throw CoinError("index >= capacity()", "[]", "CoinIndexedVector"); if ( index < 0 ) throw CoinError("index < 0" , "[]", "CoinIndexedVector"); #endif double * where = elements_ + index; return *where; } //############################################################################# void CoinIndexedVector::setElement(int index, double element) { #ifndef COIN_FAST_CODE if ( index >= nElements_ ) throw CoinError("index >= size()", "setElement", "CoinIndexedVector"); if ( index < 0 ) throw CoinError("index < 0" , "setElement", "CoinIndexedVector"); #endif elements_[indices_[index]] = element; } //############################################################################# void CoinIndexedVector::insert( int index, double element ) { #ifndef COIN_FAST_CODE if ( index < 0 ) throw CoinError("index < 0" , "setElement", "CoinIndexedVector"); #endif if (index >= capacity_) reserve(index+1); #ifndef COIN_FAST_CODE if (elements_[index]) throw CoinError("Index already exists", "insert", "CoinIndexedVector"); #endif indices_[nElements_++] = index; elements_[index] = element; } //############################################################################# void CoinIndexedVector::add( int index, double element ) { #ifndef COIN_FAST_CODE if ( index < 0 ) throw CoinError("index < 0" , "setElement", "CoinIndexedVector"); #endif if (index >= capacity_) reserve(index+1); if (elements_[index]) { element += elements_[index]; if (fabs(element)>= COIN_INDEXED_TINY_ELEMENT) { elements_[index] = element; } else { elements_[index] = COIN_INDEXED_REALLY_TINY_ELEMENT; } } else if (fabs(element)>= COIN_INDEXED_TINY_ELEMENT) { indices_[nElements_++] = index; assert (nElements_<=capacity_); elements_[index] = element; } } //############################################################################# int CoinIndexedVector::clean( double tolerance ) { int number = nElements_; int i; nElements_=0; assert(!packedMode_); for (i=0;i=tolerance) { indices_[nElements_++]=indexValue; } else { elements_[indexValue]=0.0; } } return nElements_; } #ifndef NDEBUG //############################################################################# // For debug check vector is clear i.e. no elements void CoinIndexedVector::checkClear() { #ifndef NDEBUG //printf("checkClear %p\n",this); assert(!nElements_); //assert(!packedMode_); int i; for (i=0;i (indices_+capacity_); for (i=0;i (indices_+capacity_); for (i=0;i=COIN_INDEXED_TINY_ELEMENT) { elements_[indexValue]=celem[i]; indices_[nElements_++]=indexValue; } } } if (needClean) { // go through again int size=nElements_; nElements_=0; for (i=0;i=COIN_INDEXED_TINY_ELEMENT) { indices_[nElements_++]=indexValue; } else { elements_[indexValue]=0.0; } } } if (numberDuplicates) throw CoinError("duplicate index", "append", "CoinIndexedVector"); } #endif //############################################################################# void CoinIndexedVector::swap(int i, int j) { if ( i >= nElements_ ) throw CoinError("index i >= size()","swap","CoinIndexedVector"); if ( i < 0 ) throw CoinError("index i < 0" ,"swap","CoinIndexedVector"); if ( j >= nElements_ ) throw CoinError("index j >= size()","swap","CoinIndexedVector"); if ( j < 0 ) throw CoinError("index j < 0" ,"swap","CoinIndexedVector"); // Swap positions i and j of the // indices array int isave = indices_[i]; indices_[i] = indices_[j]; indices_[j] = isave; } //############################################################################# void CoinIndexedVector::truncate( int n ) { reserve(n); } //############################################################################# void CoinIndexedVector::operator+=(double value) { assert (!packedMode_); int i,indexValue; for (i=0;i=COIN_INDEXED_TINY_ELEMENT) elements_[indexValue] = newValue; else elements_[indexValue] = COIN_INDEXED_REALLY_TINY_ELEMENT; } } //----------------------------------------------------------------------------- void CoinIndexedVector::operator-=(double value) { assert (!packedMode_); int i,indexValue; for (i=0;i=COIN_INDEXED_TINY_ELEMENT) elements_[indexValue] = newValue; else elements_[indexValue] = COIN_INDEXED_REALLY_TINY_ELEMENT; } } //----------------------------------------------------------------------------- void CoinIndexedVector::operator*=(double value) { assert (!packedMode_); int i,indexValue; for (i=0;i=COIN_INDEXED_TINY_ELEMENT) elements_[indexValue] = newValue; else elements_[indexValue] = COIN_INDEXED_REALLY_TINY_ELEMENT; } } //----------------------------------------------------------------------------- void CoinIndexedVector::operator/=(double value) { assert (!packedMode_); int i,indexValue; for (i=0;i=COIN_INDEXED_TINY_ELEMENT) elements_[indexValue] = newValue; else elements_[indexValue] = COIN_INDEXED_REALLY_TINY_ELEMENT; } } //############################################################################# void CoinIndexedVector::reserve(int n) { int i; // don't make allocated space smaller but do take off values if ( n < capacity_ ) { #ifndef COIN_FAST_CODE if (n<0) throw CoinError("negative capacity", "reserve", "CoinIndexedVector"); #endif int nNew=0; for (i=0;icapacity_) { // save pointers to existing data int * tempIndices = indices_; double * tempElements = elements_; double * delTemp = elements_-offset_; // allocate new space int nPlus; if (sizeof(int)==4*sizeof(char)) nPlus=(n+3)>>2; else nPlus=(n+7)>>4; indices_ = new int [n+nPlus]; CoinZeroN(indices_+n,nPlus); // align on 64 byte boundary double * temp = new double [n+9]; offset_ = 0; CoinInt64 xx = reinterpret_cast(temp); int iBottom = static_cast(xx & 63); //if (iBottom) offset_ = (64-iBottom)>>3; elements_ = temp + offset_;; // copy data to new space // and zero out part of array if (nElements_ > 0) { CoinMemcpyN(tempIndices, nElements_, indices_); CoinMemcpyN(tempElements, capacity_, elements_); CoinZeroN(elements_+capacity_,n-capacity_); } else { CoinZeroN(elements_,n); } capacity_ = n; // free old data if (tempElements) delete [] delTemp; delete [] tempIndices; } } //############################################################################# CoinIndexedVector::CoinIndexedVector () : indices_(NULL), elements_(NULL), nElements_(0), capacity_(0), offset_(0), packedMode_(false) { } CoinIndexedVector::CoinIndexedVector (int size) : indices_(NULL), elements_(NULL), nElements_(0), capacity_(0), offset_(0), packedMode_(false) { // Get space reserve(size); } //----------------------------------------------------------------------------- CoinIndexedVector::CoinIndexedVector(int size, const int * inds, const double * elems) : indices_(NULL), elements_(NULL), nElements_(0), capacity_(0), offset_(0), packedMode_(false) { gutsOfSetVector(size, inds, elems); } //----------------------------------------------------------------------------- CoinIndexedVector::CoinIndexedVector(int size, const int * inds, double value) : indices_(NULL), elements_(NULL), nElements_(0), capacity_(0), offset_(0), packedMode_(false) { gutsOfSetConstant(size, inds, value); } //----------------------------------------------------------------------------- CoinIndexedVector::CoinIndexedVector(int size, const double * element) : indices_(NULL), elements_(NULL), nElements_(0), capacity_(0), offset_(0), packedMode_(false) { setFull(size, element); } //----------------------------------------------------------------------------- #ifndef CLP_NO_VECTOR CoinIndexedVector::CoinIndexedVector(const CoinPackedVectorBase & rhs) : indices_(NULL), elements_(NULL), nElements_(0), capacity_(0), offset_(0), packedMode_(false) { gutsOfSetVector(rhs.getNumElements(), rhs.getIndices(), rhs.getElements()); } #endif //----------------------------------------------------------------------------- CoinIndexedVector::CoinIndexedVector(const CoinIndexedVector & rhs) : indices_(NULL), elements_(NULL), nElements_(0), capacity_(0), offset_(0), packedMode_(false) { if (!rhs.packedMode_) gutsOfSetVector(rhs.capacity_,rhs.nElements_, rhs.indices_, rhs.elements_); else gutsOfSetPackedVector(rhs.capacity_,rhs.nElements_, rhs.indices_, rhs.elements_); } //----------------------------------------------------------------------------- CoinIndexedVector::CoinIndexedVector(const CoinIndexedVector * rhs) : indices_(NULL), elements_(NULL), nElements_(0), capacity_(0), offset_(0), packedMode_(false) { if (!rhs->packedMode_) gutsOfSetVector(rhs->capacity_,rhs->nElements_, rhs->indices_, rhs->elements_); else gutsOfSetPackedVector(rhs->capacity_,rhs->nElements_, rhs->indices_, rhs->elements_); } //----------------------------------------------------------------------------- CoinIndexedVector::~CoinIndexedVector () { delete [] indices_; if (elements_) delete [] (elements_-offset_); } //############################################################################# //############################################################################# /// Return the sum of two indexed vectors CoinIndexedVector CoinIndexedVector::operator+( const CoinIndexedVector& op2) { assert (!packedMode_); int i; int nElements=nElements_; int capacity = CoinMax(capacity_,op2.capacity_); CoinIndexedVector newOne(*this); newOne.reserve(capacity); bool needClean=false; // new one now can hold everything so just modify old and add new for (i=0;i=COIN_INDEXED_TINY_ELEMENT) { newOne.elements_[indexValue]=value; newOne.indices_[nElements++]=indexValue; } } else { value += oldValue; newOne.elements_[indexValue]=value; if (fabs(value)=COIN_INDEXED_TINY_ELEMENT) { newOne.indices_[newOne.nElements_++]=indexValue; } else { newOne.elements_[indexValue]=0.0; } } } return newOne; } /// Return the difference of two indexed vectors CoinIndexedVector CoinIndexedVector::operator-( const CoinIndexedVector& op2) { assert (!packedMode_); int i; int nElements=nElements_; int capacity = CoinMax(capacity_,op2.capacity_); CoinIndexedVector newOne(*this); newOne.reserve(capacity); bool needClean=false; // new one now can hold everything so just modify old and add new for (i=0;i=COIN_INDEXED_TINY_ELEMENT) { newOne.elements_[indexValue]=-value; newOne.indices_[nElements++]=indexValue; } } else { value = oldValue-value; newOne.elements_[indexValue]=value; if (fabs(value)=COIN_INDEXED_TINY_ELEMENT) { newOne.indices_[newOne.nElements_++]=indexValue; } else { newOne.elements_[indexValue]=0.0; } } } return newOne; } /// Return the element-wise product of two indexed vectors CoinIndexedVector CoinIndexedVector::operator*( const CoinIndexedVector& op2) { assert (!packedMode_); int i; int nElements=nElements_; int capacity = CoinMax(capacity_,op2.capacity_); CoinIndexedVector newOne(*this); newOne.reserve(capacity); bool needClean=false; // new one now can hold everything so just modify old and add new for (i=0;i=COIN_INDEXED_TINY_ELEMENT) { newOne.indices_[newOne.nElements_++]=indexValue; } else { newOne.elements_[indexValue]=0.0; } } } return newOne; } /// Return the element-wise ratio of two indexed vectors CoinIndexedVector CoinIndexedVector::operator/ (const CoinIndexedVector& op2) { assert (!packedMode_); // I am treating 0.0/0.0 as 0.0 int i; int nElements=nElements_; int capacity = CoinMax(capacity_,op2.capacity_); CoinIndexedVector newOne(*this); newOne.reserve(capacity); bool needClean=false; // new one now can hold everything so just modify old and add new for (i=0;i=COIN_INDEXED_TINY_ELEMENT) { newOne.indices_[newOne.nElements_++]=indexValue; } else { newOne.elements_[indexValue]=0.0; } } } return newOne; } // The sum of two indexed vectors void CoinIndexedVector::operator+=(const CoinIndexedVector& op2) { // do slowly at first *this = *this + op2; } // The difference of two indexed vectors void CoinIndexedVector::operator-=( const CoinIndexedVector& op2) { // do slowly at first *this = *this - op2; } // The element-wise product of two indexed vectors void CoinIndexedVector::operator*=(const CoinIndexedVector& op2) { // do slowly at first *this = *this * op2; } // The element-wise ratio of two indexed vectors (0.0/0.0 => 0.0) (0 vanishes) void CoinIndexedVector::operator/=(const CoinIndexedVector& op2) { // do slowly at first *this = *this / op2; } //############################################################################# void CoinIndexedVector::sortDecrIndex() { // Should replace with std sort double * elements = new double [nElements_]; CoinZeroN (elements,nElements_); CoinSort_2(indices_, indices_ + nElements_, elements, CoinFirstGreater_2()); delete [] elements; } void CoinIndexedVector::sortPacked() { assert(packedMode_); CoinSort_2(indices_, indices_ + nElements_, elements_); } void CoinIndexedVector::sortIncrElement() { double * elements = new double [nElements_]; int i; for (i=0;i()); delete [] elements; } void CoinIndexedVector::sortDecrElement() { double * elements = new double [nElements_]; int i; for (i=0;i()); delete [] elements; } //############################################################################# void CoinIndexedVector::gutsOfSetVector(int size, const int * inds, const double * elems) { #ifndef COIN_FAST_CODE if (size<0) throw CoinError("negative number of indices", "setVector", "CoinIndexedVector"); #endif assert(!packedMode_); // find largest int i; int maxIndex=-1; for (i=0;i=COIN_INDEXED_TINY_ELEMENT) { indices_[nElements_++]=indexValue; elements_[indexValue]=elems[i]; } } else { numberDuplicates++; elements_[indexValue] += elems[i] ; if (fabs(elements_[indexValue])=COIN_INDEXED_TINY_ELEMENT) { indices_[nElements_++]=indexValue; } else { elements_[indexValue]=0.0; } } } if (numberDuplicates) throw CoinError("duplicate index", "setVector", "CoinIndexedVector"); } //############################################################################# void CoinIndexedVector::gutsOfSetVector(int size, int numberIndices, const int * inds, const double * elems) { assert(!packedMode_); int i; reserve(size); #ifndef COIN_FAST_CODE if (numberIndices<0) throw CoinError("negative number of indices", "setVector", "CoinIndexedVector"); #endif nElements_ = 0; // elements_ array is all zero bool needClean=false; int numberDuplicates=0; for (i=0;i=size) throw CoinError("too large an index", "setVector", "CoinIndexedVector"); #endif if (elements_[indexValue]) { numberDuplicates++; elements_[indexValue] += elems[indexValue] ; if (fabs(elements_[indexValue])=COIN_INDEXED_TINY_ELEMENT) { #endif elements_[indexValue]=elems[indexValue]; indices_[nElements_++]=indexValue; #ifndef COIN_FAC_NEW } #endif } } if (needClean) { // go through again size=nElements_; nElements_=0; for (i=0;i=COIN_INDEXED_TINY_ELEMENT) { indices_[nElements_++]=indexValue; } else { elements_[indexValue]=0.0; } } } if (numberDuplicates) throw CoinError("duplicate index", "setVector", "CoinIndexedVector"); } //----------------------------------------------------------------------------- void CoinIndexedVector::gutsOfSetPackedVector(int size, int numberIndices, const int * inds, const double * elems) { packedMode_=true; int i; reserve(size); #ifndef COIN_FAST_CODE if (numberIndices<0) throw CoinError("negative number of indices", "setVector", "CoinIndexedVector"); #endif nElements_ = 0; // elements_ array is all zero // Does not check for duplicates for (i=0;i=size) throw CoinError("too large an index", "setVector", "CoinIndexedVector"); #endif if (fabs(elems[i])>=COIN_INDEXED_TINY_ELEMENT) { elements_[nElements_]=elems[i]; indices_[nElements_++]=indexValue; } } } //----------------------------------------------------------------------------- void CoinIndexedVector::gutsOfSetConstant(int size, const int * inds, double value) { assert(!packedMode_); #ifndef COIN_FAST_CODE if (size<0) throw CoinError("negative number of indices", "setConstant", "CoinIndexedVector"); #endif // find largest int i; int maxIndex=-1; for (i=0;i=COIN_INDEXED_TINY_ELEMENT) { elements_[indexValue] += value; indices_[nElements_++]=indexValue; } } else { numberDuplicates++; elements_[indexValue] += value ; if (fabs(elements_[indexValue])=COIN_INDEXED_TINY_ELEMENT) { indices_[nElements_++]=indexValue; } else { elements_[indexValue]=0.0; } } } if (numberDuplicates) throw CoinError("duplicate index", "setConstant", "CoinIndexedVector"); } //############################################################################# // Append a CoinIndexedVector to the end void CoinIndexedVector::append(const CoinIndexedVector & caboose) { const int cs = caboose.getNumElements(); const int * cind = caboose.getIndices(); const double * celem = caboose.denseVector(); int maxIndex=-1; int i; for (i=0;i=COIN_INDEXED_TINY_ELEMENT) { elements_[indexValue]=celem[indexValue]; indices_[nElements_++]=indexValue; } } } if (needClean) { // go through again int size=nElements_; nElements_=0; for (i=0;i=COIN_INDEXED_TINY_ELEMENT) { indices_[nElements_++]=indexValue; } else { elements_[indexValue]=0.0; } } } if (numberDuplicates) throw CoinError("duplicate index", "append", "CoinIndexedVector"); } // Append a CoinIndexedVector to the end and modify indices void CoinIndexedVector::append(CoinIndexedVector & other,int adjustIndex, bool zapElements/*,double multiplier*/) { const int cs = other.nElements_; const int * cind = other.indices_; double * celem = other.elements_; int * newInd = indices_+nElements_; if (packedMode_) { double * newEls = elements_+nElements_; if (zapElements) { if (other.packedMode_) { for (int i=0;itolerance) { bad=i; break; } } } for (int i=0;itolerance) { bad=i; break; } } } } return bad; } /* Equal. Returns true if vectors have same length and corresponding element of each vector is equal. */ bool CoinIndexedVector::operator==(const CoinIndexedVector & rhs) const { const int cs = rhs.nElements_; const int * cind = rhs.indices_; const double * celem = rhs.elements_; if (nElements_!=cs) return false; bool okay=true; CoinRelFltEq eq(1.0e-8); if (!packedMode_&&!rhs.packedMode_) { for (int i=0;i=tolerance) indices[number++] = i; else elements_[i]=0.0; } } nElements_ += number; return number; } // These pack down int CoinIndexedVector::cleanAndPack( double tolerance ) { if (!packedMode_) { int number = nElements_; int i; nElements_=0; for (i=0;i=tolerance) { elements_[nElements_]=value; indices_[nElements_++]=indexValue; } } packedMode_=true; } return nElements_; } // These pack down int CoinIndexedVector::cleanAndPackSafe( double tolerance ) { int number = nElements_; if (number) { int i; nElements_=0; assert(!packedMode_); double * temp=NULL; bool gotMemory; if (number*3 (indices_+number); CoinInt64 xx = reinterpret_cast(tempC); CoinInt64 iBottom = xx & 7; if (iBottom) tempC += 8-iBottom; temp = reinterpret_cast (tempC); xx = reinterpret_cast(temp); iBottom = xx & 7; assert(!iBottom); } else { // might be better to do complete scan gotMemory=true; temp = new double[number]; } for (i=0;i=tolerance) { temp[nElements_]=value; indices_[nElements_++]=indexValue; } } CoinMemcpyN(temp,nElements_,elements_); if (gotMemory) delete [] temp; packedMode_=true; } return nElements_; } // Scan dense region and set up indices int CoinIndexedVector::scanAndPack() { nElements_=0; return scanAndPack(0,capacity_); } // Scan dense region from start to < end and set up indices int CoinIndexedVector::scanAndPack(int start, int end) { assert(!packedMode_); end = CoinMin(end,capacity_); start = CoinMax(start,0); int i; int number = 0; int * indices = indices_+nElements_; for (i=start;i=tolerance) { elements_[number]=value; indices[number++] = i; } } nElements_ += number; packedMode_=true; return number; } // This is mainly for testing - goes from packed to indexed void CoinIndexedVector::expand() { if (nElements_&&packedMode_) { double * temp = new double[capacity_]; int i; for (i=0;i0&&array_)||!array_); memset (array_,0,size_); } // Get array with alignment void CoinArrayWithLength::getArray(int size) { if (size>0) { if(alignment_>2) { offset_ = 1<0); char * array = new char [size+offset_]; if (offset_) { // need offset CoinInt64 xx = reinterpret_cast(array); int iBottom = static_cast(xx & ((offset_-1))); if (iBottom) offset_ = offset_-iBottom; else offset_ = 0; array_ = array + offset_;; } else { array_=array; } if (size_!=-1) size_=size; } else { array_= NULL; } } // Get rid of array with alignment void CoinArrayWithLength::conditionalDelete() { if (size_==-1) { char * charArray = reinterpret_cast (array_); if (charArray) delete [] (charArray-offset_); array_=NULL; } else if (size_>=0) { size_ = -size_-2; } } // Really get rid of array with alignment void CoinArrayWithLength::reallyFreeArray() { char * charArray = reinterpret_cast (array_); if (charArray) delete [] (charArray-offset_); array_=NULL; size_=-1; } // Get enough space void CoinArrayWithLength::getCapacity(int numberBytes,int numberNeeded) { int k=capacity(); if (k0 size_ set to size and zeroed if size<=0 just does alignment If abs(mode) >2 then align on that as power of 2 */ CoinArrayWithLength::CoinArrayWithLength(int size, int mode) { alignment_=abs(mode); getArray(size); if (mode>0&&array_) memset(array_,0,size); size_=size; } CoinArrayWithLength::~CoinArrayWithLength () { if (array_) delete [] (array_-offset_); } // Conditionally gets new array char * CoinArrayWithLength::conditionalNew(long sizeWanted) { if (size_==-1) { getCapacity(static_cast(sizeWanted)); } else { int newSize = static_cast (sizeWanted*101/100)+64; // round to multiple of 16 newSize -= newSize&15; getCapacity(static_cast(sizeWanted),newSize); } return array_; } /* Copy constructor. */ CoinArrayWithLength::CoinArrayWithLength(const CoinArrayWithLength & rhs) { assert (capacity()>=0); getArray(rhs.capacity()); if (size_>0) CoinMemcpyN(rhs.array_,size_,array_); } /* Copy constructor.2 */ CoinArrayWithLength::CoinArrayWithLength(const CoinArrayWithLength * rhs) { assert (rhs->capacity()>=0); size_=rhs->size_; getArray(rhs->capacity()); if (size_>0) CoinMemcpyN(rhs->array_,size_,array_); } /* Assignment operator. */ CoinArrayWithLength & CoinArrayWithLength::operator=(const CoinArrayWithLength & rhs) { if (this != &rhs) { assert (rhs.size_!=-1||!rhs.array_); if (rhs.size_==-1) { reallyFreeArray(); } else { getCapacity(rhs.size_); if (size_>0) CoinMemcpyN(rhs.array_,size_,array_); } } return *this; } /* Assignment with length (if -1 use internal length) */ void CoinArrayWithLength::copy(const CoinArrayWithLength & rhs, int numberBytes) { if (numberBytes==-1||numberBytes<=rhs.capacity()) { CoinArrayWithLength::operator=(rhs); } else { assert (numberBytes>=0); getCapacity(numberBytes); if (rhs.array_) CoinMemcpyN(rhs.array_,numberBytes,array_); } } /* Assignment with length - does not copy */ void CoinArrayWithLength::allocate(const CoinArrayWithLength & rhs, int numberBytes) { if (numberBytes==-1||numberBytes<=rhs.capacity()) { assert (rhs.size_!=-1||!rhs.array_); if (rhs.size_==-1) { reallyFreeArray(); } else { getCapacity(rhs.size_); } } else { assert (numberBytes>=0); if (size_==-1) { delete [] array_; array_=NULL; } else { size_=-1; } if (rhs.size_>=0) size_ = numberBytes; assert (numberBytes>=0); assert (!array_); if (numberBytes) array_ = new char[numberBytes]; } } // Does what is needed to set persistence void CoinArrayWithLength::setPersistence(int flag,int currentLength) { if (flag) { if (size_==-1) { if (currentLength&&array_) { size_=currentLength; } else { size_=0; conditionalDelete(); array_=NULL; } } } else { size_=-1; } } // Swaps memory between two members void CoinArrayWithLength::swap(CoinArrayWithLength & other) { #ifdef COIN_DEVELOP if (!(size_==other.size_||size_==-1||other.size_==-1)) printf("Two arrays have sizes - %d and %d\n",size_,other.size_); #endif assert (alignment_==other.alignment_); char * swapArray = other.array_; other.array_=array_; array_=swapArray; int swapSize = other.size_; other.size_=size_; size_=swapSize; int swapOffset = other.offset_; other.offset_=offset_; offset_=swapOffset; } // Extend a persistent array keeping data (size in bytes) void CoinArrayWithLength::extend(int newSize) { //assert (newSize>=capacity()&&capacity()>=0); assert (size_>=0); // not much point otherwise if (newSize>size_) { char * temp = array_; getArray(newSize); if (temp) { CoinMemcpyN(array_,size_,temp); delete [] (temp-offset_); } size_=newSize; } } /* Default constructor */ CoinPartitionedVector::CoinPartitionedVector() : CoinIndexedVector() { memset(startPartition_,0,((&numberPartitions_-startPartition_)+1)*sizeof(int)); } /* Copy constructor. */ CoinPartitionedVector::CoinPartitionedVector(const CoinPartitionedVector & rhs) : CoinIndexedVector(rhs) { memcpy(startPartition_,rhs.startPartition_,((&numberPartitions_-startPartition_)+1)*sizeof(int)); } /* Copy constructor.2 */ CoinPartitionedVector::CoinPartitionedVector(const CoinPartitionedVector * rhs) : CoinIndexedVector(rhs) { memcpy(startPartition_,rhs->startPartition_,((&numberPartitions_-startPartition_)+1)*sizeof(int)); } /* Assignment operator. */ CoinPartitionedVector & CoinPartitionedVector::operator=(const CoinPartitionedVector & rhs) { if (this != &rhs) { CoinIndexedVector::operator=(rhs); memcpy(startPartition_,rhs.startPartition_,((&numberPartitions_-startPartition_)+1)*sizeof(int)); } return *this; } /* Destructor */ CoinPartitionedVector::~CoinPartitionedVector () { } // Add up number of elements in partitions void CoinPartitionedVector::computeNumberElements() { if (numberPartitions_) { assert (packedMode_); int n=0; for (int i=0;i=last); assert (numberElementsPartition_[i]==0); last=startPartition_[i]; } assert (startPartition_[numberPartitions_]>=last&& startPartition_[numberPartitions_]<=capacity_); #endif } else { clearAndReset(); } } // Reset the vector (as if were just created an empty vector). Gets rid of partitions void CoinPartitionedVector::clearAndReset() { if (numberPartitions_) { assert (packedMode_||!nElements_); for (int i=0;i (indices_+capacity_); for (i=0;itolerance) { elements[n]=value; indices[n++]=i+start; } } } } numberElementsPartition_[partition]=n; return n; } // Print out void CoinPartitionedVector::print() const { printf("Vector has %d elements (%d partitions)\n",nElements_,numberPartitions_); if (!numberPartitions_) { CoinIndexedVector::print(); return; } double * tempElements=CoinCopyOfArray(elements_,capacity_); int * tempIndices=CoinCopyOfArray(indices_,capacity_); for (int partition=0;partition