home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / math / ols / loadfile.c < prev    next >
C/C++ Source or Header  |  1993-07-28  |  8KB  |  308 lines

  1.  
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include "utils.h"
  6.  
  7. #ifdef TESTING
  8. int 
  9. main ()
  10. {
  11.   int i, j, t, k, K, T;
  12.   float **data;
  13.   char *cstring, *ustring;
  14.   char **labels;
  15.   int *table, tablesize;
  16.  
  17. #ifdef FROMSTDIN
  18.   data = LoadFile ("-", &K, &T, FALSE, cstring, ustring,
  19.            &labels, &table, &tablesize);
  20.   if (data == NULL)
  21.     return 1;
  22.   printf ("K=%d, T=%d\n", K, T);
  23.   for (t = 0; t < T; t++)
  24.     {
  25.       for (k = 0; k < K; k++)
  26.     printf (" %f ", data[t][k]);
  27.       printf ("\n");
  28.     }
  29.   return 0;
  30. #endif /* STDIN */
  31.  
  32.   /*--------------------------------------------------*/
  33.   printf ("Input data file:\n");
  34.   system ("cat demo.dat");
  35.   printf ("\n");
  36.  
  37.   cstring = ustring = (char *) NULL;
  38.   printf ("No picking of fields:\nExpect x y z\n");
  39.   data = LoadFile ("demo.dat", &K, &T,
  40.            FALSE, cstring, ustring, &labels, &table, &tablesize);
  41.   if (NULL == data)
  42.     {
  43.       printf ("LoadFile failed.\n");
  44.       return 1;
  45.     }
  46.  
  47.   for (k = 0; k < K; k++)
  48.     printf (" %s ", labels[k]);
  49.   printf ("\n");
  50.   for (t = 0; t < T; t++)
  51.     {
  52.       for (k = 0; k < K; k++)
  53.     printf (" %f ", data[t][k]);
  54.       printf ("\n");
  55.     }
  56.   printf ("\nMapping table:\n");
  57.   for (i = 0; i < tablesize; i++)
  58.     printf ("Table[%d] = %d\n", i, table[i]);
  59.   printf ("\n");
  60.  
  61.  
  62.   /*--------------------------------------------------*/
  63.   cstring = strdup ("x y z");
  64.   ustring = strdup ("z x");
  65.   printf ("With picking of fields:\nExpect z x\n");
  66.   data = LoadFile ("demo.dat", &K, &T,
  67.            TRUE, cstring, ustring, &labels, &table, &tablesize);
  68.   if (NULL == data)
  69.     {
  70.       printf ("LoadFile failed.\n");
  71.       return 1;
  72.     }
  73.   for (k = 0; k < K; k++)
  74.     printf (" %s ", labels[k]);
  75.   printf ("\n");
  76.   for (t = 0; t < T; t++)
  77.     {
  78.       for (k = 0; k < K; k++)
  79.     printf (" %f ", data[t][k]);
  80.       printf ("\n");
  81.     }
  82.   printf ("\nMapping table:\n");
  83.   for (i = 0; i < tablesize; i++)
  84.     printf ("Table[%d] = %d\n", i, table[i]);
  85.   printf ("\n");
  86.  
  87.   return 0;
  88. }
  89.  
  90. #endif /* TESTING */
  91.  
  92. /* Look for a given words in a table of words */
  93. int 
  94. findword (char *word, char **manywords, int maxwords)
  95. {
  96.   int i;
  97.  
  98.   for (i = 0; i < maxwords; i++)
  99.     if (0 == strcmp (word, manywords[i]))
  100.       return i;
  101.   return -1;
  102. }
  103.  
  104. #define MAXFIELDS 1024
  105. /* When you change this, be sure to make implied changes in
  106.     messages in err_mktable below. */
  107.  
  108. /* Error codes */
  109. #define TOOMANYFIELDS_C -1    /* more than MAXFIELDS fields in cstring */
  110. #define TOOMANYFIELDS_U -2    /* more than MAXFIELDS fields in ustring */
  111. #define OUT_OF_MEMORY -3    /* ran out of RAM someplace. */
  112. #define USING_BUTNOT_CONTAINS    -4    /* a variable in ustring but not in cstring */
  113.  
  114. int 
  115. mktable (char *safe_cstring, char *safe_ustring, int *cNF,
  116.      int **table, int *tablesize, int *NumColumns,
  117.      char ***labels)
  118. {
  119.   char *cstring, *ustring;
  120.   int uNF;
  121.   static char *cwords[MAXFIELDS], *uwords[MAXFIELDS];
  122.   int i, j;
  123.  
  124.   cstring = strdup (safe_cstring);
  125.   ustring = strdup (safe_ustring);
  126.   /* screw around with copies. */
  127.  
  128.   if (MAXFIELDS <= (*cNF = split (cstring, cwords, MAXFIELDS, "")))
  129.     return TOOMANYFIELDS_C;
  130.  
  131.   if (MAXFIELDS <= (uNF = split (ustring, uwords, MAXFIELDS, "")))
  132.     return TOOMANYFIELDS_U;
  133.  
  134.   *NumColumns = *tablesize = uNF;
  135.   if (NULL == (*labels = (char **) malloc (uNF * sizeof (char *))))
  136.       return OUT_OF_MEMORY;
  137.   if (NULL == (*table = (int *) malloc (uNF * sizeof (int))))
  138.       return OUT_OF_MEMORY;
  139.  
  140.   for (i = 0; i < uNF; i++)
  141.     {                /* processing for uwords[i] */
  142.       (*labels)[i] = strdup (uwords[i]);
  143.       j = findword (uwords[i], cwords, *cNF);
  144.       if (j == -1)
  145.     return USING_BUTNOT_CONTAINS;
  146.       (*table)[i] = j;
  147.     }
  148.  
  149.   free (cstring);
  150.   free (ustring);
  151.   return 0;
  152. }
  153.  
  154. /* Converting error codes of mktable into strings; after K&R, page 113 */
  155. char *
  156. err_mktable (int n)
  157. {
  158.   static char *messages[] =
  159.   {
  160.     /*0*/ "Error in call to err_mktable.",
  161.     /*1*/ "'Contains' string contains too many variables; atmost 1024 allowed.",
  162.     /*2*/ "'Using' string contains too many variables; atmost 1024 allowed.",
  163.     /*3*/ "Out of Memory inside MkTable.",
  164.     /*4*/ "There is a variable in 'Using' which is not in 'Contains'."
  165.   };
  166.  
  167.   return (n < -4 || n > -1) ? messages[0] : messages[-n];
  168. }
  169.  
  170.  
  171. /* Function which takes
  172.     string containing one line
  173.     mapping table
  174. and returns
  175.     pointer to float * which contains required numbers.
  176. */
  177.  
  178. float *
  179. mkrowptr (char *line, int expectNF, int *table, int tablesize)
  180. {
  181.   float *tmp;            /* this is the array which will be built up. */
  182.   char *words[MAXFIELDS];
  183.   int i, NF;
  184.  
  185.   if (expectNF != (NF = split (line, words, MAXFIELDS, "")))
  186.     return NULL;
  187.  
  188.   tmp = (float *) malloc (tablesize * sizeof (float));
  189.   for (i = 0; i < tablesize; i++)
  190.     tmp[i] = (float) atof (words[table[i]]);    /* atof is slow! */
  191.  
  192.   return tmp;
  193. }
  194.  
  195. #define INITIALSIZE 100
  196. #define GROWTHFACTOR 1.5
  197. /* the float** starts off as INITIALSIZE row pointers.
  198.     Each time the data gets bigger than it's current size,
  199.     the size is increased by a factor of GROWTHFACTOR. */
  200.  
  201. #define MAXCHARSINLINE 16384
  202. /* Largest line we can read from input file. */
  203.  
  204. float **
  205. LoadFile (char *dfname,
  206.       int *NumColumns, int *ObsNum,
  207.       int pickfields, char *cstring, char *ustring,
  208.       char ***labels, int **table, int *tablesize)
  209. {
  210.   int errorcode;
  211.   float **data;
  212.   int capacity, rows;
  213.   char *linebuffer;        /* one line from data file starts off here.  */
  214.   FILE *filehandle;
  215.   char *words[MAXFIELDS];
  216.   int i, NF, cNF;
  217.   char *hiteof, *linecopy;
  218.   float *p;
  219.   if (0 == (strncmp (dfname, "-", 1)))
  220.     filehandle = stdin;
  221.   else
  222.     {
  223.       if (NULL == (filehandle = fopen (dfname, "r")))
  224.     {
  225.       fprintf (stderr, "Failed to open file %s.\n", dfname);
  226.       return NULL;
  227.     }
  228.     }
  229.   if (pickfields == TRUE)
  230.     {
  231.  
  232.       errorcode = mktable (cstring, ustring, &cNF, table,
  233.                tablesize, NumColumns, labels);
  234.  
  235.       if (errorcode < 0)
  236.     {
  237.       fprintf (stderr, "%s", err_mktable (errorcode));
  238.       return NULL;
  239.     }
  240.     }
  241.  
  242.   data = (float **) malloc (INITIALSIZE * sizeof (float *));
  243.   capacity = INITIALSIZE;
  244.   rows = 0;
  245.   linebuffer = (char *) malloc (MAXCHARSINLINE * sizeof (char));
  246.  
  247.   if (NULL == fgets (linebuffer, MAXCHARSINLINE, filehandle))
  248.     {
  249.       fprintf (stderr, "Premature EOF on Input.\n");
  250.       return NULL;
  251.     }
  252.   linebuffer[strlen (linebuffer) - 1] = 0;
  253.   /* the last char of linebuffer given us by fgets is
  254.         "\n".  The confuses Henry Spencer's split function
  255.         who has been asked to use whitespace delimiters;
  256.         split claims the "\n" is a field.  This hack
  257.         eliminates that problem */
  258.  
  259.   if (pickfields == FALSE)
  260.     {                /* learn layout from 1st row */
  261.       linecopy = strdup (linebuffer);    /* protecting linebuffer */
  262.       cNF = NF = split (linecopy, words, MAXFIELDS, "");
  263.       if (NF <= 0)
  264.     {
  265.       fprintf (stderr, "No data found on 1st line!\n");
  266.       return NULL;
  267.     }
  268.       *tablesize = *NumColumns = NF;
  269.       *table = (int *) malloc (NF * sizeof (int));
  270.       *labels = (char **) malloc (NF * sizeof (char *));
  271.  
  272.       for (i = 0; i < NF; i++)
  273.     {
  274.       (*table)[i] = i;
  275.       (*labels)[i] = (char *) malloc (5 * sizeof (char));
  276.       sprintf ((*labels)[i], "$%d", (i + 1));
  277.     }
  278.       free (linecopy);
  279.     }
  280.  
  281.   /* The main loop.  Notice lines are read at bottom. */
  282.   do
  283.     {
  284.       if (NULL ==
  285.       (p = mkrowptr (linebuffer, cNF, *table, *tablesize)))
  286.     {
  287.       fprintf (stderr, "On row %d, expect %d fields.\n", 1 + rows, cNF);
  288.       return NULL;
  289.     }
  290.       rows++;
  291.       if (rows > capacity)
  292.     {
  293.       capacity = (int) ((float) GROWTHFACTOR * capacity);
  294.       data = (float **) realloc (data, capacity * sizeof (float *));
  295.     }
  296.       data[rows - 1] = p;
  297.       hiteof = fgets (linebuffer, MAXCHARSINLINE, filehandle);
  298.       linebuffer[strlen (linebuffer) - 1] = 0;
  299.       /* Same problem -- remove \n for splitting */
  300.     }
  301.   while (hiteof != NULL);    /* End of main loop. */
  302.  
  303.   *ObsNum = rows;
  304.   data = (float **) realloc (data, rows * sizeof (float *));
  305.   free (linebuffer);
  306.   return data;
  307. }
  308.