1 /*************************************************************************\
2 *
3 * Package: TestU01
4 * File: ftab.c
5 * Environment: ANSI C
6 *
7 * Copyright (c) 2002 Pierre L'Ecuyer, DIRO, Université de Montréal.
8 * e-mail: lecuyer@iro.umontreal.ca
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted without a fee for private, research,
13 * academic, or other non-commercial purposes.
14 * Any use of this software in a commercial environment requires a
15 * written licence from the copyright owner.
16 *
17 * Any changes made to this package must be clearly identified as such.
18 *
19 * In scientific publications which used this software, a reference to it
20 * would be appreciated.
21 *
22 * Redistributions of source code must retain this copyright notice
23 * and the following disclaimer.
24 *
25 * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
26 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
27 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
28 *
29 \*************************************************************************/
30
31
32 #include "util.h"
33 #include "chrono.h"
34 #include "num.h"
35 #include "tables.h"
36 #include "gofw.h"
37
38 #include "ftab.h"
39 #include "ffam.h"
40 #include "swrite.h"
41
42 #include <stdio.h>
43 #include <math.h>
44 #include <string.h>
45 #include <limits.h>
46
47
48 #define MAXLEN 100 /* Max number of chars in Desc[] */
49
50
51
52 /*---------------------------- extern variables ---------------------------*/
53
54 ftab_StyleType ftab_Style = ftab_Plain;
55
56 double ftab_Suspectp = 0.01;
57
58 int ftab_SuspectLog2p = 6;
59
60
61
62
63 /*---------------------------- module variables ---------------------------*/
64
65 static double SuspectLog2pval;
66
67
68
69
70
71 /*-------------------------------- Functions ------------------------------*/
72
73
ftab_SetDesc(ftab_Table * T,char * Desc)74 void ftab_SetDesc (ftab_Table *T, char *Desc)
75 {
76 size_t len;
77 util_Assert (T != NULL, "ftab_SetDesc: ftab_Table is a NULL pointer");
78 len = strlen (Desc);
79 if (len > MAXLEN) {
80 len = MAXLEN;
81 util_Warning (1, "ftab_Table->Desc truncated");
82 }
83 if (T->Desc != NULL)
84 T->Desc = util_Free (T->Desc);
85 T->Desc = util_Calloc (len + 1, sizeof (char));
86 strncpy (T->Desc, Desc, (size_t) len);
87 T->Desc[len] = '\0';
88 }
89
90
91 /*=========================================================================*/
92
ftab_CreateTable(int Nr,int j1,int j2,int jstep,char * Desc,ftab_FormType Form,int Ns)93 ftab_Table *ftab_CreateTable (int Nr, int j1, int j2, int jstep,
94 char *Desc, ftab_FormType Form, int Ns)
95 {
96 ftab_Table *T;
97 T = util_Malloc (sizeof (ftab_Table));
98 memset (T, 0, sizeof (ftab_Table));
99 T->Nr = Nr;
100 T->j1 = j1;
101 T->j2 = j2;
102 T->jstep = jstep;
103 T->Nc = 1 + (j2 - j1)/jstep;
104 T->Mat = tables_CreateMatrixD (T->Nr, T->Nc);
105 T->LSize = util_Calloc ((size_t) T->Nr, sizeof (int));
106 T->Desc = NULL;
107 ftab_SetDesc (T, Desc);
108 T->Form = Form;
109 if (Form == ftab_String) {
110 T->Strings = util_Calloc ((size_t) Ns, sizeof (char *));
111 T->Ns = Ns;
112 } else
113 T->Strings = NULL;
114 return T;
115 }
116
117
118 /*=========================================================================*/
119
ftab_DeleteTable(ftab_Table * T)120 void ftab_DeleteTable (ftab_Table * T)
121 {
122 if (T == NULL)
123 return;
124 tables_DeleteMatrixD (&T->Mat);
125 T->LSize = util_Free (T->LSize);
126 T->Desc = util_Free (T->Desc);
127 if (T->Form == ftab_String)
128 T->Strings = util_Free (T->Strings);
129 util_Free (T);
130 }
131
132
133 /*=========================================================================*/
134
ftab_InitMatrix(ftab_Table * T,double x)135 void ftab_InitMatrix (ftab_Table * T, double x)
136 {
137 int i, j;
138
139 for (i = 0; i < T->Nr; i++)
140 for (j = 0; j < T->Nc; j++)
141 T->Mat[i][j] = x;
142 }
143
144
145 /*=========================================================================*/
146
ftab_MakeTables(ffam_Fam * fam,void * res,void * cho,void * par,ftab_CalcType Calc,int Nr,int f1,int f2,int fstep)147 void ftab_MakeTables (ffam_Fam *fam, void *res, void *cho, void *par,
148 ftab_CalcType Calc, int Nr, int f1, int f2, int fstep)
149 {
150 int i, j; /* Row and column of matrices for results of one test */
151 int f;
152 chrono_Chrono *Timer;
153 unif01_Gen *gen;
154
155 SuspectLog2pval = 1.0 / (num_TwoExp[ftab_SuspectLog2p] - 1.0);
156
157 Timer = chrono_Create ();
158
159 Nr = util_Min (Nr, fam->Ng);
160 for (i = 0; i < Nr; i++) {
161 if (swrite_Basic) {
162 printf ("CPU cumulative time: ");
163 chrono_Write (Timer, chrono_hms);
164 printf ("\n\n============================================="
165 "==============\n\nLSize = i = %2d\n\n", fam->LSize[i]);
166 }
167 if ((gen = fam->Gen[i])) {
168 f = f1;
169 j = 0;
170 while (f <= f2) {
171 Calc (fam, res, cho, par, fam->LSize[i], f, i, j);
172 f += fstep;
173 j++;
174 }
175 }
176 }
177 if (swrite_Basic) {
178 printf ("Total CPU time: ");
179 chrono_Write (Timer, chrono_hms);
180 printf
181 ("\n\n======================================================\n");
182 }
183 chrono_Delete (Timer);
184 }
185
186
187 /*=========================================================================*/
188
PrintTexName(char * nam)189 static void PrintTexName (char *nam)
190 /*
191 * Make sure that any _ char in Latex format name is printed as \_
192 */
193 {
194 char *p, *name = nam;
195 size_t len;
196
197 if (NULL == nam)
198 return;
199 len = strlen (name) + 1;
200 name = util_Calloc (len, sizeof (char));
201 strncpy (name, nam, (size_t) len);
202
203 while ((p = strchr(name, '_'))) {
204 *p = '\0';
205 printf ("%s", name);
206 printf ("\\_");
207 name = p + 1;
208 }
209 printf ("%s", name);
210 }
211
212
213 /*=========================================================================*/
214
PrintLog2(double d)215 static void PrintLog2 (double d)
216 /*
217 * Prints the logarithm (rounded) of d in base 2, when d is outside the
218 * interval [SuspectLog2pval, 1 - SuspectLog2pval]; otherwise prints
219 * nothing.
220 */
221 {
222 int s;
223
224 if (d <= gofw_Epsilonp) {
225 printf (" inf ");
226 } else if (d <= SuspectLog2pval) {
227 s = 0.5 - num_Log2 (d);
228 printf (" %2d ", s);
229 } else if (d >= 1.0 - gofw_Epsilonp1) {
230 printf (" -inf ");
231 } else if (d >= 1.0 - SuspectLog2pval) {
232 s = 0.5 - num_Log2 (1.0 - d);
233 if (s > 9)
234 printf (" ");
235 else
236 printf (" ");
237 printf ("-%1d ", s);
238 } else
239 printf (" ");
240 }
241
242
243 /*-------------------------------------------------------------------------*/
244
PrintLog2Tex(double d)245 static void PrintLog2Tex (double d)
246 /*
247 * Similar to PrintLog2, but prints in Latex style.
248 */
249 {
250 int s;
251 if (d <= gofw_Epsilonp) {
252 printf (" & $\\infty$ ");
253 } else if (d <= SuspectLog2pval) {
254 s = 0.5 - num_Log2 (d);
255 printf (" & %3d ", s);
256 } else if (d >= 1.0 - gofw_Epsilonp1) {
257 printf (" & $-\\infty$ ");
258 } else if (d >= 1.0 - SuspectLog2pval) {
259 s = 0.5 - num_Log2 (1.0 - d);
260 if (s > 9)
261 printf (" & $-");
262 else
263 printf (" & $-");
264 printf ("%1d $ ", s);
265 } else
266 printf (" & ");
267 }
268
269
270 /*=========================================================================*/
271
PrintLog10(double d)272 static void PrintLog10 (double d)
273 /*
274 * Prints the logarithm (rounded) of d in base 10, when d is outside the
275 * interval [ftab_Suspectp, 1 - ftab_Suspectp]; otherwise prints
276 * nothing.
277 */
278 {
279 int s;
280 if (d <= gofw_Epsilonp) {
281 printf (" inf ");
282 } else if (d <= ftab_Suspectp) {
283 s = 0.5 - log10 (d);
284 printf (" %2d ", s);
285 } else if (d >= 1.0 - gofw_Epsilonp1) {
286 printf (" -inf ");
287 } else if (d >= 1.0 - ftab_Suspectp) {
288 s = 0.5 - log10 (1.0 - d);
289 if (s > 9)
290 printf (" ");
291 else
292 printf (" ");
293 printf ("-%1d ", s);
294 } else {
295 printf (" ");
296 }
297 }
298
299
300 /*-------------------------------------------------------------------------*/
301
PrintLog10Tex(double d)302 static void PrintLog10Tex (double d)
303 /*
304 * Similar to PrintLog10, but prints in LaTex style.
305 */
306 {
307 int s;
308 if (d <= gofw_Epsilonp) {
309 printf (" & $\\infty$ ");
310 } else if (d <= ftab_Suspectp) {
311 s = 0.5 - log10 (d);
312 printf (" & %3d ", s);
313 } else if (d >= 1.0 - gofw_Epsilonp1) {
314 printf (" & $-\\infty$ ");
315 } else if (d >= 1.0 - ftab_Suspectp) {
316 s = 0.5 - log10 (1.0 - d);
317 if (s > 9)
318 printf (" & $-");
319 else
320 printf (" & $-");
321 printf ("%1d $ ", s);
322 } else {
323 printf (" & ");
324 }
325 }
326
327
328 /*=========================================================================*/
329
PrintVal(ftab_Table * T,double d,ftab_FormType Form)330 static void PrintVal (ftab_Table * T, double d, ftab_FormType Form)
331 /*
332 * Prints the value d according to format Form.
333 */
334 {
335 int s;
336 /* All Table tables are initialized to -1; thus the test was not done for
337 this pair (e, f) if d = -1. */
338 if (d < -0.9) {
339 printf (" --- ");
340 } else if (Form == ftab_String) {
341 printf (" ");
342 s = 0.5 + d;
343 printf ("%s", T->Strings[s]);
344 } else if (Form == ftab_Integer) {
345 printf (" ");
346 if (d <= LONG_MAX)
347 printf ("%8ld", (long) d);
348 else
349 num_WriteD (d, 8, 0, 0);
350 } else if (Form == ftab_Real) {
351 printf (" ");
352 num_WriteD (d, 8, 2, 2);
353 } else if (Form == ftab_pLog2) {
354 PrintLog2 (d);
355 } else if (Form == ftab_pLog10) {
356 PrintLog10 (d);
357 } else if (d < gofw_Epsilonp) {
358 printf (" eps ");
359 } else if (d < ftab_Suspectp) {
360 printf (" ");
361 num_WriteD (d, 8, 2, 2);
362 } else if (d > 1.0 - gofw_Epsilonp1 && Form == ftab_pVal2) {
363 printf (" -eps1 ");
364 } else if (d > 1.0 - ftab_Suspectp && Form == ftab_pVal2) {
365 printf (" ");
366 num_WriteD (d - 1.0, 8, 2, 2);
367 } else if (Form == ftab_NotInit) {
368 util_Error ("ftab_PrintTable: Form is not initialized");
369 } else {
370 printf (" ");
371 }
372 }
373
374
375 /*=========================================================================*/
376
PrintValTex(ftab_Table * T,double d,ftab_FormType Form)377 static void PrintValTex (ftab_Table * T, double d, ftab_FormType Form)
378 /*
379 * Similar to PrintVal, but prints in LaTex style.
380 */
381 {
382 int s;
383 if (d < -0.9) {
384 printf (" & --- ");
385 } else if (Form == ftab_String) {
386 printf (" & ");
387 s = d + 0.5;
388 printf ("%s", T->Strings[s]);
389 } else if (Form == ftab_Integer) {
390 printf (" & ");
391 if (d <= LONG_MAX)
392 printf ("%8ld", (long) d);
393 else
394 num_WriteD (d, 8, 0, 0);
395 } else if (Form == ftab_Real) {
396 printf (" & ");
397 num_WriteD (d, 8, 2, 2);
398 } else if (Form == ftab_pLog10) {
399 PrintLog10Tex (d);
400 } else if (Form == ftab_pLog2) {
401 PrintLog2Tex (d);
402 } else if (d < gofw_Epsilonp) {
403 printf (" & \\eps ");
404 } else if (d < ftab_Suspectp) {
405 printf (" & ");
406 num_WriteD (d, 8, 2, 2);
407 } else if (d > 1.0 - gofw_Epsilonp1 && Form == ftab_pVal2) {
408 printf (" & \\epsm ");
409 } else if (d > 1.0 - ftab_Suspectp && Form == ftab_pVal2) {
410 printf (" & ");
411 num_WriteD (d - 1.0, 8, 2, 2);
412 } else if (Form == ftab_NotInit) {
413 util_Error ("ftab\\_PrintTable: Form is not initialized");
414 } else {
415 printf (" & ");
416 }
417 }
418
419
420 /*=========================================================================*/
421
PrintTablePlain(ftab_Table * T)422 static void PrintTablePlain (ftab_Table * T)
423 /*
424 * Prints table T in plain text style, according to format Form.
425 */
426 {
427 int i, j;
428 int j1 = T->j1;
429 int j2 = T->j2;
430 int jstep = T->jstep;
431 double d;
432 ftab_FormType Form = T->Form;
433
434 printf ("%s", T->Desc);
435 printf ("\n\nLSize j =%2d", j1);
436 j = j1 + jstep;
437 while (j <= j2) {
438 printf (" j =%2d", j);
439 j += jstep;
440 }
441 printf ("\n------------------------------------------------------\n");
442
443 for (i = 0; i < T->Nr; i++) {
444 printf ("%3d", T->LSize[i]);
445 for (j = 0; j < T->Nc; j++) {
446 d = T->Mat[i][j];
447 PrintVal (T, d, Form);
448 }
449 printf ("\n");
450 }
451 printf ("\n=======================================================\n");
452 }
453
454
455 /*=========================================================================*/
456
PrintTableTex(ftab_Table * T)457 static void PrintTableTex (ftab_Table * T)
458 /*
459 * Prints table T in Latex style, according to format Form.
460 */
461 {
462 int i, j;
463 int j1 = T->j1;
464 int j2 = T->j2;
465 int jstep = T->jstep;
466 ftab_FormType Form = T->Form;
467
468 printf ("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
469 "\\begin {tabular}{|c|@{\\extracolsep{10pt}}");
470 j = j1;
471 while (j <= j2) {
472 printf ("c");
473 j += jstep;
474 }
475 printf ("|}\n\\multicolumn{%1d", (j2 - j1) / jstep + 2);
476 printf ("}{l}{\\makebox[0pt][l]{");
477 PrintTexName (T->Desc);
478 printf ("}}\\\\\n\\hline\nLSize & $ j=%2d", j1);
479 j = j1 + jstep;
480 while (j <= j2) {
481 printf (" $ & $ j=%2d", j);
482 j += jstep;
483 }
484 printf ("$ \\\\\n\\hline\n");
485
486 for (i = 0; i < T->Nr; i++) {
487 printf ("%3d ", T->LSize[i]);
488 for (j = 0; j < T->Nc; j++) {
489 PrintValTex (T, T->Mat[i][j], Form);
490 }
491 printf (" \\\\\n");
492 }
493 printf ("\\hline\n\\end {tabular} \\\\\n\\medskip\n\n");
494 }
495
496
497 /*=========================================================================*/
498
ftab_PrintTable(ftab_Table * T)499 void ftab_PrintTable (ftab_Table * T)
500 {
501 if (NULL == T)
502 return;
503 if (ftab_Style == ftab_Plain)
504 PrintTablePlain (T);
505 else
506 PrintTableTex (T);
507 }
508
509
510 /*=========================================================================*/
511
PrintTable2Tex(ftab_Table * T1,ftab_Table * T2,lebool Flag)512 static void PrintTable2Tex (ftab_Table * T1, ftab_Table * T2, lebool Flag)
513 /*
514 * Prints tables in Latex style, T1 according to format Form1,
515 * T2 according to format Form2.
516 */
517 {
518 int i, j;
519 int j1 = T1->j1;
520 int j2 = T1->j2;
521 int jstep = T1->jstep;
522 double x;
523 ftab_FormType Form1 = T1->Form;
524 ftab_FormType Form2 = T2->Form;
525
526 printf ("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
527 "\\begin {tabular}{|c|@{\\extracolsep{10pt}}");
528 j = j1;
529 while (j <= j2) {
530 printf ("rr|");
531 j += jstep;
532 }
533 printf ("}\n\\multicolumn{%1d", 2 * ((j2 - j1) / jstep + 1) + 1);
534 printf ("}{l}{\\makebox[0pt][l]{");
535 PrintTexName (T1->Desc);
536 printf ("---");
537 PrintTexName (T2->Desc);
538 if (Flag)
539 printf (" (RATIO)");
540 printf ("}}\\\\\n\\hline\n" " LSize& \\multicolumn{2}{c|}{$ j=%1d $}", j1);
541 j = j1 + jstep;
542 while (j <= j2) {
543 printf (" & \\multicolumn{2}{c|}{$ j=%1d $}", j);
544 j += jstep;
545 }
546 printf (" \\\\\n\\hline\n");
547
548 for (i = 0; i < T1->Nr; i++) {
549 printf ("%3d", T1->LSize[i]);
550 for (j = 0; j < T1->Nc; j++) {
551 PrintValTex (T1, T1->Mat[i][j], Form1);
552 x = T2->Mat[i][j];
553 if (!Flag || x < -0.9)
554 PrintValTex (T2, x, Form2);
555 else {
556 x = x / T1->Mat[i][j];
557 PrintValTex (T2, x, ftab_Real);
558 }
559 }
560 printf (" \\\\\n");
561 }
562 printf ("\\hline\n\\end {tabular} \\\\\n\\medskip\n\n");
563 }
564
565
566 /*=========================================================================*/
567
PrintTable2Plain(ftab_Table * T1,ftab_Table * T2,lebool Flag)568 static void PrintTable2Plain (ftab_Table * T1, ftab_Table * T2, lebool Flag)
569 /*
570 * Prints tables in plain text style, T1 according to format Form1,
571 * T2 according to format Form2.
572 */
573 {
574 int i, j;
575 int j1 = T1->j1;
576 int j2 = T1->j2;
577 int jstep = T1->jstep;
578 double x;
579 ftab_FormType Form1 = T1->Form;
580 ftab_FormType Form2 = T2->Form;
581
582 printf ("%s", T1->Desc);
583 printf ("---");
584 printf ("%s", T2->Desc);
585 if (Flag)
586 printf (" (RATIO)");
587 printf ("\n\n LSize j=%1d", j1);
588 printf (" j=%2d", j1);
589 j = j1 + jstep;
590 while (j <= j2) {
591 printf (" j=%2d", j);
592 printf (" j=%2d", j);
593 j += jstep;
594 }
595 printf ("\n----------------------------------------------------\n");
596
597 for (i = 0; i < T1->Nr; i++) {
598 printf ("%3d", T1->LSize[i]);
599 for (j = 0; j < T1->Nc; j++) {
600 PrintVal (T1, T1->Mat[i][j], Form1);
601 x = T2->Mat[i][j];
602 if (!Flag || x < -0.9)
603 PrintVal (T2, x, Form2);
604 else {
605 x = x / T1->Mat[i][j];
606 PrintVal (T2, x, ftab_Real);
607 }
608 }
609 printf ("\n");
610 }
611 printf ("\n=======================================================\n");
612 }
613
614
615 /*=========================================================================*/
616
ftab_PrintTable2(ftab_Table * T1,ftab_Table * T2,lebool Flag)617 void ftab_PrintTable2 (ftab_Table * T1, ftab_Table * T2, lebool Flag)
618 {
619 if (NULL == T1 || NULL == T2)
620 return;
621 if (ftab_Style == ftab_Plain)
622 PrintTable2Plain (T1, T2, Flag);
623 else
624 PrintTable2Tex (T1, T2, Flag);
625 }
626