1 // Copyright (C) 2000, International Business Machines
2 // Corporation and others.  All Rights Reserved.
3 // This code is licensed under the terms of the Eclipse Public License (EPL).
4 
5 #if defined(_MSC_VER)
6 // Turn off compiler warning about long names
7 #  pragma warning(disable:4786)
8 #endif
9 
10 #ifdef NDEBUG
11 #undef NDEBUG
12 // checkClean and checkClear not define
13 #define NO_CHECK_CL
14 #endif
15 
16 #include <cassert>
17 
18 #include "CoinFinite.hpp"
19 #include "CoinIndexedVector.hpp"
20 #include "CoinShallowPackedVector.hpp"
21 
22 //--------------------------------------------------------------------------
23 void
CoinIndexedVectorUnitTest()24 CoinIndexedVectorUnitTest()
25 {
26 
27   int i;
28   // Test default constructor
29   {
30     CoinIndexedVector r;
31     assert( r.indices_==NULL );
32     assert( r.elements_==NULL );
33     assert( r.getNumElements()==0 );
34     assert( r.capacity_==0);
35   }
36 
37   // Test set and get methods
38   const int ne = 4;
39   int inx[ne] = { 1, 3, 4, 7 };
40   double el[ne] = { 1.2, 3.4, 5.6, 7.8 };
41   {
42     CoinIndexedVector r;
43     assert( r.getNumElements()==0 );
44 
45     // Test setting/getting elements with int* & float* vectors
46     r.setVector( ne, inx, el );
47     assert( r.getNumElements()==ne );
48     for ( i=0; i<ne; i++ ) {
49       assert( r.getIndices()[i]  == inx[i] );
50       assert( r[inx[i]]  == el[i] );
51     }
52 
53     // Test setting/getting elements with indices out of order
54     const int ne2 = 5;
55     int inx2[ne2] = { 2, 4, 8, 14, 3 };
56     double el2[ne2] = { 2.2, 4.4, 6.6, 8.8, 3.3 };
57 
58     r.setVector(ne2,inx2,el2);
59 
60     assert( r.getNumElements()==ne2 );
61 
62     assert( r.getIndices()[0]==inx2[0] );
63 
64     assert( r.getIndices()[1]==inx2[1] );
65 
66     assert( r.getIndices()[2]==inx2[2] );
67 
68     assert( r.getIndices()[3]==inx2[3] );
69 
70     assert( r.getIndices()[4]==inx2[4] );
71 
72 
73     CoinIndexedVector r1(ne2,inx2,el2);
74     assert( r == r1 );
75   }
76   CoinIndexedVector r;
77 
78 
79   {
80     CoinIndexedVector r;
81     const int ne = 3;
82     int inx[ne] = { 1, 2, 3 };
83     double el[ne] = { 2.2, 4.4, 8.8};
84     r.setVector(ne,inx,el);
85     int c = r.capacity();
86     // Test swap function
87     r.swap(0,2);
88     assert( r.getIndices()[0]==3 );
89     assert( r.getIndices()[1]==2 );
90     assert( r.getIndices()[2]==1 );
91     assert( r.capacity() == c );
92 
93     // Test the append function
94     CoinIndexedVector s;
95     const int nes = 4;
96     int inxs[nes] = { 11, 12, 13, 14 };
97     double els[nes] = { .122, 14.4, 18.8, 19.9};
98     s.setVector(nes,inxs,els);
99     r.append(s);
100     assert( r.getNumElements()==7 );
101     assert( r.getIndices()[0]==3 );
102     assert( r.getIndices()[1]==2 );
103     assert( r.getIndices()[2]==1 );
104     assert( r.getIndices()[3]==11 );
105     assert( r.getIndices()[4]==12 );
106     assert( r.getIndices()[5]==13 );
107     assert( r.getIndices()[6]==14 );
108 
109     // Test the resize function
110     c = r.capacity();
111     r.truncate(4);
112     // we will lose 11
113     assert( r.getNumElements()==3 );
114     assert( r.getIndices()[0]==3 );
115     assert( r.getIndices()[1]==2 );
116     assert( r.getIndices()[2]==1 );
117     assert( r.getMaxIndex() == 3 );
118     assert( r.getMinIndex() == 1 );
119     assert( r.capacity() == c );
120   }
121 
122   // Test borrow and return vector
123   {
124     CoinIndexedVector r,r2;
125     const int ne = 3;
126     int inx[ne] = { 1, 2, 3 };
127     double el[ne] = { 2.2, 4.4, 8.8};
128     double els[4] = { 0.0,2.2, 4.4, 8.8};
129     r.setVector(ne,inx,el);
130     r2.borrowVector(4,ne,inx,els);
131     assert (r==r2);
132     r2.returnVector();
133     assert (!r2.capacity());
134     assert (!r2.getNumElements());
135     assert (!r2.denseVector());
136     assert (!r2.getIndices());
137   }
138 
139   // Test copy constructor and assignment operator
140   {
141     CoinIndexedVector rhs;
142     {
143       CoinIndexedVector r;
144       {
145 	CoinIndexedVector rC1(r);
146 	assert( 0==r.getNumElements() );
147 	assert( 0==rC1.getNumElements() );
148 
149 
150 	r.setVector( ne, inx, el );
151 
152 	assert( ne==r.getNumElements() );
153 	assert( 0==rC1.getNumElements() );
154       }
155 
156       CoinIndexedVector rC2(r);
157 
158       assert( ne==r.getNumElements() );
159       assert( ne==rC2.getNumElements() );
160 
161       for ( i=0; i<ne; i++ ) {
162 	assert( r.getIndices()[i] == rC2.getIndices()[i] );
163       }
164 
165       rhs=rC2;
166     }
167     // Test that rhs has correct values even though lhs has gone out of scope
168     assert( rhs.getNumElements()==ne );
169 
170     for ( i=0; i<ne; i++ ) {
171       assert( inx[i] == rhs.getIndices()[i] );
172     }
173   }
174 
175   // Test operator==
176   {
177     CoinIndexedVector v1,v2;
178     assert( v1==v2 );
179     assert( v2==v1 );
180     assert( v1==v1 );
181     assert( !(v1!=v2) );
182 
183     v1.setVector( ne, inx, el );
184     assert ( !(v1==v2) );
185     assert ( v1!=v2 );
186 
187     CoinIndexedVector v3(v1);
188     assert( v3==v1 );
189     assert( v3!=v2 );
190 
191     CoinIndexedVector v4(v2);
192     assert( v4!=v1 );
193     assert( v4==v2 );
194   }
195 
196   {
197     // Test sorting of indexed vectors
198     const int ne = 4;
199     int inx[ne] = { 1, 4, 0, 2 };
200     double el[ne] = { 10., 40., 1., 20. };
201     CoinIndexedVector r;
202     r.setVector(ne,inx,el);
203 
204     // Test that indices are in increasing order
205     r.sort();
206     for ( i=1; i<ne; i++ ) assert( r.getIndices()[i-1] < r.getIndices()[i] );
207 
208   }
209   {
210     // Test operator[] and indexExists()
211     const int ne = 4;
212     int inx[ne] =   {  1,   4,  0,   2 };
213     double el[ne] = { 10., 40., 1., 50. };
214     CoinIndexedVector r;
215     bool errorThrown = false;
216     try {
217       assert( r[1]==0. );
218     }
219     catch (CoinError& e) {
220       errorThrown = true;
221     }
222     assert( errorThrown );
223 
224     r.setVector(ne,inx,el);
225 
226     errorThrown = false;
227     try {
228       assert( r[-1]==0. );
229     }
230     catch (CoinError& e) {
231       errorThrown = true;
232     }
233     assert( errorThrown );
234 
235     assert( r[ 0]==1. );
236     assert( r[ 1]==10.);
237     assert( r[ 2]==50.);
238     assert( r[ 3]==0. );
239     assert( r[ 4]==40.);
240     errorThrown = false;
241     try {
242       assert( r[5]==0. );
243     }
244     catch (CoinError& e) {
245       errorThrown = true;
246     }
247     assert( errorThrown );
248 
249     assert ( r.getMaxIndex()==4 );
250     assert ( r.getMinIndex()==0 );
251   }
252 
253   // Test that attemping to get min/max index of a 0,
254   // length vector
255   {
256     CoinIndexedVector nullVec;
257     assert( nullVec.getMaxIndex() == -COIN_INT_MAX/*0*/ );
258     assert( nullVec.getMinIndex() == COIN_INT_MAX/*0*/ );
259   }
260 
261   // Test CoinFltEq with equivalent method
262   {
263     const int ne = 4;
264     int inx1[ne] = { 1, 3, 4, 7 };
265     double el1[ne] = { 1.2, 3.4, 5.6, 7.8 };
266     int inx2[ne] = { 7, 4, 3, 1 };
267     double el2[ne] = { 7.8+.5, 5.6+.5, 3.4+.5, 1.2+.5 };
268     CoinIndexedVector v1,v2;
269     v1.setVector(ne,inx1,el1);
270     v2.setVector(ne,inx2,el2);
271   }
272 
273   {
274     // Test reserve
275     CoinIndexedVector v1,v2;
276     assert( v1.capacity()==0 );
277     v1.reserve(6);
278     assert( v1.capacity()==6 );
279     assert( v1.getNumElements()==0 );
280     v2=v1;
281     assert( v2.capacity() == 6 );
282     assert( v2.getNumElements()==0 );
283     assert( v2==v1 );
284     v1.setVector(0,NULL,NULL);
285     assert( v1.capacity()==6 );
286     assert( v1.getNumElements()==0 );
287     assert( v2==v1 );
288     v2=v1;
289     assert( v2.capacity() == 6 );
290     assert( v2.getNumElements()==0 );
291     assert( v2==v1 );
292 
293     const int ne = 2;
294     int inx[ne] = { 1, 3 };
295     double el[ne] = { 1.2, 3.4 };
296     v1.setVector(ne,inx,el);
297     assert( v1.capacity()==6 );
298     assert( v1.getNumElements()==2 );
299     v2=v1;
300     assert( v2.capacity()==6 );
301     assert( v2.getNumElements()==2 );
302     assert( v2==v1 );
303 
304     const int ne1 = 5;
305     int inx1[ne1] = { 1, 3, 4, 5, 6 };
306     double el1[ne1] = { 1.2, 3.4, 5., 6., 7. };
307     v1.setVector(ne1,inx1,el1);
308     assert( v1.capacity()==7 );
309     assert( v1.getNumElements()==5 );
310     v2=v1;
311     assert( v2.capacity()==7 );
312     assert( v2.getNumElements()==5 );
313     assert( v2==v1 );
314 
315     const int ne2 = 8;
316     int inx2[ne2] = { 1, 3, 4, 5, 6, 7, 8, 9 };
317     double el2[ne2] = { 1.2, 3.4, 5., 6., 7., 8., 9., 10. };
318     v1.setVector(ne2,inx2,el2);
319     assert( v1.capacity()==10 );
320     assert( v1.getNumElements()==8 );
321     v2=v1;
322     assert( v2.getNumElements()==8 );
323     assert( v2==v1 );
324 
325     v1.setVector(ne1,inx1,el1);
326     assert( v1.capacity()==10 );
327     assert( v1.getNumElements()==5 );
328     v2=v1;
329     assert( v2.capacity()==10 );
330     assert( v2.getNumElements()==5 );
331     assert( v2==v1 );
332 
333     v1.reserve(7);
334     assert( v1.capacity()==10 );
335     assert( v1.getNumElements()==5 );
336     v2=v1;
337     assert( v2.capacity()==10 );
338     assert( v2.getNumElements()==5 );
339     assert( v2==v1 );
340 
341   }
342 
343   // Test the insert method
344   {
345     CoinIndexedVector v1;
346     assert( v1.getNumElements()==0 );
347     assert( v1.capacity()==0 );
348 
349     v1.insert(1,1.);
350     assert( v1.getNumElements()==1 );
351     assert( v1.capacity()==2 );
352     assert( v1.getIndices()[0] == 1 );
353 
354     v1.insert(10,10.);
355     assert( v1.getNumElements()==2 );
356     assert( v1.capacity()==11 );
357     assert( v1.getIndices()[1] == 10 );
358 
359     v1.insert(20,20.);
360     assert( v1.getNumElements()==3 );
361     assert( v1.capacity()==21 );
362     assert( v1.getIndices()[2] == 20 );
363 
364     v1.insert(30,30.);
365     assert( v1.getNumElements()==4 );
366     assert( v1.capacity()==31 );
367     assert( v1.getIndices()[3] == 30 );
368 
369     v1.insert(40,40.);
370     assert( v1.getNumElements()==5 );
371     assert( v1.capacity()==41 );
372     assert( v1.getIndices()[4] == 40 );
373 
374     v1.insert(50,50.);
375     assert( v1.getNumElements()==6 );
376     assert( v1.capacity()==51 );
377     assert( v1.getIndices()[5] == 50 );
378 
379     CoinIndexedVector v2;
380     const int ne1 = 3;
381     int inx1[ne1] = { 1, 3, 4 };
382     double el1[ne1] = { 1.2, 3.4, 5. };
383     v2.setVector(ne1,inx1,el1);
384     assert( v2.getNumElements()==3 );
385     assert( v2.capacity()==5 );
386 
387     // Test clean method - get rid of 1.2
388     assert(v2.clean(3.0)==2);
389     assert(v2.denseVector()[1]==0.0);
390 
391     // Below are purely for debug - so use assert
392     // so we won't try with false
393     // Test checkClean
394 #ifndef NO_CHECK_CL
395     v2.checkClean();
396     assert( v2.getNumElements()==2 );
397 
398     // Get rid of all
399     int numberRemaining = v2.clean(10.0);
400     assert(numberRemaining==0);
401     v2.checkClear();
402 #endif
403   }
404 
405   {
406     //Test setConstant and setElement
407     CoinIndexedVector v2;
408     const int ne1 = 3;
409     int inx1[ne1] = { 1, 3, 4 };
410     v2.setConstant(ne1,inx1,3.14);
411     assert( v2.getNumElements()==3 );
412     assert( v2.capacity()==5 );
413     assert( v2.getIndices()[0]==1 );
414     assert( v2.getIndices()[1]==3 );
415     assert( v2.getIndices()[2]==4 );
416 
417     assert( v2[3] == 3.14 );
418 
419     CoinIndexedVector v2X(ne1,inx1,3.14);
420     assert( v2 == v2X );
421 
422   }
423 
424   {
425     //Test setFull
426     CoinIndexedVector v2;
427     const int ne2 = 3;
428     double el2[ne2] = { 1., 3., 4. };
429     v2.setFull(ne2,el2);
430     assert( v2.getNumElements()==3 );
431     assert( v2.capacity()==3 );
432     assert( v2.getIndices()[0]==0 );
433     assert( v2.getIndices()[1]==1 );
434     assert( v2.getIndices()[2]==2 );
435 
436     assert( v2[1] == 3. );
437 
438     CoinIndexedVector v2X(ne2,el2);
439     assert( v2 == v2X );
440 
441     v2.setFull(0,el2);
442     assert( v2[2] == 0. );
443   }
444 
445 
446 #if 0
447   // what happens when someone sets
448   // the number of elements to be a negative number
449   {
450     const int ne = 4;
451     int inx1[ne] = { 1, 3, 4, 7 };
452     double el1[ne] = { 1.2, 3.4, 5.6, 7.8 };
453     CoinIndexedVector v1;
454     v1.set(-ne,inx1,el1);
455   }
456 #endif
457 
458 
459   // Test copy constructor from ShallowPackedVector
460   {
461     const int ne = 4;
462     int inx[ne] =   {  1,   4,  0,   2 };
463     double el[ne] = { 10., 40., 1., 50. };
464     CoinIndexedVector std(ne,inx,el);
465     CoinShallowPackedVector * spvP = new CoinShallowPackedVector(ne,inx,el);
466     CoinIndexedVector pv(*spvP);
467     assert( pv == std );
468     delete spvP;
469     assert( pv == std );
470   }
471 
472   // Test assignment from ShallowPackedVector
473   {
474     const int ne = 4;
475     int inx[ne] =   {  1,   4,  0,   2 };
476     double el[ne] = { 10., 40., 1., 50. };
477     CoinIndexedVector std(ne,inx,el);
478     CoinShallowPackedVector * spvP = new CoinShallowPackedVector(ne,inx,el);
479     CoinIndexedVector pv;
480     pv = *spvP;
481     assert( pv == std );
482     delete spvP;
483     assert( pv == std );
484   }
485 
486   {
487     // Test that sample usage works
488 
489     const int ne = 4;
490     int inx[ne] =   {  1,   4,  0,   2 };
491     double el[ne] = { 10., 40., 1., 50. };
492     CoinIndexedVector r(ne,inx,el);
493 
494     assert( r.getIndices()[0]== 1  );
495     assert( r.getIndices()[1]== 4  );
496     assert( r.getIndices()[2]== 0  );
497     assert( r.getIndices()[3]== 2  );
498 
499     assert( r[ 0]==1. );
500     assert( r[ 1]==10.);
501     assert( r[ 2]==50.);
502     assert( r[ 3]==0. );
503     assert( r[ 4]==40.);
504 
505     r.sortIncrElement();
506 
507     assert( r.getIndices()[0]== 0  );
508     assert( r.getIndices()[1]== 1  );
509     assert( r.getIndices()[2]== 4  );
510     assert( r.getIndices()[3]== 2  );
511 
512     assert( r[ 0]==1. );
513     assert( r[ 1]==10.);
514     assert( r[ 2]==50.);
515     assert( r[ 3]==0. );
516     assert( r[ 4]==40.);
517 
518     CoinIndexedVector r1;
519     r1=r;
520     assert( r==r1 );
521 
522     CoinIndexedVector add = r + r1;
523     assert( add[0] ==  1.+ 1. );
524     assert( add[1] == 10.+10. );
525     assert( add[2] == 50.+50. );
526     assert( add[3] ==  0.+ 0. );
527     assert( add[4] == 40.+40. );
528 
529   }
530 
531 }
532 
533 
534 
535