예제 #1
0
void
CoinPackedVector::append(const CoinPackedVectorBase & caboose)
{
   const int cs = caboose.getNumElements();
   if (cs == 0) {
       return;
   }
   if (testForDuplicateIndex()) {
       // Just to initialize the index heap
       indexSet("append (1st call)", "CoinPackedVector");
   }
   const int s = nElements_;
   // Make sure there is enough room for the caboose
   if ( capacity_ < s + cs)
      reserve(CoinMax(s + cs, 2 * capacity_));

   const int * cind = caboose.getIndices();
   const double * celem = caboose.getElements();
   CoinDisjointCopyN(cind, cs, indices_ + s);
   CoinDisjointCopyN(celem, cs, elements_ + s);
   CoinIotaN(origIndices_ + s, cs, s);
   nElements_ += cs;
   if (testForDuplicateIndex()) {
      std::set<int>& is = *indexSet("append (2nd call)", "CoinPackedVector");
      for (int i = 0; i < cs; ++i) {
	 if (!is.insert(cind[i]).second)
	    throw CoinError("duplicate index", "append", "CoinPackedVector");
      }
   }
}
예제 #2
0
CoinPackedVector::CoinPackedVector(const CoinPackedVectorBase & rhs) :
   CoinPackedVectorBase(),
   indices_(NULL),
   elements_(NULL),
   nElements_(0),
   origIndices_(NULL),
   capacity_(0)
{  
   gutsOfSetVector(rhs.getNumElements(), rhs.getIndices(), rhs.getElements(),
		   rhs.testForDuplicateIndex(), "copy constructor from base");
}
예제 #3
0
bool CoinPackedVectorBase::operator==(const CoinPackedVectorBase &rhs) const
{
  if (getNumElements() == 0 || rhs.getNumElements() == 0) {
    if (getNumElements() == 0 && rhs.getNumElements() == 0)
      return (true);
    else
      return (false);
  } else {
    return (getNumElements() == rhs.getNumElements() && std::equal(getIndices(), getIndices() + getNumElements(), rhs.getIndices()) && std::equal(getElements(), getElements() + getNumElements(), rhs.getElements()));
  }
}
예제 #4
0
int CoinPackedVectorBase::compare(const CoinPackedVectorBase &rhs) const
{
  const int size = getNumElements();
  int itmp = size - rhs.getNumElements();
  if (itmp != 0) {
    return itmp;
  }
  itmp = memcmp(getIndices(), rhs.getIndices(), size * sizeof(int));
  if (itmp != 0) {
    return itmp;
  }
  return memcmp(getElements(), rhs.getElements(), size * sizeof(double));
}
예제 #5
0
void
CoinIndexedVector::append(const CoinPackedVectorBase & caboose)
{
    const int cs = caboose.getNumElements();

    const int * cind = caboose.getIndices();
    const double * celem = caboose.getElements();
    int maxIndex=-1;
    int i;
    for (i=0; i<cs; i++) {
        int indexValue = cind[i];
        if (indexValue<0)
            throw CoinError("negative index", "append", "CoinIndexedVector");
        if (maxIndex<indexValue)
            maxIndex = indexValue;
    }
    reserve(maxIndex+1);
    bool needClean=false;
    int numberDuplicates=0;
    for (i=0; i<cs; i++) {
        int indexValue=cind[i];
        if (elements_[indexValue]) {
            numberDuplicates++;
            elements_[indexValue] += celem[i] ;
            if (fabs(elements_[indexValue])<COIN_INDEXED_TINY_ELEMENT)
                needClean=true; // need to go through again
        } else {
            if (fabs(celem[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<size; i++) {
            int indexValue=indices_[i];
            double value=elements_[indexValue];
            if (fabs(value)>=COIN_INDEXED_TINY_ELEMENT) {
                indices_[nElements_++]=indexValue;
            } else {
                elements_[indexValue]=0.0;
            }
        }
    }
    if (numberDuplicates)
        throw CoinError("duplicate index", "append", "CoinIndexedVector");
}
예제 #6
0
//-------------------------------------------------------------------
// Copy
//-------------------------------------------------------------------
CoinShallowPackedVector::CoinShallowPackedVector(const CoinPackedVectorBase &x)
  : CoinPackedVectorBase()
  , indices_(x.getIndices())
  , elements_(x.getElements())
  , nElements_(x.getNumElements())
{
  CoinPackedVectorBase::copyMaxMinIndex(x);
  try {
    CoinPackedVectorBase::setTestForDuplicateIndex(x.testForDuplicateIndex());
  } catch (CoinError &e) {
    throw CoinError("duplicate index", "copy constructor from base",
      "CoinShallowPackedVector");
  }
}
예제 #7
0
//@{
template <class BinaryFunction> void
binaryOp(CoinPackedVector& retVal,
	 const CoinPackedVectorBase& op1, double value,
	 BinaryFunction bf)
{
   retVal.clear();
   const int s = op1.getNumElements();
   if (s > 0) {
      retVal.reserve(s);
      const int * inds = op1.getIndices();
      const double * elems = op1.getElements();
      for (int i=0; i<s; ++i ) {
	 retVal.insert(inds[i], bf(value, elems[i]));
      }
   }
}
예제 #8
0
/// Returns the dot product of two sorted CoinPackedVector objects.
///  The vectors should be sorted in ascending order of indices.
inline double sortedSparseDotProduct(const CoinPackedVectorBase& op1,
                        const CoinPackedVectorBase& op2){
  int i, j, len1, len2;
  double acc = 0.0;

  const double* v1val = op1.getElements();
  const double* v2val = op2.getElements();
  const int* v1ind = op1.getIndices();
  const int* v2ind = op2.getIndices();

  len1 = op1.getNumElements();
  len2 = op2.getNumElements();

  i = 0;
  j = 0;

  while(i < len1 && j < len2){
    if(v1ind[i] == v2ind[j]){
      acc += v1val[i] * v2val[j];
      i++;
      j++;
   }
    else if(v2ind[j] < v1ind[i]){
      j++;
    }
    else{
      i++;
    } // end if-else-elseif
  } // end while
  return acc;
 }
예제 #9
0
template <class BinaryFunction> void
binaryOp(CoinPackedVector& retVal,
	 const CoinPackedVectorBase& op1, const CoinPackedVectorBase& op2,
	 BinaryFunction bf)
{
   retVal.clear();
   const int s1 = op1.getNumElements();
   const int s2 = op2.getNumElements();
/*
  Replaced || with &&, in response to complaint from Sven deVries, who
  rightly points out || is not appropriate for additive operations. &&
  should be ok as long as binaryOp is understood not to create something
  from nothing.		-- lh, 04.06.11
*/
   if (s1 == 0 && s2 == 0)
      return;

   retVal.reserve(s1+s2);

   const int * inds1 = op1.getIndices();
   const double * elems1 = op1.getElements();
   const int * inds2 = op2.getIndices();
   const double * elems2 = op2.getElements();

   int i;
   // loop once for each element in op1
   for ( i=0; i<s1; ++i ) {
      const int index = inds1[i];
      const int pos2 = op2.findIndex(index);
      const double val = bf(elems1[i], pos2 == -1 ? 0.0 : elems2[pos2]);
      // if (val != 0.0) // *THINK* : should we put in only nonzeros?
      retVal.insert(index, val);
   }
   // loop once for each element in operand2  
   for ( i=0; i<s2; ++i ) {
      const int index = inds2[i];
      // if index exists in op1, then element was processed in prior loop
      if ( op1.isExistingIndex(index) )
	 continue;
      // Index does not exist in op1, so the element value must be zero
      const double val = bf(0.0, elems2[i]);
      // if (val != 0.0) // *THINK* : should we put in only nonzeros?
      retVal.insert(index, val);
   }
}