home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 9 / 09.iso / e / e065 / 2.ddi / WEATHRIO.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-28  |  22.3 KB  |  746 lines

  1. /* 17:00 04-Jul-88  (weathrio.c)  Weather Prediction with Madeline */
  2.  
  3. /************************************************************************
  4.  * Copyright(C) 1988-1990 NeuralWare Inc
  5.  * Penn Center West, IV-227, Pittsburgh, PA 15276
  6.  *
  7.  * All rights reserved.  No part of this program may be reproduced,
  8.  * stored in a retrieval system, or transmitted, in any form or by any
  9.  * means, electronic, mechanical, photocopying, recording or otherwise
  10.  * without the prior written permission of the copyright owner,
  11.  * NeuralWare, Inc.
  12.  ************************************************************************
  13.  */
  14. #include "userutl.h"
  15.  
  16. #include <string.h>
  17. #include <math.h>
  18.  
  19. #ifndef SUN
  20. #ifndef DLC
  21. #include <stdlib.h>
  22. #endif
  23. #endif
  24.  
  25. #ifdef MAC
  26. #include  "macuio.redef"
  27. #endif
  28.  
  29. /************************************************************************
  30.  *
  31.  *  WEATHRIO - Weather Prediction User I/O
  32.  *
  33.  ************************************************************************
  34.  */
  35.  
  36. /* external routines */
  37. #ifdef PROTOTYPING
  38. /* --- prototypes --- */
  39. double  fabs( double );
  40. double  sqrt( double );
  41. #else
  42. double  fabs( );
  43. double  sqrt( );
  44. #endif
  45.  
  46. static short  nw_type;    /* type of network : */
  47. #define ADALINE   0
  48. #define OTHER   1
  49.  
  50.  
  51. /* local data declarations */
  52. static  float bp, dbp;    /* bar. pressure, delta b.p. */
  53. static  float prec_tod, prec_tom, prec_nxt; /* rainfall today, tomorrow..*/
  54. static  int wd, dwd;    /* wind direction, delta w. dir */
  55. static  char  date[12];
  56.  
  57. /* File definitions and declarations */
  58. #define MAX_STR 132       /* For reading from file */
  59. static  char  fbuf[3][MAX_STR + 1];   /* buffers for file i/o */
  60. static  int tod_buff, tom_buff, nxt_buff; /* buffer indices */
  61. static  int num_readings;     /* Actual # readings */
  62. static  short no_more_data;     /* recall flag */
  63. static  FILE  *fp = 0;
  64. static  FILE  *ifp = 0;
  65. static  long    start_pos;
  66. static  char  file_name[40];      /* larger for SUNs */
  67.  
  68.  
  69. /* Forecast parameters from user' file */
  70.  
  71. static float  prec_thr;   /* precipitation threshold */
  72. static float  bp_low, bp_high;  /* barometric pressure limits */
  73. static float  dbp_low, dbp_high;  /* delta barometric pressure limits */
  74. static float  wd_low, wd_high;  /* wind direction limits */
  75. static float  dwd_low, dwd_high;  /* delta wind direction limits */
  76.  
  77. /* Following need to be long for MAC scanfs */
  78. static long bp_npe;     /* # PEs for barometrics pressure */
  79. static long dbp_npe;    /* # PEs for delta bar. pressure */
  80. static long wd_npe;     /* # PEs for wind direction */
  81. static long dwd_npe;    /* # PEs for delta wind direction */
  82.  
  83. /* Network parameters */
  84. static  int   nlayp, ninp, noutp, ltype;  /* Network parameters */
  85. static  char  *csp, *netnp;     /* Network pointers*/
  86.  
  87.  
  88. /* graphics parameters */
  89. static  int xsize, ysize, ncolor, chrx, chry;
  90.  
  91.  
  92. /* Output display definitions and declarations for learning */
  93. static  double  tod_mse, tom_mse, nxt_mse;  /* Mean square errors */ 
  94.  
  95.  
  96. /* Output display definitions and declarations for recall */
  97. #define NUM_DISP  31      /* Maximum number displayed*/
  98. #define X_MARGIN  5
  99. #define Y_MARGIN  5
  100. static  int rstrtx, rstrty, rendx, rendy; /* Display window params */
  101. static  int ract_y, rtod_y, rtom_y, rnxt_y;/* y values for the 3 rows */
  102. static  int rdata;        /* start of data display */
  103. static  int curr_pos;     /* current data position */
  104. static  int dateline, actline;
  105.  
  106.  
  107. /* Results */
  108. static  float tod_correct, tom_correct, nxt_correct;
  109.  
  110. #ifndef DLC
  111. /* special routine to fill in for SUN386i */
  112. int strcmpl( pa, pb )
  113. char  *pa, *pb;   /* strings to compare */
  114. {
  115.     int   a, b;     /* work characters */
  116.     int   rc;     /* return code */
  117.  
  118.     for(;;) {
  119.   a = *pa++;
  120.   b = *pb++;
  121.   if ( 'A' <= a && a <= 'Z' ) a -= 'A'-'a';
  122.   if ( 'A' <= b && b <= 'Z' ) b -= 'A'-'a';
  123.   if ( (rc = a - b) != 0 ) return( rc );
  124.   if ( a == 0 ) return( 0 );
  125.     }
  126. }
  127. #endif
  128.  
  129. /* local routines */
  130.  
  131. /* --- prototypes --- */
  132.  
  133. void encode ARGLIST(( char * ));
  134. void decode ARGLIST(( ));
  135. void li_code ARGLIST(( double, double, double, int, char * ));
  136. void disp_rwdw ARGLIST (( ));
  137. void disp_forecast ARGLIST (( ));
  138.  
  139.  
  140. void encode( buf )
  141. char  *buf;
  142. {
  143.   char  sbuf[100];
  144.   float denom, wf;
  145.   float nbp, ndbp, nwd, ndwd; /* Normalized data */
  146.  
  147.   if ( nw_type == ADALINE ) {
  148.     strcpy( buf, date );
  149.     strcat( buf, " " );
  150.   
  151.     li_code( bp, bp_low, bp_high, (int)bp_npe, sbuf );
  152.     strcat( buf, sbuf );
  153.     strcat( buf, " " );
  154.  
  155.     wf = (float) fabs( (double)dbp_low );
  156.     if ( wf < dbp_high ) wf = dbp_high;
  157.     li_code( (double) fabs((double)dbp), 0.0, wf, (int)(dbp_npe-1), sbuf );
  158.     strcat( buf, sbuf );
  159.     strcat( buf, " " );
  160.     if ( dbp < 0.0 ) strcat( buf, "0 " );
  161.     else strcat( buf, "1 " );
  162.  
  163.     li_code( (double) wd, wd_low, wd_high, (int)wd_npe, sbuf );
  164.     strcat( buf, sbuf );
  165.     strcat( buf, " " );
  166.  
  167.     li_code( (double) dwd, dwd_low, dwd_high, (int)dwd_npe, sbuf );
  168.     strcat( buf, sbuf );
  169.     strcat( buf, " " );
  170.  
  171.     strcat( buf, " " );
  172.     strcat( buf, (prec_tod > prec_thr) ? "1" : "0" );
  173.     strcat( buf, (prec_tom > prec_thr) ? "1" : "0" );
  174.     strcat( buf, (prec_nxt > prec_thr) ? "1" : "0" );
  175.   strcat( buf, NEW_LINE_STR );
  176.   } else {
  177.     denom = bp_high - bp_low;
  178.     if (denom >= 0.0001 ) nbp = ( bp - bp_low ) / denom;
  179.     else nbp = 0.0;
  180.  
  181.     denom = dbp_high - dbp_low;
  182.     if (denom >= 0.0001 ) ndbp = ( dbp - dbp_low ) / denom;
  183.     else ndbp = 0.0;
  184.  
  185.     denom = wd_high - wd_low;
  186.     if (denom >= 0.0001 ) nwd = ( wd - wd_low ) / denom;
  187.     else nwd = 0.0;
  188.  
  189.     denom = dwd_high - dwd_low;
  190.     if (denom >= 0.0001 ) ndwd = ( dwd - dwd_low ) / denom;
  191.     else ndwd = 0.0;
  192.  
  193.     sprintf( buf, "%s %6.3f %6.3f %6.3f %6.3f %6.3f %6.3f %6.3f%s",
  194.        date, nbp, ndbp, nwd, ndwd, prec_tod, prec_tom, prec_nxt, NEW_LINE_STR );
  195.   }
  196. }
  197.  
  198.  
  199. #ifdef ANSI_HEADER
  200. void li_code( double val, double low, double high, int npe, char *sbuf )
  201. #else
  202. void li_code( val, low, high, npe, sbuf )
  203. double  val, low, high;
  204. int npe;
  205. char  *sbuf;
  206. #endif
  207. {
  208.   float increm;
  209.   int wx;
  210.   int pos = 0;
  211.   
  212.   strcpy( sbuf, "" );
  213.   if ( npe > 0 ) {
  214.     increm = ( high - low) / (float) npe;
  215.     if ( increm > 0.0001) pos = (int) ( (val - low) / increm);
  216.     if ( pos < 0 ) pos = 0;
  217.     if ( pos >= npe ) pos = npe - 1;
  218.     for ( wx = 0; wx < npe; wx++ )
  219.       strcat( sbuf, (wx == pos) ? "1" : "0" );
  220.   }
  221. }
  222.  
  223. void decode( )
  224. {
  225.   char  wc; /* work character */
  226.   float *pio; /* pointer to IODATA */
  227.   int wx;
  228.   char  *sp;
  229.  
  230.   if ( nw_type == ADALINE ) {
  231.     pio = IODATA;
  232.     sp  = fbuf[0];
  233.  
  234.     sscanf( sp, "%s", date );
  235.     sp += strlen( date );
  236.  
  237.     for ( wx = 0; wx < ninp; wx++ ) {
  238.       do  sscanf( sp++, "%1c", &wc );
  239.       while ( wc == ' ' ) ;
  240.       if ( wc == '0' ) *pio++ = -1.0;
  241.       else *pio++ = 1.0;
  242.     }
  243.     do  sscanf( sp++, "%1c", &wc );
  244.     while ( wc == ' ' ) ;
  245.     if ( wc == '0' ) prec_tod = -1.0;
  246.     else prec_tod = 1.0;
  247.     do  sscanf( sp++, "%1c", &wc );
  248.     while ( wc == ' ' ) ;
  249.     if ( wc == '0' ) prec_tom = -1.0;
  250.     else prec_tom = 1.0;
  251.     do  sscanf( sp++, "%1c", &wc );
  252.     while ( wc == ' ' ) ;
  253.     if ( wc == '0' ) prec_nxt = -1.0;
  254.     else prec_nxt = 1.0;
  255.   } else {
  256.     sscanf( fbuf[0], "%s %f %f %f %f %f %f %f",
  257.       date, &IODATA[0], &IODATA[1], &IODATA[2], &IODATA[3],
  258.       &prec_tod, &prec_tom, &prec_nxt );
  259.   }
  260. }
  261.  
  262. void disp_rwdw( )   /* Display recall window */
  263. {
  264.   ug_window( 1, gm_intcolor, rstrtx, rstrty, rstrtx + rendx, rstrty + rendy );
  265.   ug_box( 1, gm_outcolor, 0, 0, rendy, rendx, rendy, 0 );
  266.   ug_line( 1, gm_outcolor, 0, rdata, 0, rdata, rendy , 0 );
  267.   ug_line( 1, gm_outcolor, 0, 0, dateline, rendx, dateline , 0 );
  268.   ug_line( 1, gm_outcolor, 0, 0, actline, rendx, actline , 0 );
  269.   ug_puts( 1, gm_txtcolor, 0, X_MARGIN, rtod_y, "Today:", 0 );
  270.   ug_puts( 1, gm_txtcolor, 0, X_MARGIN, ract_y, "Actual:", 0 );
  271.   ug_puts( 1, gm_txtcolor, 0, X_MARGIN, rtom_y, "Tomorrow:", 0 );
  272.   ug_puts( 1, gm_txtcolor, 0, X_MARGIN, rnxt_y, "Next Day:", 0 );
  273. }
  274.  
  275. void disp_forecast( )
  276. {
  277.   int size, x0;
  278.   
  279.   x0 = rdata + 2 + curr_pos * ( chry + 2 );
  280.    
  281.   size = IODATA[0] * chry;
  282.   if ( size < 1 ) size = 1;
  283.   if ( size > chry ) size = chry;
  284.   ug_boxf( 1, gm_txtcolor, 0, x0, rtod_y, x0 + size - 1, rtod_y + size - 1 );
  285.  
  286.   size = prec_tod * chry;
  287.   if ( size < 1 ) size = 1;
  288.   if ( size > chry ) size = chry;
  289.   ug_boxf( 1, gm_txtcolor, 0, x0, ract_y, x0 + size - 1, ract_y + size - 1 );
  290.  
  291.   ug_puts( 1, gm_txtcolor, 0, x0 + chry + 1, dateline + 2, date, 1 );
  292.  
  293.   x0 += chry+2;
  294.   size = IODATA[1] * chry;
  295.   if ( size < 1 ) size = 1;
  296.   if ( size > chry ) size = chry;
  297.   ug_boxf( 1, gm_txtcolor, 0, x0, rtom_y, x0 + size - 1, rtom_y + size - 1 );
  298.  
  299.   x0 += chry+2;
  300.   size = IODATA[2] * ( chry );
  301.   if ( size < 1 ) size = 1;
  302.   if ( size > chry ) size = chry;
  303.   ug_boxf( 1, gm_txtcolor, 0, x0, rnxt_y, x0 + size - 1, rnxt_y + size - 1 );
  304.    
  305. }
  306.  
  307.  
  308. /************************************************************************
  309.  *
  310.  *  UsrIO - user I/O routine to handle requests from NWORKS
  311.  *
  312.  ************************************************************************
  313.  */
  314.  
  315. static int AbortFlag  = 0;
  316. static int InitFlag = 0;
  317.  
  318. int UsrIO()     /* handle NWORKS requests */
  319. {
  320.     int   wx;       /* work indices */
  321.     int   key, xp, yp, button;      /* mouse interface */
  322.     char  *sp;          /* string pointer */
  323.     long   total_npe;       /* Total # PEs */
  324.     int   oldwd;
  325.     float oldbp;
  326.     char  sbuf[100];        /* string buffer */
  327.  
  328.     IORTNCDE = 0;       /* good return for data */
  329.     
  330.     if ( InitFlag == 0 ) {
  331.       /* Read network parameters */
  332.       ug_rdnetinf( &nlayp, &ninp, &noutp, <ype, &csp, &netnp );
  333.       /* strcpy( file_name, netnp ); */
  334.       strcpy( file_name, "june.dat" );
  335.  
  336.       /* Get graphics parameters */
  337.       ug_gparms( &xsize, &ysize, &ncolor, &chrx, &chry );
  338.       
  339.       if ( ncolor < 8 ) {
  340.   gm_intcolor = 1;
  341.   gm_txtcolor = 0;
  342.   gm_outcolor = 0;
  343.       } else {
  344.   gm_intcolor = 7;
  345.   gm_txtcolor = 4;
  346.   gm_outcolor = 0;
  347.       }
  348.  
  349.       ract_y = Y_MARGIN;
  350.       actline = ract_y + chry + 2;
  351.       rnxt_y = ract_y + Y_MARGIN + chry + 1;
  352.       rtom_y = rnxt_y + Y_MARGIN + chry;
  353.       rtod_y = rtom_y + Y_MARGIN + chry;
  354.       dateline = rtod_y + chry + Y_MARGIN + 1;
  355.       rendy = dateline + 8 * chrx + 2 * Y_MARGIN + 1;
  356.       rdata = 9 * chrx + 2 * X_MARGIN + 2;
  357.       rendx = rdata + 2 * X_MARGIN + ( chry + 2 ) * NUM_DISP + 1;
  358.  
  359.       rstrtx = ( xsize - rendx ) / 2;
  360.       rstrty = ( ysize - rendy ) / 2;
  361.       InitFlag = 1;
  362.     }
  363.     
  364.     
  365.     switch( IOREQCDE ) {
  366.     case RQ_ATTENTION:
  367.   /* This is invoked at the request of the user from the
  368.      execute menu.  It allows parameters to be changed or
  369.      altered.  Any graphics or other interactions are allowable
  370.      as usual for the other options.
  371.   */
  372.       if ( ifp != (FILE *) NULL ) fclose( ifp );
  373.       if ( fp != (FILE *) NULL ) fclose( fp );
  374.  
  375.       ug_rdnetinf( &nlayp, &ninp, &noutp, <ype, &csp, &netnp );
  376.       if ( strcmpl( csp, "Adaline") == 0 ) nw_type = ADALINE;
  377.       else nw_type = OTHER;
  378.  
  379.       PutStr(
  380.  "This will process your weather file to a form acceptable by the network\n");
  381.       /* Read weather file */
  382.       PutStr("Enter name of weather data file:");
  383.       sp = GetStr( );
  384.  
  385.       if ( ( fp = fopen( sp, "r" ) ) == NULL) {
  386.   sprintf( sbuf, "Cannot find file <%s>\n", sp );
  387.   PutStr( sbuf );
  388.   goto bad_return;
  389.       }
  390.  
  391.       PutStr("Enter name of transformed file:");
  392.       sp = GetStr( );
  393.  
  394. #ifndef MAC     
  395.       unlink( sp ); /* delete if it already exists */
  396. #endif
  397.        if ( ( ifp = fopen( sp, "w" ) ) == NULL) {
  398.    sprintf( sbuf, "Cannot open file <%s>\n", sp );
  399.    PutStr( sbuf );
  400.    goto bad_return;
  401.       }
  402.       strcpy( file_name, sp );
  403.  
  404.  
  405.       /****************************************/
  406.       /* Read in weather parameters from file */
  407.       /****************************************/
  408.       if ( fgets( fbuf[0], MAX_STR, fp) == 0 ) {
  409.   PutStr("Could not read precipitation threshold; i/o aborted\n");
  410.   goto bad_return;
  411.       }
  412.       sscanf( fbuf[0], "%f", &prec_thr );
  413.  
  414.       if ( fgets( fbuf[0], MAX_STR, fp) == 0 ) {
  415.   PutStr(
  416.       "Could not read barometric pressure parameters; i/o aborted\n");
  417.   goto bad_return;
  418.       }
  419.       sscanf( fbuf[0], "%f %f %ld",
  420.        &bp_low, &bp_high, &bp_npe );
  421.               
  422.       if ( fgets( fbuf[0], MAX_STR, fp) == 0 ) {
  423.   PutStr(
  424.       "Could not read delta barometric pressure parameters; i/o aborted\n");
  425.   goto bad_return;
  426.       }
  427.       sscanf( fbuf[0], "%f %f %ld",
  428.        &dbp_low, &dbp_high, &dbp_npe );
  429.  
  430.       if ( fgets( fbuf[0], MAX_STR, fp) == 0 ) {
  431.   PutStr("Could not read weather direction parameters; i/o aborted\n");
  432.   goto bad_return;
  433.       }
  434.       sscanf( fbuf[0], "%f %f %ld",
  435.        &wd_low, &wd_high, &wd_npe );
  436.               
  437.       if ( fgets( fbuf[0], MAX_STR, fp) == 0 ) {
  438.   PutStr(
  439.       "Could not read delta weather direction parameters; i/o aborted\n");
  440.   goto bad_return;
  441.       }
  442.       sscanf( fbuf[0], "%f %f %ld",
  443.        &dwd_low, &dwd_high, &dwd_npe );
  444.  
  445.       if ( nw_type == ADALINE )
  446.   total_npe = bp_npe + dbp_npe + wd_npe + dwd_npe;
  447.       else total_npe = 4;
  448.     
  449.       sprintf(fbuf[0], "%ld %f    ! Number PEs, precipitation threshold%s",
  450.           total_npe, prec_thr,NEW_LINE_STR );
  451.       fputs( fbuf[0], ifp );
  452.       
  453.       /****************************************************************/
  454.       /* Read in weather data from file, convert, write to input file */
  455.       /****************************************************************/
  456.       tod_buff = 0;
  457.       tom_buff = 1;
  458.       nxt_buff = 2;
  459.       /* Read in first three lines of data */
  460.       if ( fgets( fbuf[tod_buff], MAX_STR, fp ) == 0 ) {
  461.   PutStr(" Insufficient data! ");
  462.   goto bad_return;
  463.       }
  464.       if ( fgets( fbuf[tom_buff], MAX_STR, fp ) == 0 ) {
  465.   PutStr(" Insufficient data! ");
  466.   goto bad_return;
  467.       }
  468.       if ( fgets( fbuf[nxt_buff], MAX_STR, fp ) == 0 ) {
  469.   PutStr(" Insufficient data! ");
  470.   goto bad_return;
  471.       }
  472.       sscanf( fbuf[nxt_buff], "%s %f %ld %f", date, &bp, &wd, &prec_nxt );
  473.       sscanf( fbuf[tom_buff], "%s %f %ld %f", date, &bp, &wd, &prec_tom );
  474.       sscanf( fbuf[tod_buff], "%s %f %ld %f", date, &bp, &wd, &prec_tod );
  475.       dbp = 0.0;
  476.       dwd = 0;
  477.       encode( fbuf[tod_buff] );
  478.       fputs( fbuf[tod_buff], ifp );
  479.       oldbp = bp;
  480.       oldwd = wd;
  481.  
  482.       while ( fgets(fbuf[tod_buff],MAX_STR,fp) != 0 ) {
  483.   wx = tod_buff;      /* rotate buffer indices */
  484.   tod_buff = tom_buff;
  485.   tom_buff = nxt_buff;
  486.   nxt_buff = wx;
  487.   sscanf( fbuf[nxt_buff], "%s %f %ld %f", date, &bp, &wd, &prec_nxt );
  488.   sscanf( fbuf[tom_buff], "%s %f %ld %f", date, &bp, &wd, &prec_tom );
  489.   sscanf( fbuf[tod_buff], "%s %f %ld %f", date, &bp, &wd, &prec_tod );
  490.   dbp = bp - oldbp;
  491.   dwd = wd - oldwd;
  492.   if ( dwd > 180 ) dwd -= 360;
  493.   else if ( dwd <= -180 ) dwd += 360;
  494.   encode( fbuf[tod_buff] );
  495.   fputs( fbuf[tod_buff], ifp );
  496.   oldbp = bp;
  497.   oldwd = wd;
  498.       }
  499.       
  500.       fclose( fp );
  501.       fclose( ifp );
  502.       PutStr( "Data successfully transformed\n" );
  503.       return(0);
  504.  
  505. bad_return:
  506.       IORTNCDE = -1;
  507.       if ( ifp != (FILE *) NULL ) fclose( ifp );
  508.       if ( fp != (FILE *) NULL ) fclose( fp );
  509.  
  510.       break;
  511.  
  512.     case RQ_LSTART:       /* starting learn */
  513.   /* This tells the user that the program is about to start
  514.      learning.  It is called once for a LEARN ALL, LEARN ONE,
  515.      LEARN N, or LEARN START
  516.   */
  517.     case RQ_RSTART:       /* starting recall */
  518.   /* This tells the user that the program is about to start
  519.      a recall.  It is called once for a RECALL ALL, RECALL ONE,
  520.      RECALL N, or RECALL START.
  521.   */
  522.  
  523.       AbortFlag = 0;
  524.       /* Read network parameters */
  525.       ug_rdnetinf( &nlayp, &ninp, &noutp, <ype, &csp, &netnp );
  526.       if ( strcmpl( csp, "Adaline") == 0 ) nw_type = ADALINE;
  527.       else nw_type = OTHER;
  528.  
  529.       /* Read weather file */
  530.       if ( ifp != (FILE *) NULL ) fclose( ifp );
  531.       sprintf( sbuf, "Enter name of input file ( default: %s ):", file_name );
  532.       PutStr( sbuf );
  533.       sp = GetStr();
  534.       PutStr("\n");
  535.       if ( strcmp( sp, "" ) != 0 ) strcpy( file_name, sp );
  536.  
  537.       if ( ( ifp = fopen( file_name, "r" ) ) == NULL ) {
  538.   sprintf( sbuf, "Cannot find file <%s>\n", file_name );
  539.   PutStr( sbuf );
  540.   goto abort;
  541.       }
  542.  
  543.       /* Read in header */
  544.         if ( fgets( fbuf[0], MAX_STR, ifp ) == 0 ) {
  545.   PutStr("Cannot read header; i/o aborted\n");
  546.   goto abort;
  547.       }
  548.       sscanf( fbuf[0], "%ld %f", &total_npe, &prec_thr );
  549.  
  550.      if ( total_npe != ninp ) {
  551.        PutStr( "Mismatch between network and input file; i/o aborted\n");
  552.        sprintf( sbuf,
  553.    "Number of network inputs = %ld, number of file inputs = %ld\n",
  554.     (long)ninp, total_npe );
  555.        PutStr( sbuf );
  556.        goto abort;
  557.      }
  558.  
  559.      num_readings = 0;
  560.      if ( IOREQCDE == RQ_RSTART ) {
  561.        disp_rwdw( );
  562.        curr_pos = 0;
  563.        no_more_data = 0;
  564.        tod_correct = tom_correct = nxt_correct = 0.0;
  565.      }
  566.      else {
  567.        start_pos = ftell( ifp );  /* start position for file data */
  568.        tod_mse = tom_mse = nxt_mse = 0.0; /* Initialize mean square errors */
  569.      }
  570.      return(0);
  571.      
  572. abort:
  573.      IORTNCDE = -1;
  574.      AbortFlag = 1;
  575.      if ( ifp != (FILE *) NULL ) fclose( ifp );
  576.  
  577.      break;
  578.  
  579.     case RQ_LEARNIN:        /* read training input */
  580.   /* IODATA points to an empty array of IOCOUNT elements.  The
  581.      values placed in this array by the user will become the
  582.      inputs to the network for training purposes.
  583.   */
  584.       if ( AbortFlag ) {
  585.   IORTNCDE = -1;
  586.   return(0);
  587.       }
  588.       num_readings++;
  589.       if ( fgets( fbuf[0], MAX_STR, ifp ) == 0 ) {
  590.   fseek( ifp, start_pos, 0 ); /* If at end return to start */
  591.   fgets( fbuf[0], MAX_STR, ifp );
  592.   sprintf ( sbuf,
  593.     "Mean square error. today: %5.3f, tomorrow: %5.3f, next day: %5.3f\n",
  594.       sqrt(tod_mse) / num_readings,
  595.       sqrt(tom_mse) / num_readings,
  596.       sqrt(nxt_mse) / num_readings );
  597.   PutStr( sbuf );
  598.   tod_mse = tom_mse = nxt_mse = 0.0;
  599.   num_readings = 0;
  600.       }
  601.       decode( );
  602.       break;
  603.       
  604.     case RQ_READ:       /* read test data */
  605.   /* IODATA points to an empty array of IOCOUNT values.  The
  606.      user must fill in these values.  The elements of the
  607.      array will become the "sum" of the inputs to the input
  608.      layer of processing elements.
  609.   */ 
  610.       /* Read next line of data from file */
  611.  
  612.       if ( AbortFlag ) {
  613.   IORTNCDE = -1;
  614.   return;
  615.       }
  616.  
  617.       if ( fgets( fbuf[0], MAX_STR, ifp ) != 0 ) {
  618.   decode( );
  619.   num_readings++;
  620.       }
  621.       else no_more_data = 1;
  622.       break;
  623.  
  624.     case RQ_LEARNOUT:       /* read desired output */
  625.   /* IODATA points to an empty array of IOCOUNT values.  The
  626.      elements of the array will become the desired outputs for
  627.      training purposes.  These desired outputs correspond to
  628.      the most recent "RQ_LEARNIN" request.
  629.   */
  630.     case RQ_RCLTST:   /* read desired output during recall test */
  631.   /* IODATA points to an empty array of IOCOUNT values.  The
  632.      elements of the array will become the desired outputs for
  633.      recall purposes.  This request is only made during a
  634.      Execute Network/Recall Test.
  635.   */
  636.  
  637.   IODATA[0] = prec_tod;
  638.   IODATA[1] = prec_tom;
  639.   IODATA[2] = prec_nxt;
  640.         break;
  641.  
  642.       
  643.     case RQ_WRSTEP:       /* write interim results */
  644.   /* each recall cycle for the Hopfield and BAM control strategies,
  645.      the intermediate output is made available to userio to test
  646.      for convergence or other desired states.  This option is
  647.      not used for other control strategies.
  648.   */
  649.   if (AbortFlag) {
  650.     IORTNCDE = -1;
  651.     return;
  652.   } 
  653.   break;
  654.  
  655.  
  656.     case RQ_LEARNRSLT:
  657.   /* IODATA points to an array of IOCOUNT values.  These are the
  658.      output of the network caused by the inputs from RQ_LEARNIN.
  659.   */
  660.   if (AbortFlag) {
  661.     IORTNCDE = -1;
  662.     return;
  663.   } 
  664.   tod_mse += ( IODATA[0] - prec_tod ) * ( IODATA[0] - prec_tod );
  665.   tom_mse += ( IODATA[1] - prec_tom ) * ( IODATA[1] - prec_tom );
  666.   nxt_mse += ( IODATA[2] - prec_nxt ) * ( IODATA[2] - prec_nxt );
  667.   break;
  668.  
  669.     case RQ_WRITE:        /* write out results */
  670.   /* IODATA points to an array of IOCOUNT "float" type values.
  671.      The values are the outputs of the top-most layer of the
  672.      network.
  673.   */
  674.  
  675.   if (AbortFlag) {
  676.     IORTNCDE = -1;
  677.     return;
  678.   } 
  679.  
  680.   if ( no_more_data ) {
  681.     PutStr( "No more data; press mouse button to quit.\n" );
  682.     sprintf( sbuf,
  683.  "Percentage correct: today: %5.1f, tomorrow: %5.1f, next day: %5.1f\n",
  684.              ( tod_correct / num_readings ) * 100.0,
  685.              ( tom_correct / num_readings ) * 100.0,
  686.              ( nxt_correct / num_readings ) * 100.0 );
  687.     PutStr( sbuf );
  688.     for ( ; ; ) {
  689.       ug_mouse( &key, &xp, &yp, &button );
  690.       if ( button == MBUT_RIGHT || button == MBUT_LEFT ) {
  691.         IORTNCDE = -1;
  692.         goto end_write;
  693.       }
  694.     }
  695.         } else {
  696.     if ( (IODATA[0] >= prec_thr && prec_tod >= prec_thr) ||
  697.          (IODATA[0] < prec_thr && prec_tod < prec_thr) )
  698.       tod_correct += 1.0;
  699.     if ( (IODATA[1] >= prec_thr && prec_tom >= prec_thr) ||
  700.          (IODATA[1] < prec_thr && prec_tom < prec_thr) )
  701.       tom_correct += 1.0;
  702.     if ( (IODATA[2] >= prec_thr && prec_nxt >= prec_thr) ||
  703.          (IODATA[2] < prec_thr && prec_nxt < prec_thr) )
  704.       nxt_correct += 1.0;
  705.     disp_forecast( );
  706.     if ( ++curr_pos >= NUM_DISP ) {
  707.       curr_pos = 0;
  708. #ifdef MAC
  709.       PutStr(
  710.         "Press mouse button to continue; clover mouse button to abort.\n" );
  711. #else
  712.       PutStr(
  713.         "Press right button to abort, left button to continue.\n" );
  714. #endif
  715.       for ( ; ; ) {
  716.         ug_mouse( &key, &xp, &yp, &button );
  717.         if ( button == MBUT_RIGHT ) {
  718.           IORTNCDE = -1;
  719.           goto end_write;
  720.         }
  721.         if ( button == MBUT_LEFT  ) {
  722.     disp_rwdw( ); /* Redisplay recall window */
  723.     goto end_write;
  724.         }
  725.       }
  726.     }
  727.         }
  728. end_write:
  729.   break;
  730.  
  731.     case RQ_TERM:       /* terminate interface */
  732.   /* close any files which may be open.  Deallocate any memory
  733.      which was allocated.  (This is VERY VERY important.  If
  734.      allocated memory is NOT released, dos memory will become
  735.      fragmented and it will become necessary to reboot.
  736.   */
  737.  
  738.   PutStr( "bye bye\n" );
  739.   if ( ifp != (FILE *) NULL ) fclose( ifp );
  740.   if ( fp != (FILE *) NULL ) fclose( fp );
  741.   break;
  742.     }
  743.  
  744.     return;
  745. }
  746.