void
CoinShallowPackedVectorUnitTest()
{
  CoinRelFltEq eq;
  int i;
  // Test default constructor
  {
    CoinShallowPackedVector r;
    assert( r.indices_==NULL );
    assert( r.elements_==NULL );
    assert( r.nElements_==0 );
  }

  // Test set and get methods
  const int ne = 4;
  int inx[ne] = { 1, 3, 4, 7 };
  double el[ne] = { 1.2, 3.4, 5.6, 7.8 };
  {
    CoinShallowPackedVector r;    
    assert( r.getNumElements()==0 );
    
    // Test setting/getting elements with int* & double* vectors
    r.setVector( ne, inx, el );
    assert( r.getNumElements()==ne );
    for ( i=0; i<ne; i++ ) {
      assert( r.getIndices()[i]  == inx[i] );
      assert( r.getElements()[i] == el[i]  );
    }
    assert ( r.getMaxIndex()==7 );
    assert ( r.getMinIndex()==1 );

    // try to clear it
    r.clear();
    assert( r.indices_==NULL );
    assert( r.elements_==NULL );
    assert( r.nElements_==0 );

    // Test setting/getting elements with indices out of order  
    const int ne2 = 5;
    int inx2[ne2] = { 2, 4, 8, 14, 3 };
    double el2[ne2] = { 2.2, 4.4, 6.6, 8.8, 3.3 };
 
    r.setVector(ne2,inx2,el2);
    
    assert( r.getNumElements()==ne2 );    
    for (i = 0; i < ne2; ++i) {
       assert( r.getIndices()[i]==inx2[i] );
       assert( r.getElements()[i]==el2[i] );
    }
    
    assert ( r.getMaxIndex()==14 );
    assert ( r.getMinIndex()==2 );
    // try to call it once more
    assert ( r.getMaxIndex()==14 );
    assert ( r.getMinIndex()==2 );

    CoinShallowPackedVector r1(ne2,inx2,el2);
    assert( r == r1 );

    // assignment operator
    r1.clear();
    r1 = r;
    assert( r == r1 );

    // assignment from packed vector
    CoinPackedVector pv1(ne2,inx2,el2);
    r1 = pv1;
    assert( r == r1 );

    // construction
    CoinShallowPackedVector r2(r1);
    assert( r2 == r );
    
    // construction from packed vector
    CoinShallowPackedVector r3(pv1);
    assert( r3 == r );

    // test duplicate indices
    {
      const int ne3 = 4;
      int inx3[ne3] = { 2, 4, 2, 3 };
      double el3[ne3] = { 2.2, 4.4, 8.8, 6.6 };
      r.setVector(ne3,inx3,el3, false);
      assert(r.testForDuplicateIndex() == false);
      bool errorThrown = false;
      try {
        r.setTestForDuplicateIndex(true);
      }
      catch (CoinError& e) {
        errorThrown = true;
      }
      assert( errorThrown );

      r.clear();
      errorThrown = false;
      try {
	 r.setVector(ne3,inx3,el3);
      }
      catch (CoinError& e) {
        errorThrown = true;
      }
      assert( errorThrown );
	 
      errorThrown = false;
      try {
	 CoinShallowPackedVector r1(ne3,inx3,el3);
      }
      catch (CoinError& e) {
	 errorThrown = true;
      }
      assert( errorThrown );
    } 
    
  } 

  // Test copy constructor and assignment operator
  {
    CoinShallowPackedVector rhs;
    {
      CoinShallowPackedVector r;
      {
        CoinShallowPackedVector rC1(r);      
        assert( 0==r.getNumElements() );
        assert( 0==rC1.getNumElements() );
        
        r.setVector( ne, inx, el ); 
        
        assert( ne==r.getNumElements() );
        assert( 0==rC1.getNumElements() ); 
      }
      
      CoinShallowPackedVector rC2(r);   
      
      assert( ne==r.getNumElements() );
      assert( ne==rC2.getNumElements() );
      
      for ( i=0; i<ne; i++ ) {
        assert( r.getIndices()[i] == rC2.getIndices()[i] );
        assert( r.getElements()[i] == rC2.getElements()[i] );
      }

      rhs=rC2;
    }
    // Test that rhs has correct values even though lhs has gone out of scope
    assert( rhs.getNumElements()==ne );
    
    for ( i=0; i<ne; i++ ) {
      assert( inx[i] == rhs.getIndices()[i] );
      assert(  el[i] == rhs.getElements()[i] );
    } 
  }

  // Test operator==
  {
    CoinShallowPackedVector v1,v2;
    assert( v1==v2 );
    assert( v2==v1 );
    assert( v1==v1 );
    assert( !(v1!=v2) );
    
    v1.setVector( ne, inx, el );
    assert ( !(v1==v2) );
    assert ( v1!=v2 );

    CoinShallowPackedVector v3(v1);
    assert( v3==v1 );
    assert( v3!=v2 );

    CoinShallowPackedVector v4(v2);
    assert( v4!=v1 );
    assert( v4==v2 );
  }

 

  {
    // Test operator[] and isExistingIndex()
    const int ne = 4;
    int inx[ne] =   {  1,   4,  0,   2 };
    double el[ne] = { 10., 40., 1., 50. };
    CoinShallowPackedVector r;
    assert( r[1]==0. );

    r.setVector(ne,inx,el);

    assert( r[-1]==0. );
    assert( r[ 0]==1. );
    assert( r[ 1]==10.);
    assert( r[ 2]==50.);
    assert( r[ 3]==0. );
    assert( r[ 4]==40.);
    assert( r[ 5]==0. );
    assert(  r.isExistingIndex(2) );
    assert( !r.isExistingIndex(3) );

    assert( !r.isExistingIndex(-1) );
    assert(  r.isExistingIndex(0) );
    assert( !r.isExistingIndex(3) );
    assert(  r.isExistingIndex(4) );
    assert( !r.isExistingIndex(5) );
    
    assert ( r.getMaxIndex()==4 );
    assert ( r.getMinIndex()==0 );
  }
  
  // Test that attemping to get min/max index of a 0,
  // length vector 
  {
    CoinShallowPackedVector nullVec;
    assert( nullVec.getMaxIndex() == -COIN_INT_MAX/*0*/ );
    assert( nullVec.getMinIndex() == COIN_INT_MAX/*0*/ );
  } 

  {
     // test dense vector
     const int ne = 4;
     int inx[ne] =   {  1,   4,  0,   2 };
     double el[ne] = { 10., 40., 1., 50. };
     CoinShallowPackedVector r;
     r.setVector(ne,inx,el);
     double * dense = r.denseVector(6);
     assert(dense[0] == 1.);
     assert(dense[1] == 10.);
     assert(dense[2] == 50.);
     assert(dense[3] == 0.);
     assert(dense[4] == 40.);
     assert(dense[5] == 0.);
     delete[] dense;

     // try once more
     dense = r.denseVector(7);
     assert(dense[0] == 1.);
     assert(dense[1] == 10.);
     assert(dense[2] == 50.);
     assert(dense[3] == 0.);
     assert(dense[4] == 40.);
     assert(dense[5] == 0.);
     assert(dense[6] == 0.);
     delete[] dense;
     
  }
     
     

  
#if 0
  // what happens when someone sets 
  // the number of elements to be a negative number
  {    
    const int ne = 4;
    int inx1[ne] = { 1, 3, 4, 7 };
    double el1[ne] = { 1.2, 3.4, 5.6, 7.8 };
    CoinShallowPackedVector v1;
    v1.setVector(-ne,inx1,el1);
  }
#endif

  
  // Test adding vectors
  {    
    const int ne1 = 5;
    int inx1[ne1]   = { 1,  3,  4,  7,  5  };
    double el1[ne1] = { 1., 5., 6., 2., 9. };
    const int ne2 = 4;
    int inx2[ne2] =   { 7,  4,  2,  1  };
    double el2[ne2] = { 7., 4., 2., 1. };
    CoinShallowPackedVector v1;
    v1.setVector(ne1,inx1,el1);
    CoinShallowPackedVector v2;
    v2.setVector(ne2,inx2,el2);
    CoinPackedVector r = v1 + v2;

    const int ner = 6;
    int inxr[ner] =   {    1,     2,     3,     4,     5,     7  };
    double elr[ner] = { 1.+1., 0.+2., 5.+0., 6.+4., 9.+0., 2.+7. };
    CoinPackedVector rV;
    rV.setVector(ner,inxr,elr);
    assert( rV != r );
    assert( r.isEquivalent(rV) );
    
    CoinPackedVector p1=v1+3.1415;
    for ( i=0; i<p1.getNumElements(); i++ )
      assert( eq( p1.getElements()[i], v1.getElements()[i]+3.1415) );

    CoinPackedVector p2=(-3.1415) + p1;
    assert( p2.isEquivalent(v1) );
  } 
  
  // Test subtracting vectors
  {    
    const int ne1 = 5;
    int inx1[ne1]   = { 1,  3,  4,  7,  5  };
    double el1[ne1] = { 1., 5., 6., 2., 9. };
    const int ne2 = 4;
    int inx2[ne2] =   { 7,  4,  2,  1  };
    double el2[ne2] = { 7., 4., 2., 1. };
    CoinShallowPackedVector v1;
    v1.setVector(ne1,inx1,el1);
    CoinShallowPackedVector v2;
    v2.setVector(ne2,inx2,el2);
    CoinPackedVector r = v1 - v2;

    const int ner = 6;
    int inxr[ner] =   {    1,     2,     3,     4,     5,     7  };
    double elr[ner] = { 1.-1., 0.-2., 5.-0., 6.-4., 9.-0., 2.-7. };
    CoinPackedVector rV;
    rV.setVector(ner,inxr,elr);
    assert( r.isEquivalent(rV) );  
    
    CoinPackedVector p1=v1-3.1415;
    for ( i=0; i<p1.getNumElements(); i++ )
      assert( eq( p1.getElements()[i], v1.getElements()[i]-3.1415) );
  } 
  
  // Test multiplying vectors
  {    
    const int ne1 = 5;
    int inx1[ne1]   = { 1,  3,  4,  7,  5  };
    double el1[ne1] = { 1., 5., 6., 2., 9. };
    const int ne2 = 4;
    int inx2[ne2] =   { 7,  4,  2,  1  };
    double el2[ne2] = { 7., 4., 2., 1. };
    CoinShallowPackedVector v1;
    v1.setVector(ne1,inx1,el1);
    CoinShallowPackedVector v2;
    v2.setVector(ne2,inx2,el2);
    CoinPackedVector r = v1 * v2;

    const int ner = 6;
    int inxr[ner] =   {    1,     2,     3,     4,     5,     7  };
    double elr[ner] = { 1.*1., 0.*2., 5.*0., 6.*4., 9.*0., 2.*7. };
    CoinPackedVector rV;
    rV.setVector(ner,inxr,elr);
    assert( r.isEquivalent(rV) );

    CoinPackedVector p1=v1*3.3;
    for ( i=0; i<p1.getNumElements(); i++ )
      assert( eq( p1.getElements()[i], v1.getElements()[i]*3.3) );
    
    CoinPackedVector p2=(1./3.3) * p1;
    assert( p2.isEquivalent(v1) );
  } 
  
  // Test dividing vectors
  {    
    const int ne1 = 3;
    int inx1[ne1]   = { 1,  4,  7  };
    double el1[ne1] = { 1., 6., 2. };
    const int ne2 = 4;
    int inx2[ne2] =   { 7,  4,  2,  1  };
    double el2[ne2] = { 7., 4., 2., 1. };
    CoinShallowPackedVector v1;
    v1.setVector(ne1,inx1,el1);
    CoinShallowPackedVector v2;
    v2.setVector(ne2,inx2,el2);
    CoinPackedVector r = v1 / v2;

    const int ner = 4;
    int inxr[ner] =   {    1,     2,      4,     7  };
    double elr[ner] = { 1./1., 0./2.,  6./4., 2./7. };
    CoinPackedVector rV;
    rV.setVector(ner,inxr,elr);
    assert( r.isEquivalent(rV) );
        
    CoinPackedVector p1=v1/3.1415;
    for ( i=0; i<p1.getNumElements(); i++ )
      assert( eq( p1.getElements()[i], v1.getElements()[i]/3.1415) );
  }
   
  // Test sum
  { 
    CoinShallowPackedVector s;
    assert( s.sum() == 0 );

    int inx = 25;
    double value = 45.;
    s.setVector(1, &inx, &value);
    assert(s.sum()==45.);

    const int ne1 = 5;
    int inx1[ne1]   = { 10,  3,  4,  7,  5  };
    double el1[ne1] = { 1., 5., 6., 2., 9. };
    s.setVector(ne1,inx1,el1);

    assert(s.sum()==1.+5.+6.+2.+9.);
  }
  
  // Just another interesting test
  {    
    // Create numerator vector
    const int ne1 = 2;
    int inx1[ne1]   = { 1,  4  };
    double el1[ne1] = { 1., 6. };
    CoinShallowPackedVector v1(ne1,inx1,el1);

    // create denominator vector
    const int ne2 = 3;
    int inx2[ne2] =   { 1,  2,  4 };
    double el2[ne2] = { 1., 7., 4.};
    CoinShallowPackedVector v2(ne2,inx2,el2);

    // Compute ratio
    CoinPackedVector ratio = v1 / v2;

    // Sort ratios
    ratio.sortIncrElement();

    // Test that the sort really worked
    assert( ratio.getElements()[0] == 0.0/7.0 );
    assert( ratio.getElements()[1] == 1.0/1.0 );
    assert( ratio.getElements()[2] == 6.0/4.0 );

    // Get numerator of of sorted ratio vector
    assert( v1[ ratio.getIndices()[0] ] == 0.0 );
    assert( v1[ ratio.getIndices()[1] ] == 1.0 );
    assert( v1[ ratio.getIndices()[2] ] == 6.0 );

    // Get denominator of of sorted ratio vector
    assert( v2[ ratio.getIndices()[0] ] == 7.0 );
    assert( v2[ ratio.getIndices()[1] ] == 1.0 );
    assert( v2[ ratio.getIndices()[2] ] == 4.0 );
  }

  {
    // Test that sample usage works

    const int ne = 4;
    int inx[ne] =   {  1,   4,  0,   2 };
    double el[ne] = { 10., 40., 1., 50. };
    CoinShallowPackedVector r(ne,inx,el);

    assert( r.getIndices()[0]== 1  );
    assert( r.getElements()[0]==10. );
    assert( r.getIndices()[1]== 4  );
    assert( r.getElements()[1]==40. );
    assert( r.getIndices()[2]== 0  );
    assert( r.getElements()[2]== 1. );
    assert( r.getIndices()[3]== 2  );
    assert( r.getElements()[3]==50. );

    assert( r[ 0]==1. );
    assert( r[ 1]==10.);
    assert( r[ 2]==50.);
    assert( r[ 3]==0. );
    assert( r[ 4]==40.);

    CoinShallowPackedVector r1;
    r1=r;
    assert( r==r1 );

    CoinPackedVector add = r + r1;
    assert( add[0] ==  1.+ 1. );
    assert( add[1] == 10.+10. );
    assert( add[2] == 50.+50. );
    assert( add[3] ==  0.+ 0. );
    assert( add[4] == 40.+40. );

    assert( r.sum() == 10.+40.+1.+50. );
  }
  
  {
    // Test findIndex
    const int ne = 4;
    int inx[ne] =   {  1,  -4,  0,   2 };
    double el[ne] = { 10., 40., 1., 50. };
    CoinShallowPackedVector r(ne,inx,el);

    assert( r.findIndex(2)  == 3 );
    assert( r.findIndex(0)  == 2 );
    assert( r.findIndex(-4) == 1 );
    assert( r.findIndex(1)  == 0 );
    assert( r.findIndex(3)  == -1 );
  }  
  {
    // Test construction with testing for duplicates as false
    const int ne = 4;
    int inx[ne] =   {  1,  -4,  0,   2 };
    double el[ne] = { 10., 40., 1., 50. };
    CoinShallowPackedVector r(ne,inx,el,false);

    assert( r.isExistingIndex(1) );
    assert( r.isExistingIndex(-4) );
    assert( r.isExistingIndex(0) );
    assert( r.isExistingIndex(2) );
    assert( !r.isExistingIndex(3) );
    assert( !r.isExistingIndex(-3) );
  }
}
//--------------------------------------------------------------------------
void
CoinIndexedVectorUnitTest()
{
  
  int i;
  // Test default constructor
  {
    CoinIndexedVector r;
    assert( r.indices_==NULL );
    assert( r.elements_==NULL );
    assert( r.getNumElements()==0 );
    assert( r.capacity_==0);
  }
  
  // Test set and get methods
  const int ne = 4;
  int inx[ne] = { 1, 3, 4, 7 };
  double el[ne] = { 1.2, 3.4, 5.6, 7.8 };
  {
    CoinIndexedVector r;    
    assert( r.getNumElements()==0 );
    
    // Test setting/getting elements with int* & float* vectors
    r.setVector( ne, inx, el );
    assert( r.getNumElements()==ne );
    for ( i=0; i<ne; i++ ) {
      assert( r.getIndices()[i]  == inx[i] );
      assert( r[inx[i]]  == el[i] );
    }
    
    // Test setting/getting elements with indices out of order  
    const int ne2 = 5;
    int inx2[ne2] = { 2, 4, 8, 14, 3 };
    double el2[ne2] = { 2.2, 4.4, 6.6, 8.8, 3.3 };
    
    r.setVector(ne2,inx2,el2);
    
    assert( r.getNumElements()==ne2 );    
    
    assert( r.getIndices()[0]==inx2[0] );
    
    assert( r.getIndices()[1]==inx2[1] );
    
    assert( r.getIndices()[2]==inx2[2] );
    
    assert( r.getIndices()[3]==inx2[3] );
    
    assert( r.getIndices()[4]==inx2[4] );
    

    CoinIndexedVector r1(ne2,inx2,el2);
    assert( r == r1 );   
  }    
  CoinIndexedVector r;
  
  
  {
    CoinIndexedVector r;
    const int ne = 3;
    int inx[ne] = { 1, 2, 3 };
    double el[ne] = { 2.2, 4.4, 8.8};
    r.setVector(ne,inx,el);
    int c = r.capacity();
    // Test swap function
    r.swap(0,2);
    assert( r.getIndices()[0]==3 );
    assert( r.getIndices()[1]==2 );
    assert( r.getIndices()[2]==1 );
    assert( r.capacity() == c );
    
    // Test the append function
    CoinIndexedVector s;
    const int nes = 4;
    int inxs[nes] = { 11, 12, 13, 14 };
    double els[nes] = { .122, 14.4, 18.8, 19.9};
    s.setVector(nes,inxs,els);
    r.append(s);
    assert( r.getNumElements()==7 );
    assert( r.getIndices()[0]==3 );
    assert( r.getIndices()[1]==2 );
    assert( r.getIndices()[2]==1 );
    assert( r.getIndices()[3]==11 );
    assert( r.getIndices()[4]==12 );
    assert( r.getIndices()[5]==13 );
    assert( r.getIndices()[6]==14 );
    
    // Test the resize function
    c = r.capacity();
    r.truncate(4);
    // we will lose 11
    assert( r.getNumElements()==3 );
    assert( r.getIndices()[0]==3 );
    assert( r.getIndices()[1]==2 );
    assert( r.getIndices()[2]==1 );
    assert( r.getMaxIndex() == 3 );
    assert( r.getMinIndex() == 1 );
    assert( r.capacity() == c );
  }
  
  // Test borrow and return vector
  {
    CoinIndexedVector r,r2;
    const int ne = 3;
    int inx[ne] = { 1, 2, 3 };
    double el[ne] = { 2.2, 4.4, 8.8};
    double els[4] = { 0.0,2.2, 4.4, 8.8};
    r.setVector(ne,inx,el);
    r2.borrowVector(4,ne,inx,els);
    assert (r==r2);
    r2.returnVector();
    assert (!r2.capacity());
    assert (!r2.getNumElements());
    assert (!r2.denseVector());
    assert (!r2.getIndices());
  }
  
  // Test copy constructor and assignment operator
  {
    CoinIndexedVector rhs;
    {
      CoinIndexedVector r;
      {
	CoinIndexedVector rC1(r);      
	assert( 0==r.getNumElements() );
	assert( 0==rC1.getNumElements() );
	
	
	r.setVector( ne, inx, el ); 
	
	assert( ne==r.getNumElements() );
	assert( 0==rC1.getNumElements() ); 
      }
      
      CoinIndexedVector rC2(r);   
      
      assert( ne==r.getNumElements() );
      assert( ne==rC2.getNumElements() );
      
      for ( i=0; i<ne; i++ ) {
	assert( r.getIndices()[i] == rC2.getIndices()[i] );
      }
      
      rhs=rC2;
    }
    // Test that rhs has correct values even though lhs has gone out of scope
    assert( rhs.getNumElements()==ne );
    
    for ( i=0; i<ne; i++ ) {
      assert( inx[i] == rhs.getIndices()[i] );
    } 
  }
  
  // Test operator==
  {
    CoinIndexedVector v1,v2;
    assert( v1==v2 );
    assert( v2==v1 );
    assert( v1==v1 );
    assert( !(v1!=v2) );
    
    v1.setVector( ne, inx, el );
    assert ( !(v1==v2) );
    assert ( v1!=v2 );
    
    CoinIndexedVector v3(v1);
    assert( v3==v1 );
    assert( v3!=v2 );
    
    CoinIndexedVector v4(v2);
    assert( v4!=v1 );
    assert( v4==v2 );
  }
  
  {
    // Test sorting of indexed vectors    
    const int ne = 4;
    int inx[ne] = { 1, 4, 0, 2 };
    double el[ne] = { 10., 40., 1., 20. };
    CoinIndexedVector r;
    r.setVector(ne,inx,el);
    
    // Test that indices are in increasing order
    r.sort();
    for ( i=1; i<ne; i++ ) assert( r.getIndices()[i-1] < r.getIndices()[i] );

  }    
  {
    // Test operator[] and indexExists()
    const int ne = 4;
    int inx[ne] =   {  1,   4,  0,   2 };
    double el[ne] = { 10., 40., 1., 50. };
    CoinIndexedVector r;
    bool errorThrown = false;
    try {
      assert( r[1]==0. );
    }
    catch (CoinError& e) {
      errorThrown = true;
    }
    assert( errorThrown );
    
    r.setVector(ne,inx,el);
    
    errorThrown = false;
    try {
      assert( r[-1]==0. );
    }
    catch (CoinError& e) {
      errorThrown = true;
    }
    assert( errorThrown );
    
    assert( r[ 0]==1. );
    assert( r[ 1]==10.);
    assert( r[ 2]==50.);
    assert( r[ 3]==0. );
    assert( r[ 4]==40.);
    errorThrown = false;
    try {
      assert( r[5]==0. );
    }
    catch (CoinError& e) {
      errorThrown = true;
    }
    assert( errorThrown );
    
    assert ( r.getMaxIndex()==4 );
    assert ( r.getMinIndex()==0 );
  }
  
  // Test that attemping to get min/max index of a 0,
  // length vector 
  {
    CoinIndexedVector nullVec;
    assert( nullVec.getMaxIndex() == -COIN_INT_MAX/*0*/ );
    assert( nullVec.getMinIndex() == COIN_INT_MAX/*0*/ );
  } 
  
  // Test CoinFltEq with equivalent method
  {    
    const int ne = 4;
    int inx1[ne] = { 1, 3, 4, 7 };
    double el1[ne] = { 1.2, 3.4, 5.6, 7.8 };
    int inx2[ne] = { 7, 4, 3, 1 };
    double el2[ne] = { 7.8+.5, 5.6+.5, 3.4+.5, 1.2+.5 };
    CoinIndexedVector v1,v2;
    v1.setVector(ne,inx1,el1);
    v2.setVector(ne,inx2,el2);
  }
  
  {
    // Test reserve
    CoinIndexedVector v1,v2;
    assert( v1.capacity()==0 );
    v1.reserve(6);
    assert( v1.capacity()==6 );
    assert( v1.getNumElements()==0 );
    v2=v1;
    assert( v2.capacity() == 6 );
    assert( v2.getNumElements()==0 );
    assert( v2==v1 );
    v1.setVector(0,NULL,NULL);
    assert( v1.capacity()==6 );
    assert( v1.getNumElements()==0 );
    assert( v2==v1 );
    v2=v1;
    assert( v2.capacity() == 6 );
    assert( v2.getNumElements()==0 );
    assert( v2==v1 );
    
    const int ne = 2;
    int inx[ne] = { 1, 3 };
    double el[ne] = { 1.2, 3.4 };
    v1.setVector(ne,inx,el);
    assert( v1.capacity()==6 );
    assert( v1.getNumElements()==2 );
    v2=v1;
    assert( v2.capacity()==6 );
    assert( v2.getNumElements()==2 );
    assert( v2==v1 );
    
    const int ne1 = 5;
    int inx1[ne1] = { 1, 3, 4, 5, 6 };
    double el1[ne1] = { 1.2, 3.4, 5., 6., 7. };
    v1.setVector(ne1,inx1,el1);
    assert( v1.capacity()==7 );
    assert( v1.getNumElements()==5 );
    v2=v1;
    assert( v2.capacity()==7 );
    assert( v2.getNumElements()==5 );
    assert( v2==v1 );
    
    const int ne2 = 8;
    int inx2[ne2] = { 1, 3, 4, 5, 6, 7, 8, 9 };
    double el2[ne2] = { 1.2, 3.4, 5., 6., 7., 8., 9., 10. };
    v1.setVector(ne2,inx2,el2);
    assert( v1.capacity()==10 );
    assert( v1.getNumElements()==8 );
    v2=v1;
    assert( v2.getNumElements()==8 );    
    assert( v2==v1 );
    
    v1.setVector(ne1,inx1,el1);
    assert( v1.capacity()==10 );
    assert( v1.getNumElements()==5 );
    v2=v1;    
    assert( v2.capacity()==10 );
    assert( v2.getNumElements()==5 );
    assert( v2==v1 );
    
    v1.reserve(7);
    assert( v1.capacity()==10 );
    assert( v1.getNumElements()==5 );
    v2=v1;
    assert( v2.capacity()==10 );
    assert( v2.getNumElements()==5 );
    assert( v2==v1 );
    
  }
  
  // Test the insert method
  {
    CoinIndexedVector v1;
    assert( v1.getNumElements()==0 );
    assert( v1.capacity()==0 );
    
    v1.insert(1,1.);
    assert( v1.getNumElements()==1 );
    assert( v1.capacity()==2 );
    assert( v1.getIndices()[0] == 1 );
    
    v1.insert(10,10.);
    assert( v1.getNumElements()==2 );
    assert( v1.capacity()==11 );
    assert( v1.getIndices()[1] == 10 );
    
    v1.insert(20,20.);
    assert( v1.getNumElements()==3 );
    assert( v1.capacity()==21 );
    assert( v1.getIndices()[2] == 20 );
    
    v1.insert(30,30.);
    assert( v1.getNumElements()==4 );
    assert( v1.capacity()==31 );
    assert( v1.getIndices()[3] == 30 );

    v1.insert(40,40.);
    assert( v1.getNumElements()==5 );
    assert( v1.capacity()==41 );
    assert( v1.getIndices()[4] == 40 );
    
    v1.insert(50,50.);
    assert( v1.getNumElements()==6 );
    assert( v1.capacity()==51 );
    assert( v1.getIndices()[5] == 50 );
    
    CoinIndexedVector v2;
    const int ne1 = 3;
    int inx1[ne1] = { 1, 3, 4 };
    double el1[ne1] = { 1.2, 3.4, 5. };
    v2.setVector(ne1,inx1,el1);    
    assert( v2.getNumElements()==3 );
    assert( v2.capacity()==5 );

    // Test clean method - get rid of 1.2
    assert(v2.clean(3.0)==2);
    assert(v2.denseVector()[1]==0.0);

    // Below are purely for debug - so use assert
    // so we won't try with false
    // Test checkClean 
#ifndef NO_CHECK_CL
    v2.checkClean();
    assert( v2.getNumElements()==2 );

    // Get rid of all
    int numberRemaining = v2.clean(10.0);
    assert(numberRemaining==0);
    v2.checkClear();
#endif    
  }
  
  {
    //Test setConstant and setElement     
    CoinIndexedVector v2;
    const int ne1 = 3;
    int inx1[ne1] = { 1, 3, 4 };
    v2.setConstant(ne1,inx1,3.14);    
    assert( v2.getNumElements()==3 );
    assert( v2.capacity()==5 );
    assert( v2.getIndices()[0]==1 );
    assert( v2.getIndices()[1]==3 );
    assert( v2.getIndices()[2]==4 );
    
    assert( v2[3] == 3.14 );
    
    CoinIndexedVector v2X(ne1,inx1,3.14);
    assert( v2 == v2X );
    
  }
  
  {
    //Test setFull 
    CoinIndexedVector v2;
    const int ne2 = 3;
    double el2[ne2] = { 1., 3., 4. };
    v2.setFull(ne2,el2);    
    assert( v2.getNumElements()==3 );
    assert( v2.capacity()==3 );
    assert( v2.getIndices()[0]==0 );
    assert( v2.getIndices()[1]==1 );
    assert( v2.getIndices()[2]==2 );
    
    assert( v2[1] == 3. );
    
    CoinIndexedVector v2X(ne2,el2);
    assert( v2 == v2X ); 
    
    v2.setFull(0,el2); 
    assert( v2[2] == 0. );  
  }
  
  
#if 0
  // what happens when someone sets 
  // the number of elements to be a negative number
  {    
    const int ne = 4;
    int inx1[ne] = { 1, 3, 4, 7 };
    double el1[ne] = { 1.2, 3.4, 5.6, 7.8 };
    CoinIndexedVector v1;
    v1.set(-ne,inx1,el1);
  }
#endif
  
  
  // Test copy constructor from ShallowPackedVector
  {
    const int ne = 4;
    int inx[ne] =   {  1,   4,  0,   2 };
    double el[ne] = { 10., 40., 1., 50. };
    CoinIndexedVector std(ne,inx,el);
    CoinShallowPackedVector * spvP = new CoinShallowPackedVector(ne,inx,el);
    CoinIndexedVector pv(*spvP);
    assert( pv == std );
    delete spvP;
    assert( pv == std );
  }
  
  // Test assignment from ShallowPackedVector
  {
    const int ne = 4;
    int inx[ne] =   {  1,   4,  0,   2 };
    double el[ne] = { 10., 40., 1., 50. };
    CoinIndexedVector std(ne,inx,el);
    CoinShallowPackedVector * spvP = new CoinShallowPackedVector(ne,inx,el);
    CoinIndexedVector pv;
    pv = *spvP;
    assert( pv == std );
    delete spvP;
    assert( pv == std );
  }
  
  {
    // Test that sample usage works
    
    const int ne = 4;
    int inx[ne] =   {  1,   4,  0,   2 };
    double el[ne] = { 10., 40., 1., 50. };
    CoinIndexedVector r(ne,inx,el);
    
    assert( r.getIndices()[0]== 1  );
    assert( r.getIndices()[1]== 4  );
    assert( r.getIndices()[2]== 0  );
    assert( r.getIndices()[3]== 2  );
    
    assert( r[ 0]==1. );
    assert( r[ 1]==10.);
    assert( r[ 2]==50.);
    assert( r[ 3]==0. );
    assert( r[ 4]==40.);
    
    r.sortIncrElement();
    
    assert( r.getIndices()[0]== 0  );
    assert( r.getIndices()[1]== 1  );
    assert( r.getIndices()[2]== 4  );
    assert( r.getIndices()[3]== 2  );
    
    assert( r[ 0]==1. );
    assert( r[ 1]==10.);
    assert( r[ 2]==50.);
    assert( r[ 3]==0. );
    assert( r[ 4]==40.);
    
    CoinIndexedVector r1;
    r1=r;
    assert( r==r1 );
    
    CoinIndexedVector add = r + r1;
    assert( add[0] ==  1.+ 1. );
    assert( add[1] == 10.+10. );
    assert( add[2] == 50.+50. );
    assert( add[3] ==  0.+ 0. );
    assert( add[4] == 40.+40. );
    
  }
  
}
Beispiel #3
0
//--------------------------------------------------------------------------
void OsiColCutUnitTest(const OsiSolverInterface *baseSiP, const std::string &mpsDir)
{

  // Test default constructor
  {
    OsiColCut r;
    OSIUNITTEST_ASSERT_ERROR(r.lbs_.getIndices() == NULL, {}, "osicolcut", "default constructor");
    OSIUNITTEST_ASSERT_ERROR(r.lbs_.getElements() == NULL, {}, "osicolcut", "default constructor");
    OSIUNITTEST_ASSERT_ERROR(r.lbs_.getNumElements() == 0, {}, "osicolcut", "default constructor");
    OSIUNITTEST_ASSERT_ERROR(r.lbs().getNumElements() == 0, {}, "osicolcut", "default constructor");
    OSIUNITTEST_ASSERT_ERROR(r.ubs_.getIndices() == NULL, {}, "osicolcut", "default constructor");
    OSIUNITTEST_ASSERT_ERROR(r.ubs_.getElements() == NULL, {}, "osicolcut", "default constructor");
    OSIUNITTEST_ASSERT_ERROR(r.ubs_.getNumElements() == 0, {}, "osicolcut", "default constructor");
    OSIUNITTEST_ASSERT_ERROR(r.ubs().getNumElements() == 0, {}, "osicolcut", "default constructor");
  }

  // Test set and get methods
  const int ne = 4;
  int inx[ne] = { 1, 3, 4, 7 };
  double el[ne] = { 1.2, 3.4, 5.6, 7.8 };
  const int ne3 = 0;
  int *inx3 = NULL;
  double *el3 = NULL;
  {
    OsiColCut r;

    // Test setting/getting bounds
    r.setLbs(ne, inx, el);
    r.setEffectiveness(222.);
    OSIUNITTEST_ASSERT_ERROR(r.lbs().getNumElements() == ne, return, "osicolcut", "setting bounds");
    bool bounds_ok = true;
    for (int i = 0; i < ne; i++) {
      bounds_ok &= r.lbs().getIndices()[i] == inx[i];
      bounds_ok &= r.lbs().getElements()[i] == el[i];
    }
    OSIUNITTEST_ASSERT_ERROR(bounds_ok, {}, "osicolcut", "setting bounds");
    OSIUNITTEST_ASSERT_ERROR(r.effectiveness() == 222.0, {}, "osicolcut", "setting bounds");

    r.setUbs(ne3, inx3, el3);
    OSIUNITTEST_ASSERT_ERROR(r.ubs().getNumElements() == 0, {}, "osicolcut", "setting bounds");
    OSIUNITTEST_ASSERT_ERROR(r.ubs().getIndices() == NULL, {}, "osicolcut", "setting bounds");
    OSIUNITTEST_ASSERT_ERROR(r.ubs().getElements() == NULL, {}, "osicolcut", "setting bounds");
  }

  // Test copy constructor and assignment operator
  {
    OsiColCut rhs;
    {
      OsiColCut r;
      OsiColCut rC1(r);
      OSIUNITTEST_ASSERT_ERROR(rC1.lbs().getNumElements() == r.lbs().getNumElements(), {}, "osicolcut", "copy constructor");
      OSIUNITTEST_ASSERT_ERROR(rC1.ubs().getNumElements() == r.ubs().getNumElements(), {}, "osicolcut", "copy constructor");

      r.setLbs(ne, inx, el);
      r.setUbs(ne, inx, el);
      r.setEffectiveness(121.);

      OSIUNITTEST_ASSERT_ERROR(rC1.lbs().getNumElements() != r.lbs().getNumElements(), {}, "osicolcut", "copy constructor");
      OSIUNITTEST_ASSERT_ERROR(rC1.ubs().getNumElements() != r.lbs().getNumElements(), {}, "osicolcut", "copy constructor");

      OsiColCut rC2(r);
      OSIUNITTEST_ASSERT_ERROR(rC2.lbs().getNumElements() == r.lbs().getNumElements(), {}, "osicolcut", "copy constructor");
      OSIUNITTEST_ASSERT_ERROR(rC2.ubs().getNumElements() == r.ubs().getNumElements(), {}, "osicolcut", "copy constructor");
      OSIUNITTEST_ASSERT_ERROR(rC2.lbs().getNumElements() == ne, return, "osicolcut", "copy constructor");
      OSIUNITTEST_ASSERT_ERROR(rC2.ubs().getNumElements() == ne, return, "osicolcut", "copy constructor");
      bool bounds_ok = true;
      for (int i = 0; i < ne; i++) {
        bounds_ok &= rC2.lbs().getIndices()[i] == inx[i];
        bounds_ok &= rC2.lbs().getElements()[i] == el[i];
        bounds_ok &= rC2.ubs().getIndices()[i] == inx[i];
        bounds_ok &= rC2.ubs().getElements()[i] == el[i];
      }
      OSIUNITTEST_ASSERT_ERROR(bounds_ok, {}, "osicolcut", "copy constructor");
      OSIUNITTEST_ASSERT_ERROR(rC2.effectiveness() == 121.0, {}, "osicolcut", "copy constructor");

      rhs = rC2;
    }
    // Test that rhs has correct values even though lhs has gone out of scope
    OSIUNITTEST_ASSERT_ERROR(rhs.lbs().getNumElements() == ne, return, "osicolcut", "assignment operator");
    OSIUNITTEST_ASSERT_ERROR(rhs.ubs().getNumElements() == ne, return, "osicolcut", "assignment operator");
    bool bounds_ok = true;
    for (int i = 0; i < ne; i++) {
      bounds_ok &= rhs.lbs().getIndices()[i] == inx[i];
      bounds_ok &= rhs.lbs().getElements()[i] == el[i];
      bounds_ok &= rhs.ubs().getIndices()[i] == inx[i];
      bounds_ok &= rhs.ubs().getElements()[i] == el[i];
    }
    OSIUNITTEST_ASSERT_ERROR(bounds_ok, {}, "osicolcut", "assignment operator");
    OSIUNITTEST_ASSERT_ERROR(rhs.effectiveness() == 121.0, {}, "osicolcut", "assignment operator");
  }

  // Test setting bounds with packed vector and operator==
  {
    const int ne1 = 4;
    int inx1[ne] = { 1, 3, 4, 7 };
    double el1[ne] = { 1.2, 3.4, 5.6, 7.8 };
    const int ne2 = 2;
    int inx2[ne2] = { 1, 3 };
    double el2[ne2] = { 1.2, 3.4 };
    CoinPackedVector v1, v2;
    v1.setVector(ne1, inx1, el1);
    v2.setVector(ne2, inx2, el2);

    OsiColCut c1, c2;
    OSIUNITTEST_ASSERT_ERROR(c1 == c2, {}, "osicolcut", "setting bounds with packed vector and operator ==");
    OSIUNITTEST_ASSERT_ERROR(!(c1 != c2), {}, "osicolcut", "setting bounds with packed vector and operator !=");

    c1.setLbs(v1);
    OSIUNITTEST_ASSERT_ERROR(c1 != c2, {}, "osicolcut", "setting bounds with packed vector and operator !=");
    OSIUNITTEST_ASSERT_ERROR(!(c1 == c2), {}, "osicolcut", "setting bounds with packed vector and operator ==");
    OSIUNITTEST_ASSERT_ERROR(c1.lbs() == v1, {}, "osicolcut", "setting bounds with packed vector and operator !=");

    c1.setUbs(v2);
    OSIUNITTEST_ASSERT_ERROR(c1.ubs() == v2, {}, "osicolcut", "setting bounds with packed vector and operator !=");
    c1.setEffectiveness(3.);
    OSIUNITTEST_ASSERT_ERROR(c1.effectiveness() == 3.0, {}, "osicolcut", "setting bounds with packed vector and operator !=");

    {
      OsiColCut c3(c1);
      OSIUNITTEST_ASSERT_ERROR(c3 == c1, {}, "osicolcut", "operator ==");
      OSIUNITTEST_ASSERT_ERROR(!(c3 != c1), {}, "osicolcut", "operator !=");
    }
    {
      OsiColCut c3(c1);
      c3.setLbs(v2);
      OSIUNITTEST_ASSERT_ERROR(c3 != c1, {}, "osicolcut", "operator !=");
      OSIUNITTEST_ASSERT_ERROR(!(c3 == c1), {}, "osicolcut", "operator ==");
    }
    {
      OsiColCut c3(c1);
      c3.setUbs(v1);
      OSIUNITTEST_ASSERT_ERROR(c3 != c1, {}, "osicolcut", "operator !=");
      OSIUNITTEST_ASSERT_ERROR(!(c3 == c1), {}, "osicolcut", "operator ==");
    }
    {
      OsiColCut c3(c1);
      c3.setEffectiveness(5.);
      OSIUNITTEST_ASSERT_ERROR(c3 != c1, {}, "osicolcut", "operator !=");
      OSIUNITTEST_ASSERT_ERROR(!(c3 == c1), {}, "osicolcut", "operator ==");
    }
  }

  // internal consistency
  {
    const int ne = 1;
    int inx[ne] = { -3 };
    double el[ne] = { 1.2 };
    OsiColCut r;
    r.setLbs(ne, inx, el);
    OSIUNITTEST_ASSERT_ERROR(!r.consistent(), {}, "osicolcut", "consistent");
  }
  {
    const int ne = 1;
    int inx[ne] = { -3 };
    double el[ne] = { 1.2 };
    OsiColCut r;
    r.setUbs(ne, inx, el);
    OSIUNITTEST_ASSERT_ERROR(!r.consistent(), {}, "osicolcut", "consistent");
  }
  {
    const int ne = 1;
    int inx[ne] = { 100 };
    double el[ne] = { 1.2 };
    const int ne1 = 2;
    int inx1[ne1] = { 50, 100 };
    double el1[ne1] = { 100., 100. };
    OsiColCut r;
    r.setUbs(ne, inx, el);
    r.setLbs(ne1, inx1, el1);
    OSIUNITTEST_ASSERT_ERROR(r.consistent(), {}, "osicolcut", "consistent");

    OsiSolverInterface *imP = baseSiP->clone();
    assert(imP != NULL);
    std::string fn = mpsDir + "exmip1";
    imP->readMps(fn.c_str(), "mps");
    OSIUNITTEST_ASSERT_ERROR(!r.consistent(*imP), {}, "osicolcut", "consistent");
    delete imP;
  }
  {
    const int ne = 1;
    int inx[ne] = { 100 };
    double el[ne] = { 1.2 };
    const int ne1 = 2;
    int inx1[ne1] = { 50, 100 };
    double el1[ne1] = { 100., 1. };
    OsiColCut r;
    r.setUbs(ne, inx, el);
    r.setLbs(ne1, inx1, el1);
    OSIUNITTEST_ASSERT_ERROR(r.consistent(), {}, "osicolcut", "consistent");
  }
  {
    // Test consistent(IntegerModel) method.
    OsiSolverInterface *imP = baseSiP->clone();
    assert(imP != NULL);
    std::string fn = mpsDir + "exmip1";
    imP->readMps(fn.c_str(), "mps");

    OsiColCut cut;
    const int ne = 1;
    int inx[ne] = { 20 };
    double el[ne] = { 0.25 };
    cut.setLbs(ne, inx, el);
    OSIUNITTEST_ASSERT_ERROR(!cut.consistent(*imP), {}, "osicolcut", "consistent(IntegerModel)");

    cut.setLbs(0, NULL, NULL);
    cut.setUbs(ne, inx, el);
    OSIUNITTEST_ASSERT_ERROR(!cut.consistent(*imP), {}, "osicolcut", "consistent(IntegerModel)");

    inx[0] = 4;
    cut.setLbs(ne, inx, el);
    cut.setUbs(0, NULL, NULL);
    OSIUNITTEST_ASSERT_ERROR(cut.consistent(*imP), {}, "osicolcut", "consistent(IntegerModel)");

    el[0] = 4.5;
    cut.setLbs(0, NULL, NULL);
    cut.setUbs(ne, inx, el);
    OSIUNITTEST_ASSERT_ERROR(cut.consistent(*imP), {}, "osicolcut", "consistent(IntegerModel)");

    cut.setLbs(ne, inx, el);
    cut.setUbs(0, NULL, NULL);
    OSIUNITTEST_ASSERT_ERROR(cut.consistent(*imP), {}, "osicolcut", "consistent(IntegerModel)");
    OSIUNITTEST_ASSERT_ERROR(cut.infeasible(*imP), {}, "osicolcut", "infeasible(IntegerModel)");

    el[0] = 3.0;
    cut.setLbs(ne, inx, el);
    cut.setUbs(ne, inx, el);
    OSIUNITTEST_ASSERT_ERROR(cut.consistent(*imP), {}, "osicolcut", "consistent(IntegerModel)");
    delete imP;
  }
  {
    //Test infeasible(im) method
    // Test consistent(IntegerModel) method.
    OsiSolverInterface *imP = baseSiP->clone();
    assert(imP != NULL);
    std::string fn = mpsDir + "exmip1";
    imP->readMps(fn.c_str(), "mps");

    OsiColCut cut;
    const int ne = 1;
    int inx[ne] = { 4 };
    double el[ne] = { 4.5 };
    cut.setLbs(ne, inx, el);
    OSIUNITTEST_ASSERT_ERROR(cut.infeasible(*imP), {}, "osicolcut", "infeasible(IntegerModel)");

    el[0] = 0.25;
    cut.setLbs(0, NULL, NULL);
    cut.setUbs(ne, inx, el);
    OSIUNITTEST_ASSERT_ERROR(cut.infeasible(*imP), {}, "osicolcut", "infeasible(IntegerModel)");

    el[0] = 3.0;
    cut.setLbs(ne, inx, el);
    cut.setUbs(ne, inx, el);
    OSIUNITTEST_ASSERT_ERROR(!cut.infeasible(*imP), {}, "osicolcut", "infeasible(IntegerModel)");

    delete imP;
  }
  {
    //Test violation

    double solution[] = { 1.0 };
    OsiColCut cut;
    const int ne = 1;
    int inx[ne] = { 0 };
    double el[ne] = { 4.5 };
    cut.setLbs(ne, inx, el);
    OSIUNITTEST_ASSERT_ERROR(cut.violated(solution), {}, "osicolcut", "violated");

    el[0] = 0.25;
    cut.setLbs(0, NULL, NULL);
    cut.setUbs(ne, inx, el);
    OSIUNITTEST_ASSERT_ERROR(cut.violated(solution), {}, "osicolcut", "violated");

    el[0] = 1.0;
    cut.setLbs(ne, inx, el);
    cut.setUbs(ne, inx, el);
    OSIUNITTEST_ASSERT_ERROR(!cut.violated(solution), {}, "osicolcut", "violated");
  }
}