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