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

  1. /* 11:05 04-Jul-88  (stockio.c)  Stock Prediction I/O module */
  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.  
  15. #include "userutl.h"
  16. #include <string.h>
  17. #include <math.h>
  18. #ifndef SUN
  19. #ifndef DLC
  20. #include <stdlib.h>
  21. #endif
  22. #endif
  23.  
  24. #ifdef MAC
  25. #include  "macuio.redef"
  26. #endif
  27.  
  28. /************************************************************************
  29.  *                                                                      *
  30.  *  Custom Interface for Stock Prediction                               *
  31.  *                                                                      *
  32.  ************************************************************************
  33.  This provides a convenient method of displaying the stock data and 
  34.  and comparing network prediction to actual as well as 10-week moving
  35.  average.
  36.  */
  37.  
  38. static int InitFlag = 0;    /* initialize things flag */
  39. static int *null_ptr  = 0;    /* to handle Microsoft C bug */
  40.  
  41. /*   */
  42. /************************************************************************
  43.  *                                                                      *
  44.  *  Window management                                                   *
  45.  *                                                                      *
  46.  ************************************************************************
  47.  */
  48.  
  49. #define W0  1   /* main window */
  50. #define CHT 16    /* character height */
  51.  
  52. #if 1
  53. int W0_Wid  = {480};  /* basic defining parameters */
  54. int W0_Ht = {200};  /* height of graph */
  55. int W0_Sep  = { 50};  /* separation */
  56. int W0_Pix  = {  1};  /* pixel size */
  57. #else
  58. #ifdef SUN
  59. #define W0_Wid  800
  60. #define W0_Ht 400
  61. #define W0_Sep  100
  62. #else
  63. #define W0_Wid  480
  64. #define W0_Ht 200
  65. #define W0_Sep   50
  66. #endif
  67. #endif  /* #if 1 */
  68.  
  69. #define MX_ALL  (10)        /* x-for all messages */
  70. #define MY_1  (MX_ALL+10+(W0_Sep*1)/2)  /* y-for messages */
  71. #define MY_2  (MX_ALL+10+(W0_Sep*3)/2)
  72. #define MY_3  (MX_ALL+10+(W0_Sep*5)/2)
  73.  
  74. #define EX0 MX_ALL
  75. #define EX1 (W0_Wid-MX_ALL)
  76. #define EY0 (MX_ALL)
  77. #define EY1 (W0_Ht-MX_ALL)
  78. #define EHT (W0_Ht-2*MX_ALL)
  79.  
  80. /*   */
  81. /************************************************************************
  82.  *                                                                      *
  83.  *  SetParms() - set up basic display size parameters                   *
  84.  *                                                                      *
  85.  ************************************************************************
  86.  */
  87.  
  88. void SetParms()
  89. {
  90.   int xsize, ysize, ncolor, chrx, chry; /* graphic parms */
  91.   int   ifx, ify;     /* integer factor */
  92.   
  93.   ug_gparms( &xsize, &ysize, &ncolor, &chrx, &chry );
  94.   
  95.   ifx = (double)xsize / (double)W0_Wid;
  96.   ify = (double)ysize / (double)W0_Ht;
  97.   
  98.   if ( ifx > 1 ) {
  99.     W0_Wid *= ifx;
  100.   }
  101.   if ( ify > 1 ) {
  102.     W0_Ht  *= ify;
  103.     W0_Sep *= ify;
  104.   }
  105.   if ( ifx > 1 && ify > 1 ) {
  106.     W0_Pix = 2;
  107.   }
  108.   
  109.   return;
  110. }
  111. /*   */
  112. /************************************************************************
  113.  *                                                                      *
  114.  *  PlotArray() - plot a window full of data                            *
  115.  *                                                                      *
  116.  ************************************************************************
  117.  */
  118.  
  119. #ifdef MAC
  120. #define MAIN_COLOR  2
  121. #define AUX_COLOR 5
  122. #else
  123. #define MAIN_COLOR  6
  124. #define AUX_COLOR 13
  125. #endif
  126.  
  127. typedef struct _WinBlk {
  128.   int  Win;   /* window handle */
  129.   char  *Title;   /* title */
  130.   int  X0,Y0;   /* coordinates of origin */
  131.   int  X1,Y1;   /* coordinates of top right */
  132.   int  XOff;    /* x-offset */
  133.   int  XInc;    /* x-increment */
  134.   double   Scale, Offset; /* scaling */
  135.   int  px, py;  /* previous x,y */
  136.   int  ArraySize; /* array size */
  137.   int  cwx;   /* current work index */
  138.   float *SavArray;  /* save array */
  139.   char  *SavFlag; /* save flags */
  140. } WB;
  141.  
  142.  
  143. #ifdef PROTOTYPING
  144. void PlotSet( WB *, int, char *, int, int, int, int, int, int, double, double,
  145.          float *, char *, int );
  146. void PlotClear( WB * );
  147. void PlotArray( WB *, float *, float *, int, int );
  148. void PlotSave(  WB * );
  149. void PlotNext(  WB *, double, double, int, int );
  150. #endif
  151.  
  152.  
  153. void PlotSet( WBp, Win, Title, X0,Y0, X1,Y1, XOff, XInc, Scale, Offset,
  154.          SaveA, SaveF, NSave )
  155.      WB  *WBp;     /* window block pointer */
  156.      int  Win;
  157.      char  *Title;
  158.      int  X0,Y0, X1,Y1;
  159.      int  XOff;
  160.      int  XInc;
  161.      double   Scale, Offset;
  162.      float *SaveA;
  163.      char  *SaveF;
  164.      int  NSave;
  165. {
  166.   WBp->Win  = Win;
  167.   WBp->Title  = Title;
  168.   WBp->X0 = X0;
  169.   WBp->Y0 = Y0;
  170.   WBp->X1 = X1;
  171.   WBp->Y1 = Y1;
  172.   WBp->XOff = XOff;
  173.   WBp->XInc = XInc;
  174.   WBp->Scale  = Scale;
  175.   WBp->Offset = Offset;
  176.   WBp->px = X0 - XInc + (XOff * XInc);
  177.   WBp->py = Y0;
  178.   WBp->cwx  = 0;
  179.   WBp->ArraySize = NSave;
  180.   WBp->SavArray  = SaveA;
  181.   WBp->SavFlag   = SaveF;
  182. }
  183.  
  184.  
  185. void PlotClear( WBp )
  186.      WB  *WBp;
  187. {
  188.   int wx;
  189.   
  190.   WBp->px = WBp->X0 - WBp->XInc + (WBp->XOff * WBp->XInc);
  191.   WBp->py = WBp->Y0;
  192.   WBp->cwx = 0;
  193.   
  194.   if ( WBp->SavArray != (float *)null_ptr ) {
  195.     for( wx = 0; wx < WBp->ArraySize; wx++ ) {
  196.       WBp->SavArray[wx] = 0.0;
  197.       WBp->SavFlag[wx]  = 0;
  198.     }
  199.   }
  200.   
  201.   /* clear out the background */
  202.   ug_boxf( WBp->Win, 0, 0, WBp->X0, WBp->Y0, WBp->X1, WBp->Y1 );
  203.   
  204.   /* outline box */
  205.   ug_box( WBp->Win,  8, 0, WBp->X0-1, WBp->Y0-1, WBp->X1+1, WBp->Y1+1, 0 );
  206.   
  207.   return;
  208. }
  209.  
  210.  
  211.  
  212. void PlotArray( WBp, MDp, ADp, NPts, off )
  213.      WB  *WBp;   /* window block pointer */
  214.      float *MDp;   /* main data array */
  215.      float *ADp;   /* aux data array */
  216.      int  NPts;    /* # of points in the array */
  217.      int  off;   /* offset for multiple plots */
  218. {
  219.   int cx, cy;   /* current x,y point */
  220.   int px, py;   /* previous x,y point */
  221.   int ay;   /* y-coordinate of alternate data */
  222.   int nx;   /* index */
  223.   int lcolor;   /* line color */
  224.   
  225.   if ( off == 0 ) {
  226.     /* clear out the background */
  227.     ug_boxf( WBp->Win, 0, 0, WBp->X0, WBp->Y0, WBp->X1, WBp->Y1 );
  228.     
  229.     /* outline box */
  230.     ug_box( WBp->Win,  8, 0, WBp->X0-1,WBp->Y0-1,WBp->X1+1,WBp->Y1+1, 0 );
  231.   }
  232.   
  233.   /* plot the data */
  234.   px = WBp->X0 - WBp->XInc + WBp->XOff * WBp->XInc;
  235.   py = px;
  236.   lcolor = ADp == (float *)null_ptr?MAIN_COLOR:AUX_COLOR;
  237.   for( nx = 0; nx < NPts && px < WBp->X1; nx++ ) {
  238.     /* next x-location */
  239.     cx = px + WBp->XInc;
  240.     
  241.     /* y-coordinate & clip it */
  242.     cy = off+ WBp->Y0 + ((MDp[nx] + WBp->Offset) * WBp->Scale);
  243.     if ( cy < WBp->Y0 ) cy = WBp->Y0;
  244.     if ( cy > WBp->Y1 ) cy = WBp->Y1;
  245.     if ( cx > WBp->X1 ) cx = WBp->X1;
  246.     if ( nx != 0 ) {
  247.       ug_line( WBp->Win, lcolor, 0, px, py, cx, cy, 0 );
  248.     }
  249.     
  250.     /* auxiliary data */
  251.     if ( ADp != (float *)null_ptr ) {
  252.       ay = off+ WBp->Y0 + ((ADp[nx] + WBp->Offset) * WBp->Scale);
  253.       if ( ay < WBp->Y0 )  ay = WBp->Y0;
  254.       if ( ay > WBp->Y1 )  ay = WBp->Y1;
  255. #if 1
  256.       if ( W0_Pix > 1 )
  257.     ug_boxf(  WBp->Win,  MAIN_COLOR, 0,
  258.         cx-(W0_Pix-1), ay-(W0_Pix-1), cx+(W0_Pix-1), ay+(W0_Pix-1) );
  259.       else
  260.     ug_point( WBp->Win,  MAIN_COLOR, 0, cx, ay );
  261. #else
  262. #ifdef SUN
  263.       ug_boxf(  WBp->Win,  MAIN_COLOR, 0, cx-1, ay-1, cx+1, ay+1 );
  264. #else
  265.       ug_point( WBp->Win,  MAIN_COLOR, 0, cx, ay );
  266. #endif
  267. #endif
  268.     }
  269.     /* track the last point */
  270.     px = cx;
  271.     py = cy;
  272.   }
  273.   
  274.   if ( WBp->Title != (char *)null_ptr )
  275.     ug_puts( WBp->Win, 15, 0, WBp->X0+5, WBp->Y1-15, WBp->Title, 0 );
  276.   
  277.   return;
  278. }
  279.  
  280.  
  281.  
  282. void PlotSave( WBp )
  283.      WB  *WBp;
  284. {
  285.   int n;
  286.   
  287.   n = WBp->cwx;
  288.   if ( WBp->SavFlag[WBp->ArraySize-1] != 0 ) n = WBp->ArraySize;
  289.   
  290.   if ( WBp->Scale > 0.0 )
  291.     PlotArray( WBp, WBp->SavArray, (float *)null_ptr, n, 0 );
  292. }
  293.  
  294.  
  295.  
  296. void PlotNext( WBp, MV, AV, af, cf )    /* plot next point */
  297.      WB  *WBp;   /* window block pointer */
  298.      double   MV;    /* main value */
  299.      double   AV;    /* auxiliary value */
  300.      int  af;    /* aux data flag */
  301.      int  cf;    /* cursor flag */
  302. {
  303.   int ay;
  304.   int cx, cy;
  305.   
  306.   if ( cf != 0 && WBp->Scale > 0.0 ) {
  307.     if ( WBp->X0 <= WBp->px && WBp->px < WBp->X1 ) {
  308.       ug_line( WBp->Win, 0, 0, WBp->px+1,WBp->Y0,WBp->px+1,WBp->Y1, 0 );
  309.     }
  310.   }
  311.   
  312.   cx = WBp->px + WBp->XInc;
  313.   cy = WBp->Y0 + (MV + WBp->Offset) * WBp->Scale;
  314.   if ( cy < WBp->Y0 )  cy = WBp->Y0;
  315.   if ( cy > WBp->Y1 )  cy = WBp->Y1;
  316.   if ( cx > WBp->X1 )  cx = WBp->X1;
  317.   if ( WBp->px < cx && WBp->Scale > 0.0 &&
  318.       WBp->px >= (WBp->X0 + WBp->XOff * WBp->XInc) ) {
  319.     ug_line( WBp->Win, MAIN_COLOR, 0, WBp->px, WBp->py, cx, cy, 0 );
  320.     if ( af ) {
  321.       ay = WBp->Y0 + (AV + WBp->Offset) * WBp->Scale;
  322.       if ( ay < WBp->Y0 ) ay = WBp->Y0;
  323.       if ( ay > WBp->Y1 ) ay = WBp->Y1;
  324.       ug_point( WBp->Win, MAIN_COLOR, 0, cx, ay );
  325.     }
  326.   }
  327.   if ( cx >= WBp->X1 ) cx = WBp->X0;    /* wrap */
  328.   if ( WBp->SavArray != (float *)null_ptr ) {
  329.     WBp->SavArray[WBp->cwx] = MV;
  330.     WBp->SavFlag[WBp->cwx]  = 1;
  331.     WBp->cwx++;
  332.     if ( WBp->cwx >= WBp->ArraySize || cx == WBp->X0 ) {
  333.       WBp->cwx = 0;     /* force wrap */
  334.       cx = WBp->X0;
  335.     }
  336.   }
  337.   
  338.   WBp->px = cx;
  339.   WBp->py = cy;
  340.   
  341.   if ( cf != 0 && WBp->Scale > 0.0 && WBp->px < WBp->X1 ) {
  342.     ug_line( WBp->Win, 15, 0, WBp->px+1, WBp->Y0, WBp->px+1, WBp->Y1, 0 );
  343.   }
  344.   
  345.   return;
  346. }
  347. /*   */
  348. /************************************************************************
  349.  *                                                                      *
  350.  *  Learning Error display                                              *
  351.  *                                                                      *
  352.  ************************************************************************
  353.  
  354.  There are three windows:
  355.  top - 4-week moving average w/actual data too
  356.  mid - neural network (learning error)
  357.  bot - original data
  358.  */
  359.  
  360. WB  EWB = {0};    /* error */
  361. WB  MWB = {0};    /* main */
  362.  
  363. #define ENPts   526 /* # of error points */
  364. #define EYVals    90  /* # of y-values */
  365.  
  366. int ECtr    = 0;    /* current "data" item */
  367.  
  368. double  EXScale   = 0.0;  /* x-scale factor */
  369. double  EXOffset  = 0.0;  /* error offset */
  370.  
  371. float EVals[ENPts]  = {0};    /* error values */
  372. char  EVFlag[ENPts] = {0};    /* error value valid flag */
  373.  
  374. /*   */
  375. /************************************************************************
  376.  *                                                                      *
  377.  *  Common data & statics                                               *
  378.  *                                                                      *
  379.  ************************************************************************
  380.  */
  381.  
  382. /* data set definitions */
  383.  
  384. #define NTPTS     491               /* number of pts in data file */
  385. #define SetSize   450               /* size of training set */
  386. float   TrainSet[NTPTS+1] = {0.0};  /* current training set */
  387. float NetPred[NTPTS+1]  = {0.0};  /* network prediction */
  388. float TenPred[NTPTS+1]  = {0.0};  /* moving average prediction */
  389. int InputLen= 0;        /* input length */
  390. int     TSetL   = 0;              /* training set length */
  391. int TrainSz = 50;       /* training samples per pass */
  392. int ToTrain = 0;        /* # of items still to train */
  393. long  Pass  = 0;        /* pass number */
  394. int DataCtr = 0;        /* data counter */
  395. int NextFlag= 0;        /* next cycle flag */
  396. float LastDR  = 0.0;      /* last desired result */
  397. float MSE = 0.0;      /* mean square error for a data set */
  398. int     x       = 0;              /* previous x-coordinate */
  399. int     ynew    = 0;              /* current y-coordinate */
  400. int     yold    = 0;              /* previous y-coordinate */
  401. int     yout    = 0;              /* network out y-coordinate */
  402. int     xlag    = 14;             /* first x-coordinate for network out */
  403. int HitRate = 0;        /* # of successful times it predicts trend*/
  404. int HitTen  = 0;        /* 10-week hit rate */
  405. int TotalCt = 0;        /* Total # of recalls */
  406. float PrevWk  = 0.0;      /* previous week output */
  407. float PrevPrd = 0.0;      /* previously predicted output */
  408. float CurTen  = 0.0;      /* current 10-wk moving average */
  409. float PrevTen = 0.0;      /* previous 10-wk moving average */
  410. double  maxe  = 0.0;      /* max error (%) */
  411.      int maxect  = 0;        /* max error count */
  412.      double  maxe2 = 0.0;      /* max error > 20% */
  413.      int maxe2ct = 0;        /* max error 2 count */
  414.      double  TotErr  = 0.0;      /* total error over all cases */
  415.      /*   */
  416.      /************************************************************************
  417.       *                                                                      *
  418.       *  Training Set Input / Check it is there Routines                     *
  419.       *                                                                      *
  420.       ************************************************************************
  421.       */
  422.      
  423.      int IsTSOk()
  424. {
  425.   IORTNCDE = 0;
  426.   if ( TSetL <= 0 ) {
  427.     IORTNCDE = -1;      /* end of file */
  428.   }
  429.   
  430.   return( IORTNCDE );
  431. }
  432.  
  433.  
  434. int ReadTS( buf )
  435.      char    *buf;   /* work buffer */
  436. {
  437.   FILE  *fp;    /* input file pointer */
  438.   char  *sp;    /* input string */
  439.   int    c;   /* work character */
  440.   int    wx;    /* work index */
  441.   
  442.   TSetL = 0;
  443.   for(;;) {
  444.     PutStr ("What is the training input File (<RETURN> for default) ?");
  445.     sp = GetStr();
  446.     while( *sp && *sp <= ' ' ) sp++;  /* skip leading white space */
  447.     if ( *sp == '\0' ) {
  448.       sp = "sp500.in";      /* default string */
  449.     }
  450.     
  451.     fp = fopen (sp, "r");    
  452.     if (fp == (FILE *) 0) {
  453.       sprintf( buf, "Could not open <%s>\n", sp );
  454.       PutStr( buf );
  455.       continue;
  456.     }
  457.     
  458.     for ( wx = 0; wx < NTPTS;)   {
  459.       if ( fgets( &buf[0], 80, fp ) == 0 ) break;
  460.       
  461.       /* kill any comments */
  462.       
  463.       for( sp = &buf[0]; (c = *sp) != '\0'; sp++ ) {
  464.     if ( c == '!' || c == '*' || c == '\r' || c == '\n' )
  465.       break;
  466.       }
  467.       *sp = '\0';     /* kill comments, etc */
  468.       
  469.       /* skip leading space and check for blank lines */
  470.       
  471.       for( sp = &buf[0]; *sp && *sp <= ' '; ) sp++;
  472.       if ( *sp == '\0' ) continue;
  473.       
  474.       sscanf( buf, "%f", &TrainSet[wx] );
  475.       wx++;
  476.     }
  477.     TSetL = wx;
  478.     fclose(fp);   
  479.     
  480.     if ( TSetL == 0 ) {
  481.       PutStr( "Nothing in data set, try again\n" );
  482.       continue;
  483.     }
  484.     
  485.     break;
  486.   }
  487.   
  488.   return( 0 );
  489. }
  490. /*   */
  491. /************************************************************************
  492.  *                                                                      *
  493.  *  UsrIO() - user handler for i/o                                      *
  494.  *                                                                      *
  495.  ************************************************************************
  496.  */
  497.  
  498. int UsrIO()     /* handle NWORKS requests */
  499. {
  500.   
  501.   char  *sp;    /* string pointer */
  502.   float  v;   /* work float */
  503.   int    wn;    /* work number */
  504.   int    wx;    /* work index */
  505.   float  act, prd, ten; /* actual / predicted difference */
  506.   char   buf[100];  /* work buffer */
  507. #if (SUN || VAXULT) && !SYSV
  508.   extern long  random();
  509. #define rand   random
  510. #define MAXRAND (0x7fffffffl)
  511. #else
  512.   extern int   rand();  /* random number generator */
  513. #define MAXRAND (0x7fff)
  514. #endif
  515.   FILE  *fp;
  516. #ifdef SUN
  517.   extern double fabs( );
  518.   extern double sqrt();
  519. #endif
  520.   
  521.   if ( InitFlag == 0 ) {
  522.     /* open any files which may be required at this point in the
  523.        code.
  524.        */
  525.     
  526.     /* open all windows at this time */
  527.     SetParms();
  528.     
  529.     ug_window( W0, 0, 80, 3, 80+W0_Wid, 3+W0_Ht );
  530.     
  531.     PlotSet( &EWB, W0, "Mean-Square Error", EX0,EY0,EX1,EY1,
  532.         0, 1, EHT / .005, 0.0, &EVals[0], &EVFlag[0], ENPts );
  533.     
  534. #if 1
  535.     PlotSet( &MWB, W0, (char *)null_ptr, EX0,EY0,EX1,EY1,
  536.         0, (int)(3.4*(EX1-EX0)/NTPTS), EHT / 2.1,  0.0, (float *)null_ptr, 
  537.         (char *)null_ptr, 0 );
  538. #else
  539. #ifdef SUN
  540.     PlotSet( &MWB, W0, (char *)null_ptr, EX0,EY0,EX1,EY1,
  541.         0, (int)(3.4*(EX1-EX0)/NTPTS), EHT / 2.1,  0.0, (float *)null_ptr, 
  542.         (char *)null_ptr, 0 );
  543. #else
  544.     PlotSet( &MWB, W0, (char *)null_ptr, EX0,EY0,EX1,EY1,
  545.         0, 3, EHT / 2.1,  0.0, (float *)null_ptr, (char *)null_ptr, 0 );
  546. #endif
  547. #endif
  548.     
  549.     InitFlag = 1;
  550.   }
  551.   
  552.   IORTNCDE = 0;       /* good return for data */
  553.   switch( IOREQCDE ) {
  554.     
  555.     /* ------ LEARNING ------ */
  556.     
  557.   case RQ_LSTART:       /* starting learn */
  558.     /* This tells the user that the program is about to start
  559.        learning.  It is called once for a LEARN ALL, LEARN ONE,
  560.        LEARN N, or LEARN START
  561.        */
  562.     
  563.     if ( TSetL <= 0 )  ReadTS( &buf[0] ); /* read data */
  564.     if ( IsTSOk() ) return(0);
  565.     
  566.     /* set up the window & tell the user what to do */
  567.     ug_winclr( 0 );       /* clear windows */
  568.     
  569.     ToTrain = TrainSz-1;
  570.     /* ask the user for the scale factor for errors */
  571.     PutStr( "What is the maximum expected error? " );
  572.     sp = GetStr();
  573.     
  574.     v = 0.0;
  575.     sscanf( sp, "%f", &v );
  576.     if ( v < 0 ) EXScale = -1.;
  577.     else if ( v < 0.0001 ) {
  578.       if ( EXScale < .0001 )  EXScale = EHT / 1.0;
  579.     } else {      EXScale = EHT / v;
  580.         }
  581.     
  582.     /* display the errors as they stand */
  583.     EWB.Scale = EXScale;
  584.     PlotSave( &EWB );
  585.     
  586.     DataCtr   = 0;
  587.     MSE   = 0.0;
  588.     Pass    = 0;
  589.     break;
  590.     
  591.   case RQ_LEARNIN:        /* read training input */
  592.     /* IODATA points to an empty array of IOCOUNT elements.  The
  593.        values placed in this array by the user will become the
  594.        inputs to the network for training purposes.
  595.        */
  596.     
  597.     if ( IsTSOk() ) return(0);
  598.     
  599.     if ( IOCOUNT > InputLen ) InputLen = IOCOUNT;
  600.     
  601.     /* pick next training input randomly */
  602. #if (SUN || VAXULT) && !SYSV
  603.     wn = rand() % (TSetL - IOCOUNT - 1);
  604. #else
  605.     wn = (((long)rand()) * (TSetL - IOCOUNT-1)) / MAXRAND;
  606. #endif
  607.     
  608.     for (wx = 0; wx < IOCOUNT; wx++, wn++)
  609.       IODATA[wx] = TrainSet[wn];
  610.     
  611.     /*desired response*/
  612.     LastDR = TrainSet[wn];
  613.     
  614.     break;
  615.     
  616.   case RQ_LEARNOUT:       /* read desired output */
  617.     /* IODATA points to an empty array of IOCOUNT values.  The
  618.        elements of the array will become the desired outputs for
  619.        training purposes.  These desired outputs correspond to
  620.        the most recent "RQ_LEARNIN" request.
  621.        */
  622.     
  623.   case RQ_LEARNRSLT:
  624.     /* IODATA points to an array of IOCOUNT values.  These are the
  625.        output of the network caused by the inputs from RQ_LEARNIN.
  626.        */
  627.     v = IODATA[0] - LastDR;     /* error */
  628.     MSE += (v * v);       /* mean square error */
  629.     
  630.     if ( --ToTrain <= 0 ) {
  631.       MSE = sqrt(MSE)/TrainSz;
  632.       Pass++;
  633.       sprintf( buf, "pass = %ld, MSE = %.3f\n", Pass, MSE );
  634.       PutStr( buf );
  635.       
  636.       PlotNext( &EWB, MSE, 0.0, 0, 1 );
  637.       MSE = 0.0;
  638.       ToTrain = TrainSz;
  639.     }
  640.     break;
  641.     
  642.     
  643.     /* ------ RECALL ------ */
  644.     
  645.   case RQ_RSTART:       /* starting recall */
  646.     /* This tells the user that the program is about to start
  647.        a recall.  It is called once for a REACLL ALL, RECALL ONE,
  648.        RECALL N, or RECALL START.
  649.        */
  650.     
  651.     if ( TSetL <= 0 )  ReadTS( &buf[0] ); /* read data */
  652.     if ( IsTSOk() ) return(0);
  653.     
  654.     DataCtr = 0;
  655.     maxe  = 0.0;
  656.     maxect  = 0;
  657.     maxe2 = 0.0;
  658.     maxe2ct = 0;
  659.     TotErr  = 0.0;
  660.     
  661.     ug_winclr( 0 );
  662.     
  663.     yold = 0;
  664.     xlag = 0;
  665.     HitRate = 0;
  666.     HitTen  = 0;
  667.     TotalCt = 0;
  668.     
  669.     break;
  670.     
  671.   case RQ_READ:       /* read test data */
  672.     /* IODATA points to an empty array of IOCOUNT values.  The
  673.        user must fill in these values.  The elements of the
  674.        array will become the "sum" of the inputs to the input
  675.        layer of processing elements.
  676.        */ 
  677.     
  678.     if ( IsTSOk() ) return(0);
  679.     
  680.     if ( IOCOUNT > InputLen ) InputLen = IOCOUNT;
  681.     
  682.     /* select the next string from the data set */
  683.     PrevTen = CurTen;
  684.     CurTen = 0.0;
  685.     for (wn = DataCtr, wx = 0; wx < IOCOUNT; wx++, wn++ ) {
  686.       CurTen  += TrainSet[wn];
  687.       IODATA[wx]   = TrainSet[wn];
  688.     }
  689.     
  690.     TenPred[wn] =
  691.       (1.0 * CurTen) / InputLen;  /* save moving average prediction */
  692.     
  693.     PrevWk = LastDR;    /* save previous week */
  694.     LastDR = TrainSet[wn];
  695.     break;
  696.     
  697.   case RQ_RCLTST:   /* read desired output during recall test */
  698.     /* IODATA points to an empty array of IOCOUNT values.  The
  699.        elements of the array will become the desired outputs for
  700.        recall purposes.  This request is only made during a
  701.        Execute Network/Recall Test.
  702.        */
  703.     
  704.     wx = 0;
  705.     IODATA[wx++] = LastDR;      /* set data */
  706.     
  707.     while( wx < IOCOUNT ) IODATA[wx++] = 0.0; /* no data for these */
  708.     break;
  709.     
  710.   case RQ_WRITE:        /* write out results */
  711.     /* IODATA points to an array of IOCOUNT "float" type values.
  712.        The values are the outputs of the top-most layer of the
  713.        network.
  714.        */
  715.     
  716.     NetPred[DataCtr+InputLen] = IODATA[0];  /* current prediction */
  717.     
  718.     if ( xlag == 0 ) {
  719.       xlag = InputLen;
  720.       MWB.XOff = xlag;
  721.     }
  722.     DataCtr++;
  723.     
  724.     /* see if it correctly predicted up/down trend */
  725.     if ( fabs(IODATA[0]) > .001 ) v = fabs((IODATA[0]-LastDR)/IODATA[0]);
  726.     else        v = 0.0;
  727.     if ( v > .10 ) {
  728.       if ( v > maxe2 )  maxe2 = v;
  729.       maxe2ct++;
  730.     } else {
  731.       if ( v > maxe ) maxe = v;
  732.       maxect++;
  733.     }
  734.     TotErr += v;
  735.     
  736.     if ( DataCtr > 1 ) {
  737.       act = LastDR    - PrevWk;
  738.       prd = IODATA[0] - PrevPrd;
  739.       ten = CurTen    - PrevTen;
  740.       
  741.       /* classify network hit rate */
  742.       if ( (fabs(act) < .002 && fabs(prd) < .002) ||
  743.       (act < 0.0 && prd < 0.0) || (act > 0.0 && prd > 0.0) )
  744.     HitRate++;
  745.       if ( (fabs(act) < .002 && fabs(ten) < .002) ||
  746.       (act < 0.0 && ten < 0.0) || (act > 0.0 && ten > 0.0) )
  747.     HitTen++;
  748.       TotalCt++;
  749.     }
  750.     PrevPrd = IODATA[0];
  751.     PrevWk  = LastDR;
  752.     
  753.     if(DataCtr >= (TSetL - InputLen-1)) {
  754.       IORTNCDE = -1;
  755.     }
  756.     break;
  757.     
  758.   case RQ_REND:
  759.     if ( TotalCt == 0 )
  760.       TotalCt = 1;
  761.     
  762.     MWB.XOff = 0;
  763.     PlotClear( &MWB );
  764.     PlotArray( &MWB, &TrainSet[0], (float *)null_ptr, TSetL, 0 );
  765.     MWB.XOff = InputLen;
  766.     PlotArray( &MWB, &NetPred[InputLen], &TrainSet[InputLen],
  767.           TSetL-InputLen-1, W0_Sep*1 );
  768.     PlotArray( &MWB, &TenPred[InputLen], &TrainSet[InputLen],
  769.           TSetL-InputLen-1, W0_Sep*2 );
  770.     
  771.     /* put up titles */
  772.     sprintf( buf, "%ld-Week Moving Average", (long) InputLen );
  773.     ug_puts( W0, 13, 0, MX_ALL+5, MY_1, "S&P 500", 0 );
  774.     ug_puts( W0, 13, 0, MX_ALL+5, MY_2, "Network Prediction", 0 );
  775.     ug_puts( W0, 13, 0, MX_ALL+5, MY_3, buf, 0 );
  776.     
  777.     DataCtr = 0;
  778.     sprintf( buf,
  779.         "Trends:  Net: %ld/%ld (%ld%%), Ave Err=%.3f%%; %ld-Week: %ld/%ld (%ld%%)",
  780.         (long)HitRate, (long)TotalCt,
  781.         (long) ((HitRate * 100 + TotalCt/2) / TotalCt),
  782.         TotErr / TotalCt * 100.,
  783.         (long) InputLen,
  784.         (long) HitTen,  (long) TotalCt,
  785.         (long) ((HitTen  * 100. + TotalCt/2) / TotalCt ));
  786.     
  787.     PutStr( buf );
  788.     
  789.     GetStr();
  790.     break;
  791.     
  792.     
  793.   case RQ_TERM:       /* terminate interface */
  794.     /* close any files which may be open.  Deallocate any memory
  795.        which was allocated.  (This is VERY VERY important.  If
  796.        allocated memory is NOT released, dos memory will become
  797.        fragmented and it will become necessary to reboot.
  798.        */
  799.     
  800.     PutStr( "bye bye\n" );
  801.     break;
  802.   }
  803.   
  804.   return;
  805. }
  806.