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 #ifdef NDEBUG
6 #undef NDEBUG
7 #endif
8
9 #include <cassert>
10
11 #include "CoinPragma.hpp"
12 #include "CoinFloatEqual.hpp"
13 #include "CoinFinite.hpp"
14 #include "CoinPackedVector.hpp"
15 #include "CoinShallowPackedVector.hpp"
16
17 //--------------------------------------------------------------------------
18 void
CoinPackedVectorUnitTest()19 CoinPackedVectorUnitTest()
20 {
21
22 int i;
23 // Test default constructor
24 {
25 CoinPackedVector r;
26 assert( r.indices_==NULL );
27 assert( r.origIndices_==NULL );
28 assert( r.elements_==NULL );
29 assert( r.getNumElements()==0 );
30 assert( r.capacity_==0);
31 }
32
33 // Test set and get methods
34 const int ne = 4;
35 int inx[ne] = { 1, 3, 4, 7 };
36 double el[ne] = { 1.2, 3.4, 5.6, 7.8 };
37 {
38 CoinPackedVector r;
39 assert( r.getNumElements()==0 );
40
41 // Test setting/getting elements with int* & float* vectors
42 r.setVector( ne, inx, el );
43 assert( r.getNumElements()==ne );
44 for ( i=0; i<ne; i++ ) {
45 assert( r.getIndices()[i] == inx[i] );
46 assert( r.getOriginalPosition()[i] == i );
47 assert( r.getElements()[i] == el[i] );
48 }
49 assert ( r.getMaxIndex()==7 );
50 assert ( r.getMinIndex()==1 );
51
52 // Test setting/getting elements with indices out of order
53 const int ne2 = 5;
54 int inx2[ne2] = { 2, 4, 8, 14, 3 };
55 double el2[ne2] = { 2.2, 4.4, 6.6, 8.8, 3.3 };
56
57 r.setVector(ne2,inx2,el2);
58
59 assert( r.getNumElements()==ne2 );
60
61 assert( r.getIndices()[0]==inx2[0] );
62 assert( r.getOriginalPosition()[0]==0 );
63 assert( r.getElements()[0]==el2[0] );
64
65 assert( r.getIndices()[1]==inx2[1] );
66 assert( r.getOriginalPosition()[1]==1 );
67 assert( r.getElements()[1]==el2[1] );
68
69 assert( r.getIndices()[2]==inx2[2] );
70 assert( r.getOriginalPosition()[2]==2 );
71 assert( r.getElements()[2]==el2[2] );
72
73 assert( r.getIndices()[3]==inx2[3] );
74 assert( r.getOriginalPosition()[3]==3 );
75 assert( r.getElements()[3]==el2[3] );
76
77 assert( r.getIndices()[4]==inx2[4] );
78 assert( r.getOriginalPosition()[4]==4 );
79 assert( r.getElements()[4]==el2[4] );
80
81 assert ( r.getMaxIndex()==14 );
82 assert ( r.getMinIndex()==2 );
83 assert ( r.getMaxIndex()==14 );
84 assert ( r.getMinIndex()==2 );
85 {
86 bool errorThrown = false;
87 try {
88 r.duplicateIndex();
89 }
90 catch (CoinError& e) {
91 errorThrown = true;
92 }
93 assert( !errorThrown );
94 }
95
96 CoinPackedVector r1(ne2,inx2,el2,true);
97 assert( r == r1 );
98
99 // Test operator[] where index is duplicated
100 // Causes exception to be thrown
101 {
102 const int ne3 = 4;
103 int inx3[ne3] = { 2, 4, 2, 3 };
104 double el3[ne3] = { 2.2, 4.4, 8.8, 6.6 };
105 bool errorThrown = false;
106 try {
107 r.setVector(ne3,inx3,el3,true);
108 }
109 catch (CoinError& e) {
110 errorThrown = true;
111 }
112 assert( errorThrown );
113
114 errorThrown = false;
115 try {
116 r.duplicateIndex();
117 }
118 catch (CoinError& e) {
119 errorThrown = true;
120 }
121 assert( errorThrown );
122 }
123
124
125 // Test sorting by increasing elements
126 r.setVector(ne2,inx2,el2);
127 bool incr=true;
128 for ( i=1; i<ne2; i++ )
129 if ( r.getElements()[i-1]>r.getElements()[i] )
130 incr=false;
131 assert( !incr );
132 r.sortIncrElement();
133 incr = true;
134 for ( i=1; i<ne2; i++ )
135 if ( r.getElements()[i-1]>r.getElements()[i] )
136 incr=false;
137 assert( incr );
138
139 }
140
141
142 {
143 CoinPackedVector r;
144 const int ne = 3;
145 int inx[ne] = { 1, 2, 3 };
146 double el[ne] = { 2.2, 4.4, 8.8};
147 r.setVector(ne,inx,el);
148 int c = r.capacity();
149 int max = r.getMaxIndex();
150 int min = r.getMinIndex();
151 // Test swap function
152 r.swap(0,2);
153 assert( r.getIndices()[0]==3 );
154 assert( r.getIndices()[1]==2 );
155 assert( r.getIndices()[2]==1 );
156 assert( r.getElements()[0]==8.8 );
157 assert( r.getElements()[1]==4.4 );
158 assert( r.getElements()[2]==2.2 );
159 assert( r.getMaxIndex() == max );
160 assert( r.getMinIndex() == min );
161 assert( r.capacity() == c );
162
163 // Test the append function
164 CoinPackedVector s;
165 const int nes = 4;
166 int inxs[nes] = { 11, 12, 13, 14 };
167 double els[nes] = { .122, 14.4, 18.8, 19.9};
168 s.setVector(nes,inxs,els);
169 r.append(s);
170 assert( r.getNumElements()==7 );
171 assert( r.getIndices()[0]==3 );
172 assert( r.getIndices()[1]==2 );
173 assert( r.getIndices()[2]==1 );
174 assert( r.getIndices()[3]==11 );
175 assert( r.getIndices()[4]==12 );
176 assert( r.getIndices()[5]==13 );
177 assert( r.getIndices()[6]==14 );
178 assert( r.getElements()[0]==8.8 );
179 assert( r.getElements()[1]==4.4 );
180 assert( r.getElements()[2]==2.2 );
181 assert( r.getElements()[3]==.122 );
182 assert( r.getElements()[4]==14.4 );
183 assert( r.getElements()[5]==18.8 );
184 assert( r.getElements()[6]==19.9 );
185 assert( r.getMaxIndex() == 14 );
186 assert( r.getMinIndex() == 1 );
187
188 // Test the resize function
189 c = r.capacity();
190 r.truncate(4);
191 assert( r.getNumElements()==4 );
192 assert( r.getIndices()[0]==3 );
193 assert( r.getIndices()[1]==2 );
194 assert( r.getIndices()[2]==1 );
195 assert( r.getIndices()[3]==11 );
196 assert( r.getElements()[0]==8.8 );
197 assert( r.getElements()[1]==4.4 );
198 assert( r.getElements()[2]==2.2 );
199 assert( r.getElements()[3]==.122 );
200 assert( r.getMaxIndex() == 11 );
201 assert( r.getMinIndex() == 1 );
202 assert( r.capacity() == c );
203 }
204
205
206 // Test copy constructor and assignment operator
207 {
208 CoinPackedVector rhs;
209 {
210 CoinPackedVector r;
211 {
212 CoinPackedVector rC1(r);
213 assert( 0==r.getNumElements() );
214 assert( 0==rC1.getNumElements() );
215
216
217 r.setVector( ne, inx, el );
218
219 assert( ne==r.getNumElements() );
220 assert( 0==rC1.getNumElements() );
221 }
222
223 CoinPackedVector rC2(r);
224
225 assert( ne==r.getNumElements() );
226 assert( ne==rC2.getNumElements() );
227
228 for ( i=0; i<ne; i++ ) {
229 assert( r.getIndices()[i] == rC2.getIndices()[i] );
230 assert( r.getOriginalPosition()[i] == rC2.getOriginalPosition()[i] );
231 assert( r.getElements()[i] == rC2.getElements()[i] );
232 }
233
234 rhs=rC2;
235 }
236 // Test that rhs has correct values even though lhs has gone out of scope
237 assert( rhs.getNumElements()==ne );
238
239 for ( i=0; i<ne; i++ ) {
240 assert( inx[i] == rhs.getIndices()[i] );
241 assert( i == rhs.getOriginalPosition()[i] );
242 assert( el[i] == rhs.getElements()[i] );
243 }
244 }
245
246 // Test operator==
247 {
248 CoinPackedVector v1,v2;
249 assert( v1==v2 );
250 assert( v2==v1 );
251 assert( v1==v1 );
252 assert( !(v1!=v2) );
253 assert( v1.isEquivalent(v2) );
254 assert( v2.isEquivalent(v1) );
255 assert( v1.isEquivalent(v1) );
256
257 v1.setVector( ne, inx, el );
258 assert ( !(v1==v2) );
259 assert ( v1!=v2 );
260 assert( !v1.isEquivalent(v2) );
261
262 CoinPackedVector v3(v1);
263 assert( v3==v1 );
264 assert( v3!=v2 );
265 assert( v1.isEquivalent(v3) );
266 assert( v3.isEquivalent(v1) );
267
268 CoinPackedVector v4(v2);
269 assert( v4!=v1 );
270 assert( v4==v2 );
271 }
272
273 {
274 // Test sorting of packed vectors
275 const int ne = 4;
276 int inx[ne] = { 1, 4, 0, 2 };
277 double el[ne] = { 10., 40., 1., 20. };
278 double extSortKey[5] = { -20., 10., 5., 4., 20. };
279 CoinPackedVector r;
280 r.setVector(ne,inx,el);
281
282 // Test that indices are in increasing order
283 r.sortIncrIndex();
284 for ( i=1; i<ne; i++ ) assert( r.getIndices()[i-1] < r.getIndices()[i] );
285
286 // Sort by element values;
287 r.sortIncrElement();
288 for ( i=1; i<ne; i++ ) assert( r.getElements()[i-1] < r.getElements()[i] );
289
290 // Sort using indices into an external sort vector
291 CoinIncrSolutionOrdered pcSo(extSortKey);
292 r.sort(pcSo);
293 for ( i=1; i<ne; i++ )
294 assert( extSortKey[r.getIndices()[i-1]] < extSortKey[r.getIndices()[i]] );
295
296
297 // Now sort by indices.
298 r.sortIncrIndex();
299 for ( i=1; i<ne; i++ ) assert( r.getIndices()[i-1] < r.getIndices()[i] );
300 }
301
302
303 {
304 // Test operator[] and indexExists()
305 const int ne = 4;
306 int inx[ne] = { 1, 4, 0, 2 };
307 double el[ne] = { 10., 40., 1., 50. };
308 CoinPackedVector r;
309 assert( r[1]==0. );
310
311 r.setVector(ne,inx,el);
312
313 assert( r[-1]==0. );
314 assert( r[ 0]==1. );
315 assert( r[ 1]==10.);
316 assert( r[ 2]==50.);
317 assert( r[ 3]==0. );
318 assert( r[ 4]==40.);
319 assert( r[ 5]==0. );
320 assert( r.isExistingIndex(2) );
321 assert( !r.isExistingIndex(3) );
322
323 r.sortIncrElement();
324
325 assert( r[-1]==0. );
326 assert( r[ 0]==1. );
327 assert( r[ 1]==10.);
328 assert( r[ 2]==50.);
329 assert( r[ 3]==0. );
330 assert( r[ 4]==40.);
331 assert( r[ 5]==0. );
332 assert( !r.isExistingIndex(-1) );
333 assert( r.isExistingIndex(0) );
334 assert( !r.isExistingIndex(3) );
335 assert( r.isExistingIndex(4) );
336 assert( !r.isExistingIndex(5) );
337
338 assert ( r.getMaxIndex()==4 );
339 assert ( r.getMinIndex()==0 );
340 }
341
342 // Test that attemping to get min/max index of a 0,
343 // length vector
344 {
345 CoinPackedVector nullVec;
346 assert( nullVec.getMaxIndex() == -COIN_INT_MAX/*0*/ );
347 assert( nullVec.getMinIndex() == COIN_INT_MAX/*0*/ );
348 }
349
350 // Test CoinFltEq with equivalent method
351 {
352 const int ne = 4;
353 int inx1[ne] = { 1, 3, 4, 7 };
354 double el1[ne] = { 1.2, 3.4, 5.6, 7.8 };
355 int inx2[ne] = { 7, 4, 3, 1 };
356 double el2[ne] = { 7.8+.5, 5.6+.5, 3.4+.5, 1.2+.5 };
357 CoinPackedVector v1,v2;
358 v1.setVector(ne,inx1,el1);
359 v2.setVector(ne,inx2,el2);
360 assert( !v1.isEquivalent(v2) );
361 assert( v1.isEquivalent(v2,CoinAbsFltEq(.6)) );
362 assert( v1.isEquivalent(v2,CoinRelFltEq(.6)) );
363 }
364
365 {
366 // Test reserve
367 CoinPackedVector v1,v2;
368 assert( v1.capacity()==0 );
369 v1.reserve(6);
370 assert( v1.capacity()==6 );
371 assert( v1.getNumElements()==0 );
372 v2=v1;
373 assert( v2.capacity() == v2.getNumElements() );
374 assert( v2.getNumElements()==0 );
375 assert( v2==v1 );
376 v1.setVector(0,NULL,NULL);
377 assert( v1.capacity()==6 );
378 assert( v1.getNumElements()==0 );
379 assert( v2==v1 );
380 v2=v1;
381 assert( v2.capacity() == v2.getNumElements() );
382 assert( v2.getNumElements()==0 );
383 assert( v2==v1 );
384
385 const int ne = 2;
386 int inx[ne] = { 1, 3 };
387 double el[ne] = { 1.2, 3.4 };
388 v1.setVector(ne,inx,el);
389 assert( v1.capacity()==6 );
390 assert( v1.getNumElements()==2 );
391 v2=v1;
392 assert( v2.capacity()==v2.getNumElements() );
393 assert( v2.getNumElements()==2 );
394 assert( v2==v1 );
395
396 const int ne1 = 5;
397 int inx1[ne1] = { 1, 3, 4, 5, 6 };
398 double el1[ne1] = { 1.2, 3.4, 5., 6., 7. };
399 v1.setVector(ne1,inx1,el1);
400 assert( v1.capacity()==6 );
401 assert( v1.getNumElements()==5 );
402 v2=v1;
403 assert( v2.capacity()==v2.getNumElements() );
404 assert( v2.getNumElements()==5 );
405 assert( v2==v1 );
406
407 const int ne2 = 8;
408 int inx2[ne2] = { 1, 3, 4, 5, 6, 7, 8, 9 };
409 double el2[ne2] = { 1.2, 3.4, 5., 6., 7., 8., 9., 10. };
410 v1.setVector(ne2,inx2,el2);
411 assert( v1.capacity()==8 );
412 assert( v1.getNumElements()==8 );
413 v2=v1;
414 assert( v2.capacity()==v2.getNumElements() );
415 assert( v2.getNumElements()==8 );
416 assert( v2==v1 );
417
418 v1.setVector(ne1,inx1,el1);
419 assert( v1.capacity()==8 );
420 assert( v1.getNumElements()==5 );
421 v2=v1;
422 assert( v2.capacity()==8 );
423 assert( v2.getNumElements()==5 );
424 assert( v2==v1 );
425
426 v1.reserve(7);
427 assert( v1.capacity()==8 );
428 assert( v1.getNumElements()==5 );
429 v2=v1;
430 assert( v2.capacity()==8 );
431 assert( v2.getNumElements()==5 );
432 assert( v2==v1 );
433
434 }
435
436 // Test the insert method
437 {
438 CoinPackedVector v1(true);
439 assert( v1.getNumElements()==0 );
440 assert( v1.capacity()==0 );
441
442 assert( !v1.isExistingIndex(1) );
443 v1.insert(1,1.);
444 assert( v1.getNumElements()==1 );
445 assert( v1.capacity()==5 );
446 assert( v1.getIndices()[0] == 1 );
447 assert( v1.getElements()[0] == 1. );
448 assert( v1.isExistingIndex(1) );
449
450 assert( !v1.isExistingIndex(10) );
451 v1.insert(10,10.);
452 assert( v1.getNumElements()==2 );
453 assert( v1.capacity()==5 );
454 assert( v1.getIndices()[1] == 10 );
455 assert( v1.getElements()[1] == 10. );
456 assert( v1.isExistingIndex(1) );
457 assert( v1.isExistingIndex(10) );
458
459 assert( !v1.isExistingIndex(20) );
460 v1.insert(20,20.);
461 assert( v1.getNumElements()==3 );
462 assert( v1.capacity()==5 );
463 assert( v1.getIndices()[2] == 20 );
464 assert( v1.getElements()[2] == 20. );
465 assert( v1.isExistingIndex(20) );
466
467 assert( !v1.isExistingIndex(30) );
468 v1.insert(30,30.);
469 assert( v1.getNumElements()==4 );
470 assert( v1.capacity()==5 );
471 assert( v1.getIndices()[3] == 30 );
472 assert( v1.getElements()[3] == 30. );
473 assert( v1.isExistingIndex(30) );
474
475 assert( !v1.isExistingIndex(40) );
476 v1.insert(40,40.);
477 assert( v1.getNumElements()==5 );
478 assert( v1.capacity()==5 );
479 assert( v1.getIndices()[4] == 40 );
480 assert( v1.getElements()[4] == 40. );
481 assert( v1.isExistingIndex(40) );
482
483 assert( !v1.isExistingIndex(50) );
484 v1.insert(50,50.);
485 assert( v1.getNumElements()==6 );
486 assert( v1.capacity()==10 );
487 assert( v1.getIndices()[5] == 50 );
488 assert( v1.getElements()[5] == 50. );
489 assert( v1.isExistingIndex(50) );
490
491 CoinPackedVector v2;
492 const int ne1 = 3;
493 int inx1[ne1] = { 1, 3, 4 };
494 double el1[ne1] = { 1.2, 3.4, 5. };
495 v2.setVector(ne1,inx1,el1);
496 assert( v2.getNumElements()==3 );
497 assert( v2.capacity()==3 );
498
499 }
500
501 {
502 //Test setConstant and setElement
503 CoinPackedVector v2;
504 const int ne1 = 3;
505 int inx1[ne1] = { 1, 3, 4 };
506 v2.setConstant(ne1,inx1,3.14);
507 assert( v2.getNumElements()==3 );
508 assert( v2.capacity()==3 );
509 assert( v2.getIndices()[0]==1 );
510 assert( v2.getElements()[0]==3.14 );
511 assert( v2.getIndices()[1]==3 );
512 assert( v2.getElements()[1]==3.14 );
513 assert( v2.getIndices()[2]==4 );
514 assert( v2.getElements()[2]==3.14 );
515
516 assert( v2[3] == 3.14 );
517
518 CoinPackedVector v2X(ne1,inx1,3.14);
519 assert( v2 == v2X );
520
521 #if 0
522 v2.setElement( 1 , 100. );
523 assert( v2.getNumElements()==3 );
524 assert( v2.capacity()==3 );
525 assert( v2.getIndices()[0]==1 );
526 assert( v2.getElements()[0]==3.14 );
527 assert( v2.getIndices()[1]==3 );
528 assert( v2.getElements()[1]==100. );
529 assert( v2.getIndices()[2]==4 );
530 assert( v2.getElements()[2]==3.14 );
531
532 assert( v2[3] == 100. );
533
534 bool errorThrown = false;
535 try {
536 v2.setElement( 100, 100. );
537 }
538 catch (CoinError e) {
539 errorThrown = true;
540 }
541 assert( errorThrown );
542 #endif
543 }
544
545 {
546 //Test setFull
547 CoinPackedVector v2;
548 const int ne2 = 3;
549 double el2[ne2] = { 1., 3., 4. };
550 v2.setFull(ne2,el2);
551 assert( v2.getNumElements()==3 );
552 assert( v2.capacity()==3 );
553 assert( v2.getIndices()[0]==0 );
554 assert( v2.getElements()[0]==1. );
555 assert( v2.getIndices()[1]==1 );
556 assert( v2.getElements()[1]==3. );
557 assert( v2.getIndices()[2]==2 );
558 assert( v2.getElements()[2]==4. );
559
560 assert( v2[1] == 3. );
561
562 CoinPackedVector v2X(ne2,el2);
563 assert( v2 == v2X );
564
565 v2.setFull(0,el2);
566 assert( v2[2] == 0. );
567
568 // Test setFullNonZero
569 el2[1]=0.0;
570 v2.setFullNonZero(ne2,el2);
571 assert( v2.getNumElements()==2 );
572 assert( v2.capacity()==3 );
573 assert( v2.getIndices()[0]==0 );
574 assert( v2.getElements()[0]==1. );
575 assert( v2.getIndices()[1]==2 );
576 assert( v2.getElements()[1]==4. );
577
578 assert( v2[1] == 0. );
579
580 CoinPackedVector v2Y(ne2,el2);
581 assert( v2 != v2Y );
582 assert( v2 != v2X );
583
584 }
585
586
587 #if 0
588 // what happens when someone sets
589 // the number of elements to be a negative number
590 {
591 const int ne = 4;
592 int inx1[ne] = { 1, 3, 4, 7 };
593 double el1[ne] = { 1.2, 3.4, 5.6, 7.8 };
594 CoinPackedVector v1;
595 v1.set(-ne,inx1,el1);
596 }
597 #endif
598
599 // Test binaryOp method with addition, subtraction, multiplication, division. // Test adding vectors: v1+<empty>, <empty>+v1, v1+v2
600 {
601 const int ne1 = 5;
602 int inx1[ne1] = { 1, 3, 4, 7, 5 };
603 double el1[ne1] = { 1., 5., 6., 2., 9. };
604 const int ne2 = 4;
605 int inx2[ne2] = { 7, 4, 2, 1 };
606 double el2[ne2] = { 7., 4., 2., 1. };
607
608 CoinPackedVector v1;
609 CoinPackedVector v2;
610 CoinPackedVector r ;
611 CoinPackedVector rV ;
612
613 v1.setVector(ne1,inx1,el1);
614
615 rV.setVector(ne1,inx1,el1) ;
616 r = v1 + v2 ;
617 assert(r.isEquivalent(rV)) ;
618 r = v2 + v1 ;
619 assert(r.isEquivalent(rV)) ;
620
621 v2.setVector(ne2,inx2,el2);
622 r = v1 + v2 ;
623 const int ner = 6;
624 int inxr[ner] = { 1, 2, 3, 4, 5, 7 };
625 double elr[ner] = { 1.+1., 0.+2., 5.+0., 6.+4., 9.+0., 2.+7. };
626 rV.setVector(ner,inxr,elr);
627 assert( r.isEquivalent(rV) );
628
629 }
630
631 // Test subtracting vectors. Note that zeros are not automatically
632 // compressed out of the result.
633 {
634 const int ne1 = 5;
635 int inx1[ne1] = { 1, 3, 4, 7, 5 };
636 double el1[ne1] = { 1., 5., 6., 2., 9. };
637 const int ne2 = 4;
638 int inx2[ne2] = { 7, 4, 2, 1 };
639 double el2[ne2] = { 7., 4., 2., 1. };
640 CoinPackedVector v1;
641 v1.setVector(ne1,inx1,el1);
642 CoinPackedVector v2;
643 v2.setVector(ne2,inx2,el2);
644 CoinPackedVector r = v1 - v2;
645
646 const int ner = 6;
647 int inxr[ner] = { 1, 2, 3, 4, 5, 7 };
648 double elr[ner] = { 1.-1., 0.-2., 5.-0., 6.-4., 9.-0., 2.-7. };
649 CoinPackedVector rV;
650 rV.setVector(ner,inxr,elr);
651 assert( r.isEquivalent(rV) );
652 }
653
654 // Test multiplying vectors. Note that zeros are not automatically
655 // compressed out of the result.
656 {
657 const int ne1 = 5;
658 int inx1[ne1] = { 1, 3, 4, 7, 5 };
659 double el1[ne1] = { 1., 5., 6., 2., 9. };
660 const int ne2 = 4;
661 int inx2[ne2] = { 7, 4, 2, 1 };
662 double el2[ne2] = { 7., 4., 2., 1. };
663 CoinPackedVector v1;
664 v1.setVector(ne1,inx1,el1);
665 CoinPackedVector v2;
666 v2.setVector(ne2,inx2,el2);
667 CoinPackedVector r = v1 * v2;
668
669 const int ner = 6;
670 int inxr[ner] = { 1, 2, 3, 4, 5, 7 };
671 double elr[ner] = { 1.*1., 0.*2., 5.*0., 6.*4., 9.*0., 2.*7. };
672 CoinPackedVector rV;
673 rV.setVector(ner,inxr,elr);
674 assert( r.isEquivalent(rV) );
675 }
676
677 // Test dividing vectors. Note that zeros are not automatically compressed
678 // out of the result. Previously, used HUGE_VAL to get IEEE infinity, but
679 // this triggers a bug in some GCC compilers. -- lh, 061020 --
680 {
681 const int ne1 = 3;
682 int inx1[ne1] = { 1, 4, 7 };
683 double el1[ne1] = { 1., 6., 2. };
684 const int ne2 = 4;
685 int inx2[ne2] = { 7, 4, 2, 1 };
686 double el2[ne2] = { 7., 4., 2., 1. };
687
688 # ifdef COIN_C_FINITE
689 double one = 1.0 ;
690 double zero = 0.0 ;
691 double infty = one/zero ;
692 # else
693 double infty = COIN_DBL_MAX ;
694 # endif
695
696 CoinPackedVector v1;
697 CoinPackedVector v2;
698 CoinPackedVector r ;
699 CoinPackedVector rV;
700
701 v1.setVector(ne1,inx1,el1) ;
702 rV.setConstant(ne1,inx1,0) ;
703 r = v2 / v1;
704 assert(r.isEquivalent(rV)) ;
705 rV.setConstant(ne1,inx1,infty) ;
706 r = v1 / v2;
707 assert(r.isEquivalent(rV)) ;
708
709 r.isEquivalent(rV) ;
710
711 v2.setVector(ne2,inx2,el2);
712 r = v1 / v2;
713
714 const int ner = 4;
715 int inxr[ner] = { 1, 2, 4, 7 };
716 double elr[ner] = { 1./1., 0./2., 6./4., 2./7. };
717 rV.setVector(ner,inxr,elr);
718 assert( r.isEquivalent(rV) );
719 }
720
721 // Test sum
722 {
723 CoinPackedVector s;
724 assert( s.sum() == 0 );
725
726 s.insert(25,45.);
727 assert(s.sum()==45.);
728
729 const int ne1 = 5;
730 int inx1[ne1] = { 10, 3, 4, 7, 5 };
731 double el1[ne1] = { 1., 5., 6., 2., 9. };
732 s.setVector(ne1,inx1,el1);
733
734 assert(s.sum()==1.+5.+6.+2.+9.);
735 }
736
737 // Just another interesting test
738 {
739 // Create numerator vector
740 const int ne1 = 2;
741 int inx1[ne1] = { 1, 4 };
742 double el1[ne1] = { 1., 6. };
743 CoinPackedVector v1(ne1,inx1,el1);
744
745 // create denominator vector
746 const int ne2 = 3;
747 int inx2[ne2] = { 1, 2, 4 };
748 double el2[ne2] = { 1., 7., 4.};
749 CoinPackedVector v2(ne2,inx2,el2);
750
751 // Compute ratio
752 CoinPackedVector ratio = v1 / v2;
753
754 // Sort ratios
755 ratio.sortIncrElement();
756
757 // Test that the sort really worked
758 assert( ratio.getElements()[0] == 0.0/7.0 );
759 assert( ratio.getElements()[1] == 1.0/1.0 );
760 assert( ratio.getElements()[2] == 6.0/4.0 );
761
762 // Get numerator of of sorted ratio vector
763 assert( v1[ ratio.getIndices()[0] ] == 0.0 );
764 assert( v1[ ratio.getIndices()[1] ] == 1.0 );
765 assert( v1[ ratio.getIndices()[2] ] == 6.0 );
766
767 // Get denominator of of sorted ratio vector
768 assert( v2[ ratio.getIndices()[0] ] == 7.0 );
769 assert( v2[ ratio.getIndices()[1] ] == 1.0 );
770 assert( v2[ ratio.getIndices()[2] ] == 4.0 );
771 }
772
773 // Test copy constructor from ShallowPackedVector
774 {
775 const int ne = 4;
776 int inx[ne] = { 1, 4, 0, 2 };
777 double el[ne] = { 10., 40., 1., 50. };
778 CoinPackedVector std(ne,inx,el);
779 CoinShallowPackedVector * spvP = new CoinShallowPackedVector(ne,inx,el);
780 CoinPackedVector pv(*spvP);
781 assert( pv == std );
782 assert( pv.isEquivalent(std) );
783 delete spvP;
784 assert( pv == std );
785 assert( pv.isEquivalent(std) );
786 pv.sortIncrElement();
787 assert( pv != std );
788 assert( pv.isEquivalent(std) );
789 }
790
791 // Test assignment from ShallowPackedVector
792 {
793 const int ne = 4;
794 int inx[ne] = { 1, 4, 0, 2 };
795 double el[ne] = { 10., 40., 1., 50. };
796 CoinPackedVector std(ne,inx,el);
797 CoinShallowPackedVector * spvP = new CoinShallowPackedVector(ne,inx,el);
798 CoinPackedVector pv;
799 pv = *spvP;
800 assert( pv == std );
801 assert( pv.isEquivalent(std) );
802 delete spvP;
803 assert( pv == std );
804 assert( pv.isEquivalent(std) );
805 pv.sortIncrElement();
806 assert( pv != std );
807 assert( pv.isEquivalent(std) );
808 }
809
810 {
811 // Test that sample usage works
812
813 const int ne = 4;
814 int inx[ne] = { 1, 4, 0, 2 };
815 double el[ne] = { 10., 40., 1., 50. };
816 CoinPackedVector r(ne,inx,el);
817
818 assert( r.getIndices()[0]== 1 );
819 assert( r.getElements()[0]==10. );
820 assert( r.getIndices()[1]== 4 );
821 assert( r.getElements()[1]==40. );
822 assert( r.getIndices()[2]== 0 );
823 assert( r.getElements()[2]== 1. );
824 assert( r.getIndices()[3]== 2 );
825 assert( r.getElements()[3]==50. );
826
827 assert( r.getOriginalPosition()[0]==0 );
828 assert( r.getOriginalPosition()[1]==1 );
829 assert( r.getOriginalPosition()[2]==2 );
830 assert( r.getOriginalPosition()[3]==3 );
831
832 assert( r[ 0]==1. );
833 assert( r[ 1]==10.);
834 assert( r[ 2]==50.);
835 assert( r[ 3]==0. );
836 assert( r[ 4]==40.);
837
838 r.sortIncrElement();
839
840 assert( r.getIndices()[0]== 0 );
841 assert( r.getElements()[0]== 1. );
842 assert( r.getIndices()[1]== 1 );
843 assert( r.getElements()[1]==10. );
844 assert( r.getIndices()[2]== 4 );
845 assert( r.getElements()[2]==40. );
846 assert( r.getIndices()[3]== 2 );
847 assert( r.getElements()[3]==50. );
848
849 assert( r.getOriginalPosition()[0]==2 );
850 assert( r.getOriginalPosition()[1]==0 );
851 assert( r.getOriginalPosition()[2]==1 );
852 assert( r.getOriginalPosition()[3]==3 );
853
854 assert( r[ 0]==1. );
855 assert( r[ 1]==10.);
856 assert( r[ 2]==50.);
857 assert( r[ 3]==0. );
858 assert( r[ 4]==40.);
859
860 r.sortOriginalOrder();
861
862 assert( r.getIndices()[0]== 1 );
863 assert( r.getElements()[0]==10. );
864 assert( r.getIndices()[1]== 4 );
865 assert( r.getElements()[1]==40. );
866 assert( r.getIndices()[2]== 0 );
867 assert( r.getElements()[2]== 1. );
868 assert( r.getIndices()[3]== 2 );
869 assert( r.getElements()[3]==50. );
870
871 CoinPackedVector r1;
872 r1=r;
873 assert( r==r1 );
874 assert( r.isEquivalent(r1) );
875 r.sortIncrElement();
876 assert( r!=r1 );
877 assert( r.isEquivalent(r1) );
878
879 CoinPackedVector add = r + r1;
880 assert( add[0] == 1.+ 1. );
881 assert( add[1] == 10.+10. );
882 assert( add[2] == 50.+50. );
883 assert( add[3] == 0.+ 0. );
884 assert( add[4] == 40.+40. );
885
886 assert( r.sum() == 10.+40.+1.+50. );
887 }
888
889 {
890 // Test findIndex
891 const int ne = 4;
892 int inx[ne] = { 1, -4, 0, 2 };
893 double el[ne] = { 10., 40., 1., 50. };
894 CoinPackedVector r(ne,inx,el);
895
896 assert( r.findIndex(2) == 3 );
897 assert( r.findIndex(0) == 2 );
898 assert( r.findIndex(-4) == 1 );
899 assert( r.findIndex(1) == 0 );
900 assert( r.findIndex(3) == -1 );
901 }
902 #if 0
903 {
904 // Test construction with testing for duplicates as false
905 const int ne = 4;
906 int inx[ne] = { 1, -4, 0, 2 };
907 double el[ne] = { 10., 40., 1., 50. };
908 CoinPackedVector rT(ne,inx,el);
909 CoinPackedVector r(false);
910
911 assert( !r.isExistingIndex(1) );
912 r.insert(1,10.);
913
914 assert( !r.isExistingIndex(-4) );
915 r.insert(-4,20.);
916
917 assert( !r.isExistingIndex(0) );
918 r.insert(0,1.);
919
920 assert( r.isExistingIndex(-4) ); // This line is failing!!
921 // If r is constructed with true,
922 // then it does not fail
923 int neg4Index = r.findIndex(-4);
924 assert( neg4Index == 1 );
925 r.setElement(neg4Index, r.getElements()[neg4Index] + 20);
926
927 assert( !r.isExistingIndex(2) );
928 r.insert(2,50.);
929
930 assert( r == rT );
931 }
932 #endif
933
934 /*
935 Repeat various tests, using the constructor that takes ownership of the
936 vectors.
937 */
938 { const int neo = ne;
939 int *inxo = new int[neo];
940 double *elo = new double[neo];
941
942 for (i = 0 ; i < neo ; i++) inxo[i] = inx[i] ;
943 for (i = 0 ; i < neo ; i++) elo[i] = el[i] ;
944
945 CoinPackedVector r(neo,neo,inxo,elo);
946 assert( inxo == NULL ) ;
947 assert( elo == NULL ) ;
948
949 // Test getting elements with int* & float* vectors
950 assert( r.getNumElements()==ne );
951 for ( i=0; i<ne; i++ ) {
952 assert( r.getIndices()[i] == inx[i] );
953 assert( r.getOriginalPosition()[i] == i );
954 assert( r.getElements()[i] == el[i] );
955 }
956 assert ( r.getMaxIndex()==7 );
957 assert ( r.getMinIndex()==1 );
958
959 // Test setting/getting elements with indices out of order
960 const int ne2 = 5;
961 int inx2[ne2] = { 2, 4, 8, 14, 3 };
962 double el2[ne2] = { 2.2, 4.4, 6.6, 8.8, 3.3 };
963
964 r.setVector(ne2,inx2,el2);
965
966 assert( r.getNumElements()==ne2 );
967
968 assert( r.getIndices()[0]==inx2[0] );
969 assert( r.getOriginalPosition()[0]==0 );
970 assert( r.getElements()[0]==el2[0] );
971
972 assert( r.getIndices()[1]==inx2[1] );
973 assert( r.getOriginalPosition()[1]==1 );
974 assert( r.getElements()[1]==el2[1] );
975
976 assert( r.getIndices()[2]==inx2[2] );
977 assert( r.getOriginalPosition()[2]==2 );
978 assert( r.getElements()[2]==el2[2] );
979
980 assert( r.getIndices()[3]==inx2[3] );
981 assert( r.getOriginalPosition()[3]==3 );
982 assert( r.getElements()[3]==el2[3] );
983
984 assert( r.getIndices()[4]==inx2[4] );
985 assert( r.getOriginalPosition()[4]==4 );
986 assert( r.getElements()[4]==el2[4] );
987
988 assert ( r.getMaxIndex()==14 );
989 assert ( r.getMinIndex()==2 );
990 assert ( r.getMaxIndex()==14 );
991 assert ( r.getMinIndex()==2 );
992 {
993 bool errorThrown = false;
994 try {
995 r.duplicateIndex();
996 }
997 catch (CoinError& e) {
998 errorThrown = true;
999 }
1000 assert( !errorThrown );
1001 }
1002
1003 CoinPackedVector r1(ne2,inx2,el2,true);
1004 assert( r == r1 );
1005
1006 // Test operator[] where index is duplicated
1007 // Causes exception to be thrown
1008 {
1009 const int ne3 = 4;
1010 int inx3[ne3] = { 2, 4, 2, 3 };
1011 double el3[ne3] = { 2.2, 4.4, 8.8, 6.6 };
1012 bool errorThrown = false;
1013 try {
1014 r.setVector(ne3,inx3,el3,true);
1015 }
1016 catch (CoinError& e) {
1017 errorThrown = true;
1018 }
1019 assert( errorThrown );
1020
1021 errorThrown = false;
1022 try {
1023 r.duplicateIndex();
1024 }
1025 catch (CoinError& e) {
1026 errorThrown = true;
1027 }
1028 assert( errorThrown );
1029 }
1030
1031
1032
1033 // Test sorting by increasing elements
1034 r.setVector(ne2,inx2,el2);
1035 bool incr=true;
1036 for ( i=1; i<ne2; i++ )
1037 if ( r.getElements()[i-1]>r.getElements()[i] )
1038 incr=false;
1039 assert( !incr );
1040 r.sortIncrElement();
1041 incr = true;
1042 for ( i=1; i<ne2; i++ )
1043 if ( r.getElements()[i-1]>r.getElements()[i] )
1044 incr=false;
1045 assert( incr );
1046
1047 }
1048
1049 }
1050
1051