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