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 #endif
13 
14 #include <cassert>
15 
16 #include "CoinMpsIO.hpp"
17 #include "CoinFloatEqual.hpp"
18 
19 //#############################################################################
20 
21 //--------------------------------------------------------------------------
22 // test import methods
23 void
CoinMpsIOUnitTest(const std::string & mpsDir)24 CoinMpsIOUnitTest(const std::string & mpsDir)
25 {
26 
27   // Test default constructor
28   {
29     CoinMpsIO m;
30     assert( m.rowsense_==NULL );
31     assert( m.rhs_==NULL );
32     assert( m.rowrange_==NULL );
33     assert( m.matrixByRow_==NULL );
34     assert( m.matrixByColumn_==NULL );
35     assert( m.integerType_==NULL);
36     assert( !strcmp( m.getFileName() , "????"));
37     assert( !strcmp( m.getProblemName() , ""));
38     assert( !strcmp( m.objectiveName_ , ""));
39     assert( !strcmp( m.rhsName_ , ""));
40     assert( !strcmp( m.rangeName_ , ""));
41     assert( !strcmp( m.boundName_ , ""));
42   }
43 
44 
45   {
46     CoinRelFltEq eq;
47     CoinMpsIO m;
48     std::string fn = mpsDir+"exmip1";
49     int numErr = m.readMps(fn.c_str(),"mps");
50     assert( numErr== 0 );
51 
52     assert( !strcmp( m.problemName_ , "EXAMPLE"));
53     assert( !strcmp( m.objectiveName_ , "OBJ"));
54     assert( !strcmp( m.rhsName_ , "RHS1"));
55     assert( !strcmp( m.rangeName_ , "RNG1"));
56     assert( !strcmp( m.boundName_ , "BND1"));
57 
58      // Test language and re-use
59     m.newLanguage(CoinMessages::it);
60     m.messageHandler()->setPrefix(false);
61 
62     // This call should return an error indicating that the
63     // end-of-file was reached.
64     // This is because the file remains open to possibly read
65     // a quad. section.
66     numErr = m.readMps(fn.c_str(),"mps");
67     assert( numErr < 0 );
68 
69     // Test copy constructor and assignment operator
70     {
71       CoinMpsIO lhs;
72       {
73         CoinMpsIO im(m);
74 
75         CoinMpsIO imC1(im);
76         assert( imC1.getNumCols() == im.getNumCols() );
77         assert( imC1.getNumRows() == im.getNumRows() );
78 
79         CoinMpsIO imC2(im);
80         assert( imC2.getNumCols() == im.getNumCols() );
81         assert( imC2.getNumRows() == im.getNumRows() );
82 
83         lhs=imC2;
84       }
85       // Test that lhs has correct values even though rhs has gone out of scope
86 
87       assert( lhs.getNumCols() == m.getNumCols() );
88       assert( lhs.getNumRows() == m.getNumRows() );
89     }
90 
91 
92     {
93       CoinMpsIO dumSi(m);
94       int nc = dumSi.getNumCols();
95       int nr = dumSi.getNumRows();
96       const double * cl = dumSi.getColLower();
97       const double * cu = dumSi.getColUpper();
98       const double * rl = dumSi.getRowLower();
99       const double * ru = dumSi.getRowUpper();
100       assert( nc == 8 );
101       assert( nr == 5 );
102       assert( eq(cl[0],2.5) );
103       assert( eq(cl[1],0.0) );
104       assert( eq(cu[1],4.1) );
105       assert( eq(cu[2],1.0) );
106       assert( eq(rl[0],2.5) );
107       assert( eq(rl[4],3.0) );
108       assert( eq(ru[1],2.1) );
109       assert( eq(ru[4],15.0) );
110 
111       assert( !eq(cl[3],1.2345) );
112 
113       assert( !eq(cu[4],10.2345) );
114 
115       assert( eq( dumSi.getObjCoefficients()[0],  1.0) );
116       assert( eq( dumSi.getObjCoefficients()[1],  0.0) );
117       assert( eq( dumSi.getObjCoefficients()[2],  0.0) );
118       assert( eq( dumSi.getObjCoefficients()[3],  0.0) );
119       assert( eq( dumSi.getObjCoefficients()[4],  2.0) );
120       assert( eq( dumSi.getObjCoefficients()[5],  0.0) );
121       assert( eq( dumSi.getObjCoefficients()[6],  0.0) );
122       assert( eq( dumSi.getObjCoefficients()[7], -1.0) );
123 
124       dumSi.writeMps("CoinMpsIoTest.mps");//,0,0,1);
125     }
126 
127     // Read just written file
128     {
129       CoinMpsIO dumSi;
130       dumSi.readMps("CoinMpsIoTest");
131       int nc = dumSi.getNumCols();
132       int nr = dumSi.getNumRows();
133       const double * cl = dumSi.getColLower();
134       const double * cu = dumSi.getColUpper();
135       const double * rl = dumSi.getRowLower();
136       const double * ru = dumSi.getRowUpper();
137       assert( nc == 8 );
138       assert( nr == 5 );
139       assert( eq(cl[0],2.5) );
140       assert( eq(cl[1],0.0) );
141       assert( eq(cu[1],4.1) );
142       assert( eq(cu[2],1.0) );
143       assert( eq(rl[0],2.5) );
144       assert( eq(rl[4],3.0) );
145       assert( eq(ru[1],2.1) );
146       assert( eq(ru[4],15.0) );
147 
148       assert( !eq(cl[3],1.2345) );
149 
150       assert( !eq(cu[4],10.2345) );
151 
152       assert( eq( dumSi.getObjCoefficients()[0],  1.0) );
153       assert( eq( dumSi.getObjCoefficients()[1],  0.0) );
154       assert( eq( dumSi.getObjCoefficients()[2],  0.0) );
155       assert( eq( dumSi.getObjCoefficients()[3],  0.0) );
156       assert( eq( dumSi.getObjCoefficients()[4],  2.0) );
157       assert( eq( dumSi.getObjCoefficients()[5],  0.0) );
158       assert( eq( dumSi.getObjCoefficients()[6],  0.0) );
159       assert( eq( dumSi.getObjCoefficients()[7], -1.0) );
160     }
161 
162     // Test matrixByRow method
163     {
164       const CoinMpsIO si(m);
165       const CoinPackedMatrix * smP = si.getMatrixByRow();
166       // LL:      const CoinDumPackedMatrix * osmP = dynamic_cast<const CoinDumPackedMatrix*>(smP);
167       // LL: assert( osmP!=NULL );
168 
169       CoinRelFltEq eq;
170       const double * ev = smP->getElements();
171       assert( eq(ev[0],   3.0) );
172       assert( eq(ev[1],   1.0) );
173       assert( eq(ev[2],  -2.0) );
174       assert( eq(ev[3],  -1.0) );
175       assert( eq(ev[4],  -1.0) );
176       assert( eq(ev[5],   2.0) );
177       assert( eq(ev[6],   1.1) );
178       assert( eq(ev[7],   1.0) );
179       assert( eq(ev[8],   1.0) );
180       assert( eq(ev[9],   2.8) );
181       assert( eq(ev[10], -1.2) );
182       assert( eq(ev[11],  5.6) );
183       assert( eq(ev[12],  1.0) );
184       assert( eq(ev[13],  1.9) );
185 
186       const CoinBigIndex * mi = smP->getVectorStarts();
187       assert( mi[0]==0 );
188       assert( mi[1]==5 );
189       assert( mi[2]==7 );
190       assert( mi[3]==9 );
191       assert( mi[4]==11 );
192       assert( mi[5]==14 );
193 
194       const int * ei = smP->getIndices();
195       assert( ei[0]  ==  0 );
196       assert( ei[1]  ==  1 );
197       assert( ei[2]  ==  3 );
198       assert( ei[3]  ==  4 );
199       assert( ei[4]  ==  7 );
200       assert( ei[5]  ==  1 );
201       assert( ei[6]  ==  2 );
202       assert( ei[7]  ==  2 );
203       assert( ei[8]  ==  5 );
204       assert( ei[9]  ==  3 );
205       assert( ei[10] ==  6 );
206       assert( ei[11] ==  0 );
207       assert( ei[12] ==  4 );
208       assert( ei[13] ==  7 );
209 
210       assert( smP->getMajorDim() == 5 );
211       assert( smP->getNumElements() == 14 );
212 
213     }
214         // Test matrixByCol method
215     {
216 
217       const CoinMpsIO si(m);
218       const CoinPackedMatrix * smP = si.getMatrixByCol();
219       // LL:      const CoinDumPackedMatrix * osmP = dynamic_cast<const CoinDumPackedMatrix*>(smP);
220       // LL: assert( osmP!=NULL );
221 
222       CoinRelFltEq eq;
223       const double * ev = smP->getElements();
224       assert( eq(ev[0],   3.0) );
225       assert( eq(ev[1],   5.6) );
226       assert( eq(ev[2],   1.0) );
227       assert( eq(ev[3],   2.0) );
228       assert( eq(ev[4],   1.1) );
229       assert( eq(ev[5],   1.0) );
230       assert( eq(ev[6],  -2.0) );
231       assert( eq(ev[7],   2.8) );
232       assert( eq(ev[8],  -1.0) );
233       assert( eq(ev[9],   1.0) );
234       assert( eq(ev[10],  1.0) );
235       assert( eq(ev[11], -1.2) );
236       assert( eq(ev[12], -1.0) );
237       assert( eq(ev[13],  1.9) );
238 
239       const CoinBigIndex * mi = smP->getVectorStarts();
240       assert( mi[0]==0 );
241       assert( mi[1]==2 );
242       assert( mi[2]==4 );
243       assert( mi[3]==6 );
244       assert( mi[4]==8 );
245       assert( mi[5]==10 );
246       assert( mi[6]==11 );
247       assert( mi[7]==12 );
248       assert( mi[8]==14 );
249 
250       const int * ei = smP->getIndices();
251       assert( ei[0]  ==  0 );
252       assert( ei[1]  ==  4 );
253       assert( ei[2]  ==  0 );
254       assert( ei[3]  ==  1 );
255       assert( ei[4]  ==  1 );
256       assert( ei[5]  ==  2 );
257       assert( ei[6]  ==  0 );
258       assert( ei[7]  ==  3 );
259       assert( ei[8]  ==  0 );
260       assert( ei[9]  ==  4 );
261       assert( ei[10] ==  2 );
262       assert( ei[11] ==  3 );
263       assert( ei[12] ==  0 );
264       assert( ei[13] ==  4 );
265 
266       assert( smP->getMajorDim() == 8 );
267       assert( smP->getNumElements() == 14 );
268 
269       assert( smP->getSizeVectorStarts()==9 );
270       assert( smP->getMinorDim() == 5 );
271 
272     }
273     //--------------
274     // Test rowsense, rhs, rowrange, matrixByRow
275     {
276       CoinMpsIO lhs;
277       {
278         assert( m.rowrange_==NULL );
279         assert( m.rowsense_==NULL );
280         assert( m.rhs_==NULL );
281         assert( m.matrixByRow_==NULL );
282 
283         CoinMpsIO siC1(m);
284         assert( siC1.rowrange_==NULL );
285         assert( siC1.rowsense_==NULL );
286         assert( siC1.rhs_==NULL );
287         assert( siC1.matrixByRow_==NULL );
288 
289         const char   * siC1rs  = siC1.getRowSense();
290         assert( siC1rs[0]=='G' );
291         assert( siC1rs[1]=='L' );
292         assert( siC1rs[2]=='E' );
293         assert( siC1rs[3]=='R' );
294         assert( siC1rs[4]=='R' );
295 
296         const double * siC1rhs = siC1.getRightHandSide();
297         assert( eq(siC1rhs[0],2.5) );
298         assert( eq(siC1rhs[1],2.1) );
299         assert( eq(siC1rhs[2],4.0) );
300         assert( eq(siC1rhs[3],5.0) );
301         assert( eq(siC1rhs[4],15.) );
302 
303         const double * siC1rr  = siC1.getRowRange();
304         assert( eq(siC1rr[0],0.0) );
305         assert( eq(siC1rr[1],0.0) );
306         assert( eq(siC1rr[2],0.0) );
307         assert( eq(siC1rr[3],5.0-1.8) );
308         assert( eq(siC1rr[4],15.0-3.0) );
309 
310         const CoinPackedMatrix * siC1mbr = siC1.getMatrixByRow();
311         assert( siC1mbr != NULL );
312 
313         const double * ev = siC1mbr->getElements();
314         assert( eq(ev[0],   3.0) );
315         assert( eq(ev[1],   1.0) );
316         assert( eq(ev[2],  -2.0) );
317         assert( eq(ev[3],  -1.0) );
318         assert( eq(ev[4],  -1.0) );
319         assert( eq(ev[5],   2.0) );
320         assert( eq(ev[6],   1.1) );
321         assert( eq(ev[7],   1.0) );
322         assert( eq(ev[8],   1.0) );
323         assert( eq(ev[9],   2.8) );
324         assert( eq(ev[10], -1.2) );
325         assert( eq(ev[11],  5.6) );
326         assert( eq(ev[12],  1.0) );
327         assert( eq(ev[13],  1.9) );
328 
329         const CoinBigIndex * mi = siC1mbr->getVectorStarts();
330         assert( mi[0]==0 );
331         assert( mi[1]==5 );
332         assert( mi[2]==7 );
333         assert( mi[3]==9 );
334         assert( mi[4]==11 );
335         assert( mi[5]==14 );
336 
337         const int * ei = siC1mbr->getIndices();
338         assert( ei[0]  ==  0 );
339         assert( ei[1]  ==  1 );
340         assert( ei[2]  ==  3 );
341         assert( ei[3]  ==  4 );
342         assert( ei[4]  ==  7 );
343         assert( ei[5]  ==  1 );
344         assert( ei[6]  ==  2 );
345         assert( ei[7]  ==  2 );
346         assert( ei[8]  ==  5 );
347         assert( ei[9]  ==  3 );
348         assert( ei[10] ==  6 );
349         assert( ei[11] ==  0 );
350         assert( ei[12] ==  4 );
351         assert( ei[13] ==  7 );
352 
353         assert( siC1mbr->getMajorDim() == 5 );
354         assert( siC1mbr->getNumElements() == 14 );
355 
356 
357         assert( siC1rs  == siC1.getRowSense() );
358         assert( siC1rhs == siC1.getRightHandSide() );
359         assert( siC1rr  == siC1.getRowRange() );
360       }
361     }
362 
363 	//test special sections: SOS, QUADOBJ, CSECTION
364 	{
365 	    CoinMpsIO m_MpsData;
366 		std::string fn = mpsDir+"spec_sections";
367 		int nOfSOS;
368 		CoinSet ** SOS;
369 		int status = m_MpsData.readMps(fn.c_str(),"mps", nOfSOS, SOS);
370 
371 		assert (status == 0);
372 
373 		assert (nOfSOS == 2);
374 
375 		assert (SOS[0]->numberEntries() == 2);
376 		assert (SOS[1]->numberEntries() == 2);
377 		assert (SOS[0]->setType() == 1);
378 		assert (SOS[1]->setType() == 2);
379 
380 		{
381 		    int numberEntries = SOS[0]->numberEntries();
382 			const int * which = SOS[0]->which();
383 			const double * weights = SOS[0]->weights();
384 			assert (which[0] == 2);
385 			assert (which[1] == 3);
386 			assert (weights[0] == 0);
387 			assert (weights[1] == 1);
388 		}
389 
390 		{
391 		    int numberEntries = SOS[1]->numberEntries();
392 			const int * which = SOS[1]->which();
393 			const double * weights = SOS[1]->weights();
394 			assert (which[0] == 4);
395 			assert (which[1] == 5);
396 			assert (weights[0] == 20);
397 			assert (weights[1] == 40);
398 		}
399 
400 		int * columnStart = NULL;
401 		int * columnIdx = NULL;
402 		double * elements = NULL;
403 		status = m_MpsData.readQuadraticMps(NULL, columnStart, columnIdx, elements, 0);
404 
405 		assert (status == 0);
406 
407 		assert (columnStart[ 0] == 0);
408 		assert (columnStart[ 1] == 0);
409 		assert (columnStart[ 2] == 0);
410 		assert (columnStart[ 3] == 0);
411 		assert (columnStart[ 4] == 0);
412 		assert (columnStart[ 5] == 0);
413 		assert (columnStart[ 6] == 0);
414 		assert (columnStart[ 7] == 2);
415 		assert (columnStart[ 8] == 3);
416 		assert (columnStart[ 9] == 3);
417 		assert (columnStart[10] == 3);
418 		assert (columnStart[11] == 3);
419 		assert (columnStart[12] == 3);
420 		assert (columnStart[13] == 3);
421 		assert (columnStart[14] == 3);
422 		assert (columnStart[15] == 3);
423 
424 		assert (columnIdx[0] == 6);
425 		assert (columnIdx[1] == 7);
426 		assert (columnIdx[2] == 7);
427 
428 		assert (elements[0] == 1.0);
429 		assert (elements[1] == 2.0);
430 		assert (elements[2] == 7.0);
431 
432 		int nOfCones;
433 		int * coneStart = NULL;
434 		int * coneIdx = NULL;
435 		int * coneType = NULL;
436 		status = m_MpsData.readConicMps(NULL, coneStart, coneIdx, coneType, nOfCones);
437 
438 		assert (status == 0);
439 
440 		assert (nOfCones == 2);
441 
442 		assert (coneType[0] == 1);
443 		assert (coneType[1] == 2);
444 
445 		assert (coneStart[0] == 0);
446 		assert (coneStart[1] == 3);
447 		assert (coneStart[2] == 7);
448 
449 		assert (coneStart[0] == 0);
450 		assert (coneStart[1] == 3);
451 		assert (coneStart[2] == 7);
452 
453 		assert (coneIdx[0] ==  8);
454 		assert (coneIdx[1] ==  9);
455 		assert (coneIdx[2] == 10);
456 		assert (coneIdx[3] == 11);
457 		assert (coneIdx[4] == 12);
458 		assert (coneIdx[5] == 13);
459 		assert (coneIdx[6] == 14);
460 	}
461 
462 #ifdef COIN_HAS_GLPK
463     // test GMPL reader
464     {
465       CoinMessageHandler msghandler;
466       CoinMpsIO mpsio;
467       mpsio.passInMessageHandler(&msghandler);
468       int ret = mpsio.readGMPL("plan.mod", NULL, true);
469       printf("read plan.mod with return == %d\n", ret);
470       assert(ret == 0);
471 
472       int nc = mpsio.getNumCols();
473       int nr = mpsio.getNumRows();
474       const double * cl = mpsio.getColLower();
475       const double * cu = mpsio.getColUpper();
476       const double * rl = mpsio.getRowLower();
477       const double * ru = mpsio.getRowUpper();
478       const double * obj = mpsio.getObjCoefficients();
479       assert( nc == 7 );
480       assert( nr == 8 );
481 
482       assert( eq(cl[0],0) );
483       assert( eq(cl[1],0) );
484       assert( eq(cl[2],400) );
485       assert( eq(cl[3],100) );
486       assert( eq(cl[4],0) );
487       assert( eq(cl[5],0) );
488       assert( eq(cl[6],0) );
489 
490       assert( eq(cu[0],200) );
491       assert( eq(cu[1],2500) );
492       assert( eq(cu[2],800) );
493       assert( eq(cu[3],700) );
494       assert( eq(cu[4],1500) );
495       assert( eq(cu[5],mpsio.getInfinity()) );
496       assert( eq(cu[6],mpsio.getInfinity()) );
497 
498       assert( eq(rl[0],-mpsio.getInfinity()) );
499       assert( eq(rl[1],2000) );
500       assert( eq(rl[2],-mpsio.getInfinity()) );
501       assert( eq(rl[3],-mpsio.getInfinity()) );
502       assert( eq(rl[4],-mpsio.getInfinity()) );
503       assert( eq(rl[5],-mpsio.getInfinity()) );
504       assert( eq(rl[6],1500) );
505       assert( eq(rl[7],250) );
506 
507       assert( eq(ru[0],mpsio.getInfinity()) );
508       assert( eq(ru[1],2000) );
509       assert( eq(ru[2],60) );
510       assert( eq(ru[3],100) );
511       assert( eq(ru[4],40) );
512       assert( eq(ru[5],30) );
513       assert( eq(ru[6],mpsio.getInfinity()) );
514       assert( eq(ru[7],300) );
515 
516       assert( eq(obj[0],0.03) );
517       assert( eq(obj[1],0.08) );
518       assert( eq(obj[2],0.17) );
519       assert( eq(obj[3],0.12) );
520       assert( eq(obj[4],0.15) );
521       assert( eq(obj[5],0.21) );
522       assert( eq(obj[6],0.38) );
523 
524       const CoinPackedMatrix * matrix = mpsio.getMatrixByRow();
525       assert( matrix != NULL );
526       assert( matrix->getMajorDim() == nr );
527 
528       int nel = matrix->getNumElements();
529       assert( nel == 48 );
530 
531       const double * ev = matrix->getElements();
532       assert( ev != NULL );
533       const int * ei = matrix->getIndices();
534       assert( ei != NULL );
535       const CoinBigIndex * mi = matrix->getVectorStarts();
536       assert( mi != NULL );
537 
538       assert( eq(ev[0],0.03) );
539       assert( eq(ev[1],0.08) );
540       assert( eq(ev[2],0.17) );
541       assert( eq(ev[3],0.12) );
542       assert( eq(ev[4],0.15) );
543       assert( eq(ev[5],0.21) );
544       assert( eq(ev[6],0.38) );
545       assert( eq(ev[7],1) );
546       assert( eq(ev[8],1) );
547       assert( eq(ev[9],1) );
548       assert( eq(ev[10],1) );
549       assert( eq(ev[11],1) );
550       assert( eq(ev[12],1) );
551       assert( eq(ev[13],1) );
552       assert( eq(ev[14],0.15) );
553       assert( eq(ev[15],0.04) );
554       assert( eq(ev[16],0.02) );
555       assert( eq(ev[17],0.04) );
556       assert( eq(ev[18],0.02) );
557       assert( eq(ev[19],0.01) );
558       assert( eq(ev[20],0.03) );
559       assert( eq(ev[21],0.03) );
560       assert( eq(ev[22],0.05) );
561       assert( eq(ev[23],0.08) );
562       assert( eq(ev[24],0.02) );
563       assert( eq(ev[25],0.06) );
564       assert( eq(ev[26],0.01) );
565       assert( eq(ev[27],0.02) );
566       assert( eq(ev[28],0.04) );
567       assert( eq(ev[29],0.01) );
568       assert( eq(ev[30],0.02) );
569       assert( eq(ev[31],0.02) );
570       assert( eq(ev[32],0.02) );
571       assert( eq(ev[33],0.03) );
572       assert( eq(ev[34],0.01) );
573       assert( eq(ev[35],0.7) );
574       assert( eq(ev[36],0.75) );
575       assert( eq(ev[37],0.8) );
576       assert( eq(ev[38],0.75) );
577       assert( eq(ev[39],0.8) );
578       assert( eq(ev[40],0.97) );
579       assert( eq(ev[41],0.02) );
580       assert( eq(ev[42],0.06) );
581       assert( eq(ev[43],0.08) );
582       assert( eq(ev[44],0.12) );
583       assert( eq(ev[45],0.02) );
584       assert( eq(ev[46],0.01) );
585       assert( eq(ev[47],0.97) );
586 
587       assert( ei[0] == 0 );
588       assert( ei[1] == 1 );
589       assert( ei[2] == 2 );
590       assert( ei[3] == 3 );
591       assert( ei[4] == 4 );
592       assert( ei[5] == 5 );
593       assert( ei[6] == 6 );
594       assert( ei[7] == 0 );
595       assert( ei[8] == 1 );
596       assert( ei[9] == 2 );
597       assert( ei[10] == 3 );
598       assert( ei[11] == 4 );
599       assert( ei[12] == 5 );
600       assert( ei[13] == 6 );
601       assert( ei[14] == 0 );
602       assert( ei[15] == 1 );
603       assert( ei[16] == 2 );
604       assert( ei[17] == 3 );
605       assert( ei[18] == 4 );
606       assert( ei[19] == 5 );
607       assert( ei[20] == 6 );
608       assert( ei[21] == 0 );
609       assert( ei[22] == 1 );
610       assert( ei[23] == 2 );
611       assert( ei[24] == 3 );
612       assert( ei[25] == 4 );
613       assert( ei[26] == 5 );
614       assert( ei[27] == 0 );
615       assert( ei[28] == 1 );
616       assert( ei[29] == 2 );
617       assert( ei[30] == 3 );
618       assert( ei[31] == 4 );
619       assert( ei[32] == 0 );
620       assert( ei[33] == 1 );
621       assert( ei[34] == 4 );
622       assert( ei[35] == 0 );
623       assert( ei[36] == 1 );
624       assert( ei[37] == 2 );
625       assert( ei[38] == 3 );
626       assert( ei[39] == 4 );
627       assert( ei[40] == 5 );
628       assert( ei[41] == 0 );
629       assert( ei[42] == 1 );
630       assert( ei[43] == 2 );
631       assert( ei[44] == 3 );
632       assert( ei[45] == 4 );
633       assert( ei[46] == 5 );
634       assert( ei[47] == 6 );
635 
636       assert( mi[0] == 0 );
637       assert( mi[1] == 7 );
638       assert( mi[2] == 14 );
639       assert( mi[3] == 21 );
640       assert( mi[4] == 27 );
641       assert( mi[5] == 32 );
642       assert( mi[6] == 35 );
643       assert( mi[7] == 41 );
644       assert( mi[8] == 48 );
645     }
646 #endif
647   }
648 
649 }
650 
651