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

  1. /* 14:00 22-Jun-88 (sundayio.c)  Sunday Afternoon Advisor I/O package */
  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 <math.h>
  16.  
  17. #define UIO_SERVER             1
  18. #define SERVER_EMULATOR_FILE   1
  19. #define SKIP_COMPAT_DATA       1
  20. #include "userutl.h"
  21. #include "uio_strc.h"
  22. #include "uio_tran.h"
  23. #include "uio_reqs.pro"
  24. #include "uio_cmds.pro"
  25.  
  26. #ifdef MAC
  27. #include "macuio.redef"
  28. #endif
  29.  
  30. #define arraysize(array)  (sizeof(array) / sizeof(array[0]))
  31.  
  32. /************************************************************************
  33.  *                  *
  34.  *  SundayIO - Sunday Afternoon Advisor I/O       *
  35.  *                  *
  36.  ************************************************************************
  37.  
  38.    This I/O module is designed to provide a convenient interface to
  39.    the Sunday Afternoon Advisor.
  40.  
  41.    LEARNING:  During learning, it uses a file (sunday.dat) which trains
  42.    the network on specific input patterns (the amount of work at the
  43.    office  and my feelings toward my wife) and output class (0..4).
  44.  
  45.    The format of the input file is:
  46.  
  47.   Output_Class  Amount_of_work  Feelings_toward_Wife
  48.  
  49.    Look at "sunday.dat" to see how this is done.  The data for this
  50.    example is explained in the text.
  51.  
  52. RECALL:  In recall mode, you will be prompted for two inputs:  Work and
  53.    Feelings.  The code will translate the first character of each
  54.    input to a numeric value, or you can enter a numeric value.  The
  55.    translations performed are:
  56.  
  57.   Work:   N = None (0.0)
  58.       S = Some (0.5)
  59.       L = Lots (1.0)
  60.  
  61.   Feelings: D = Dog_house (0.0)
  62.       G = Good (0.5)
  63.       R = Romantic (1.0)
  64.  
  65.    So, to enter Some Work, Feeling Romantic respond with:
  66.  
  67.   Some Romantic
  68.  
  69.    or:  0.5 1.0
  70.  
  71.  */
  72.  
  73. /*   */
  74. /************************************************************************
  75.  *                  *
  76.  *  ReadSample() - get sample data          *
  77.  *                  *
  78.  ************************************************************************
  79.  */
  80.  
  81. int _stack = 8192;         /* leave lots of stack space */
  82.  
  83. struct SAMPLE
  84. {
  85.   long  DesiredOut;      /* output class */
  86.   float Input[4];        /* input value */
  87. };
  88.  
  89. #define MAXSAM 128         /* maximum number of samples */
  90.  
  91. long          PassPerUpdate    = 0;       /* # of passes between updates */
  92. int           NSamples         = 0;       /* # of samples read in */
  93. struct SAMPLE TestData[MAXSAM] = {0};     /* test data read from user */
  94. char          SampX[MAXSAM]    = {0};     /* sample index buffer */
  95. int           SX               = MAXSAM;  /* index into sample array */
  96.  
  97.  
  98. /*   */
  99. NINT ReadSample(buf)
  100. char *buf;
  101. {
  102.   char *sp;         /* input string */
  103.   int  wx;          /* work index */
  104.     FILE *fp;         /* input file pointer */
  105.  
  106. TryAgain:
  107.   NSamples = 0;     /* kill sample array */
  108.   for(;;)
  109.   {
  110.     PutStr("What is the sample input file: ");
  111.     sp = GetStr();
  112.     while(*sp && *sp <= ' ')
  113.       sp++;
  114.     if (*sp == '\0')  /* no input file */
  115.       return(UIO_ERROR);
  116.  
  117.     if ((fp = fopen( sp, "r")) == (FILE *)0)
  118.     {
  119.       PutStr( sp );
  120.       PutStr( " -- will not open\n" );
  121.   }
  122.   else
  123.     break;
  124.   }
  125.  
  126.   /* read in the sample data */
  127.   for(wx = 0; wx < MAXSAM;)
  128.   {
  129.     /* get a new line */
  130.     if (fgets( buf, 100, fp ) == 0)
  131.       break;
  132.  
  133.   /* kill trailing comments */
  134.   for( sp = &buf[0]; *sp; sp++ )
  135.   {
  136.     if (*sp == '!' || *sp == '\n' || *sp == '\r')
  137.     {
  138.       *sp = '\0';
  139.       break;
  140.     }
  141.   }
  142.  
  143.   /* skip leading white space */
  144.   for(sp = &buf[0]; *sp != 0; sp++ )
  145.     if (*sp > ' ')
  146.       break;
  147.     if (*sp == 0 )
  148.       continue;     /* ignore blank lines */
  149.  
  150.     /* convert the data on the line to float and save them */
  151.     sscanf( sp, "%ld %f %f %f %f",
  152.       &TestData[wx].DesiredOut,
  153.       &TestData[wx].Input[0],
  154.       &TestData[wx].Input[1],
  155.       &TestData[wx].Input[2],
  156.       &TestData[wx].Input[3]);
  157.  
  158.     wx++;
  159.   }
  160.   fclose(fp);
  161.  
  162.   NSamples = wx;
  163.  
  164. /*   */
  165.   if (NSamples == 0)
  166.   {
  167.     PutStr("Nothing in the INPUT file, re-enter\n");
  168.     goto TryAgain;
  169.   }
  170.  
  171.   sprintf(buf, "Samples=%ld, How many passes per update: ", (long)NSamples);
  172.   PutStr(buf);
  173.  
  174.   sp = GetStr();
  175.   PassPerUpdate = 10l;
  176.   sscanf(sp, "%ld", &PassPerUpdate);
  177.  
  178.   return(UIO_OK);
  179. }
  180.  
  181. /*   */
  182. float         MSE   = 0;          /* mean square error */
  183. long          Pass  = 0;          /* pass number */
  184. int           Item  = 0;          /* item in the current pass */
  185. struct SAMPLE *SamP = 0;          /* pointer to last sample */
  186. char          buf[102];           /* work buffer */
  187.  
  188. /*****************************************************************************/
  189. /*                                                                           */
  190. /* Functions neccessary for handling the User I/O package itself.            */
  191. /*                                                                           */
  192. /*****************************************************************************/
  193.  
  194. /* FUNCTION */
  195. NINT UIO_Init(file)
  196. TEXT *file;
  197. {
  198.   NINT ret_val = UIO_OK;
  199.  
  200.   /* USER TO PLACE CODE HERE */
  201.  
  202.   return(ret_val);
  203. }
  204.  
  205. /* FUNCTION */
  206. NINT UIO_Term(process)
  207. NINT  process;
  208. {
  209.   NINT ret_val = UIO_OK;
  210.  
  211.   /* USER TO PLACE CODE HERE */
  212.   /* close any files which may be open.  Deallocate any memory
  213.      which was allocated.  (This is VERY VERY important.  If
  214.      allocated memory is NOT released, dos memory will become
  215.      fragmented and it will become necessary to reboot.
  216.   */
  217.  
  218.   PutStr("bye bye\n");
  219.  
  220.   return(ret_val);
  221. }
  222.  
  223. /* FUNCTION */
  224. NINT UIO_Attention()
  225. {
  226.   NINT ret_val = UIO_OK;
  227.  
  228.   /* USER TO PLACE CODE HERE */
  229.  
  230.   SX   = MAXSAM;
  231.   Item = 0;
  232.   Pass = 0;
  233.   PassPerUpdate = 10;
  234.   NSamples = 0;
  235.  
  236.   return(ret_val);
  237. }
  238. /*   */
  239.  
  240.  
  241. /*****************************************************************************/
  242. /*                                                                           */
  243. /*  Functions necessary for handling a learning session.                     */
  244. /*                                                                           */
  245. /*****************************************************************************/
  246.  
  247. /* FUNCTION */
  248. NINT UIO_Learn_Start()
  249. {
  250.   NINT ret_val = UIO_OK;
  251.  
  252.   /* USER TO PLACE CODE HERE */
  253.  
  254.   if (NSamples == 0)
  255.     ret_val = ReadSample(&buf[0]);    /* read samples */
  256.  
  257.   return(ret_val);
  258. }
  259.  
  260. /* FUNCTION */
  261. NINT UIO_Learn_Input(LayN, nPEs, Datap)
  262. NINT  LayN;
  263. NINT  nPEs;
  264. SREAL *Datap;
  265. {
  266.   NINT ret_val = UIO_OK;
  267.  
  268.   /* USER TO PLACE CODE HERE */
  269.  
  270.   int wx;           /* work index */
  271.   int r;            /* work random number */
  272.  
  273.   /* Datap points to an empty array of nPEs elements.  The
  274.      values placed in this array by the user will become the
  275.      inputs to the network for training purposes.
  276.   */
  277.  
  278.   if (NSamples <= 0)
  279.   {
  280.     return(UIO_ERROR);
  281.   }
  282.  
  283. /*   */
  284.   if (SX >= NSamples)
  285.   {
  286.     for(SX = 0; SX < NSamples; SX++)
  287.     {
  288.       RandAgain:
  289.       r = rand() % NSamples;        /* try a random number*/
  290.       for( wx = 0; wx < SX; wx++ )
  291.       {
  292.         if (SampX[wx] == r) goto RandAgain;
  293.       }
  294.       SampX[SX] = r;
  295.     }
  296.     SX = 0;
  297.   }
  298.   r = SampX[SX++];
  299.  
  300.   SamP = &TestData[r];
  301.   for(wx = 0; wx < nPEs; wx++)
  302.     Datap[wx] = (wx < 4)? SamP->Input[wx]: 0.0;
  303.  
  304.   Item++;         /* count items in a pass */
  305.   return(ret_val);
  306. }
  307.  
  308. /* FUNCTION */
  309. NINT UIO_Learn_Output(LayN, nPEs, Datap)
  310. NINT  LayN;
  311. NINT  nPEs;
  312. SREAL *Datap;
  313. {
  314.   NINT ret_val = UIO_OK;
  315.  
  316.   /* USER TO PLACE CODE HERE */
  317.  
  318.   int wx;           /* work index */
  319.  
  320.   /* Datap points to an empty array of nPEs values.  The
  321.      elements of the array will become the desired outputs for
  322.      training purposes.  These desired outputs correspond to
  323.      the most recent "RQ_LEARNIN" request.
  324.   */
  325.  
  326.   if (NSamples <= 0)
  327.   {
  328.     return(UIO_ERROR);
  329.   }
  330.  
  331.   for(wx = 0; wx < nPEs; wx++)
  332.     Datap[wx] = (wx==SamP->DesiredOut? 1.0:0.0);
  333.  
  334.   return(ret_val);
  335. }
  336.  
  337. /* FUNCTION */
  338. NINT UIO_Learn_Result(LayN, nPEs, Datap)
  339. NINT  LayN;
  340. NINT  nPEs;
  341. SREAL *Datap;
  342. {
  343.   NINT ret_val = UIO_OK;
  344.  
  345.   int   wx;         /* work index */
  346.   float v;          /* real value */
  347.  
  348.   /* USER TO PLACE CODE HERE */
  349.   for(wx = 0; wx < nPEs; wx++)
  350.   {
  351.     v = Datap[wx] - ((wx==SamP->DesiredOut) ? 1.0 : 0.0);
  352.     MSE += v*v;
  353.   }
  354.  
  355.   if (Item >= NSamples)
  356.   {
  357.     Item = 0;
  358.     Pass++;
  359.     if (PassPerUpdate == 0)
  360.       PassPerUpdate = 1;
  361.  
  362.     if ((Pass % PassPerUpdate) != 0)
  363.       return(ret_val);
  364.  
  365.     MSE = sqrt(MSE) / (NSamples * PassPerUpdate);
  366.     sprintf(buf, "Pass = %4ld, MSE = %.4f\n", Pass, MSE);
  367.     PutStr(buf);
  368.  
  369.     ret_val = (MSE < .00001) ?
  370.       UIO_ERROR : UIO_UPDATE;  /* end / update display */
  371.     MSE = 0.0;
  372.   }
  373.  
  374.   return(ret_val);
  375. }
  376.  
  377. /* FUNCTION */
  378. NINT UIO_Learn_End()
  379. {
  380.   NINT ret_val = UIO_OK;
  381.  
  382.   /* USER TO PLACE CODE HERE */
  383.  
  384.   return(ret_val);
  385. }
  386. /* */
  387.  
  388.  
  389. /*****************************************************************************/
  390. /*                                                                           */
  391. /*  Functions necessary for handling a recall or testing session.            */
  392. /*                                                                           */
  393. /*****************************************************************************/
  394.  
  395. /* FUNCTION */
  396. NINT UIO_Recall_Start()
  397. {
  398.   NINT ret_val = UIO_OK;
  399.  
  400.   /* USER TO PLACE CODE HERE */
  401.  
  402.   return(ret_val);
  403. }
  404.  
  405. /* FUNCTION */
  406. NINT UIO_Read(LayN, nPEs, Datap)
  407. NINT  LayN;
  408. NINT  nPEs;
  409. SREAL *Datap;
  410. {
  411.   NINT ret_val = UIO_OK;
  412.   int   wx;         /* work index */
  413.   float WorkIn[4];  /* work input */
  414.   char  *sp;        /* string pointer */
  415.   int   r;          /* work random number */
  416.   float v;          /* real value */
  417.  
  418.   /* USER TO PLACE CODE HERE */
  419.   /* Datap points to an empty array of nPEs values.  The
  420.      user must fill in these values.  The elements of the
  421.      array will become the "sum" of the inputs to the input
  422.      layer of processing elements.
  423.   */ 
  424.  
  425.   for( wx = 0; wx < 4; wx++ )
  426.     WorkIn[wx] = 0.0;
  427.  
  428.   PutStr("Enter 'Work Feelings' (E=End): ");      /* prompt user */
  429.   sp = GetStr();                                  /* read input */
  430.   while(*sp == ' ')                               /* skip spaces */
  431.     sp++;
  432.  
  433.   if (*sp == 'e' || *sp == 'E')
  434.   {
  435.       return(UIO_ERROR);                      /* end of input */
  436.   }
  437.  
  438.  
  439.   r = *sp;
  440.   v = 0.0;
  441.   if      ( r == 'n' || r == 'N' )  v = 0.0;  /* none */
  442.   else if ( r == 's' || r == 'S' )  v = 0.5;  /* some */
  443.   else if ( r == 'l' || r == 'L' )  v = 1.0;  /* lots */
  444.   else {
  445.       /* assume it is a number an convert it */
  446.       sscanf( sp, "%f", &v );
  447.   }
  448.   Datap[0] = v;
  449.  
  450.   while( (r = *sp) != '\0' ) {    /* skip number or text */
  451.       if ( r == ' ' ) break;
  452.       sp++;
  453.   }
  454.   while( (r = *sp) != '\0' ) {    /* skip following space */
  455.       if ( r != ' ' ) break;
  456.       sp++;
  457.   }
  458.  
  459.   v = 0.0;
  460.   if  ( r == 'd' || r == 'D' )  v = 0.0;  /* dog_house */
  461.   else if ( r == 'g' || r == 'G' )  v = 0.5;  /* good */
  462.   else if ( r == 'r' || r == 'R' )  v = 1.0;  /* romantic */
  463.   else {
  464.       /* assume it is a number an convert it */
  465.       sscanf( sp, "%f", &v );
  466.   }
  467.   if ( nPEs > 1 ) Datap[1] = v;
  468.  
  469.   return(ret_val);
  470. }
  471. /*   */
  472.  
  473. /* FUNCTION */
  474. NINT UIO_Write(LayN, nPEs, Datap)
  475. NINT  LayN;
  476. NINT  nPEs;
  477. SREAL *Datap;
  478. {
  479.   NINT ret_val = UIO_OK;
  480.  
  481.   /* USER TO PLACE CODE HERE */
  482.   /* Datap points to an array of nPEs "float" type values.
  483.      The values are the outputs of the top-most layer of the
  484.      network.
  485.   */
  486. #ifdef WRITEIT
  487.   PutStr( "Result =" );
  488.   for( wx = 0; wx < nPEs; wx++ ) {
  489.       sprintf( buf, " %.4f", Datap[wx] );
  490.       PutStr(  buf );
  491.   }
  492.   PutStr( "\n" );
  493. #endif
  494.  
  495.   ret_val = UIO_UPDATE;           /* update display */
  496.  
  497.   return(ret_val);
  498. }
  499.  
  500. /* FUNCTION */
  501. NINT UIO_Write_Step(LayN, nPEs, Datap)
  502. NINT  LayN;
  503. NINT  nPEs;
  504. SREAL *Datap;
  505. {
  506.   NINT ret_val = UIO_OK;
  507.  
  508.   /* USER TO PLACE CODE HERE */
  509.  
  510.   return(ret_val);
  511. }
  512. /*   */
  513.  
  514. /* FUNCTION */
  515. NINT UIO_Recall_Test(LayN, nPEs, Datap)
  516. NINT  LayN;
  517. NINT  nPEs;
  518. SREAL *Datap;
  519. {
  520.   NINT ret_val = UIO_OK;
  521.  
  522.   /* USER TO PLACE CODE HERE */
  523.   /* Datap points to an empty array of nPEs values.  The
  524.      elements of the array will become the desired outputs for
  525.      recall purposes.  This request is only made during a
  526.      Execute Network/Recall Test.
  527.   */
  528.  
  529.   return(ret_val);
  530. }
  531.  
  532. /* FUNCTION */
  533. NINT UIO_Recall_End()
  534. {
  535.   NINT ret_val = UIO_OK;
  536.  
  537.   /* USER TO PLACE CODE HERE */
  538.  
  539.   return(ret_val);
  540. }
  541.  
  542.  
  543. /* */
  544. /*****************************************************************************/
  545. /*                                                                           */
  546. /*  Other miscelaneous functions.                                            */
  547. /*                                                                           */
  548. /*****************************************************************************/
  549.  
  550. /* FUNCTION */
  551. NINT UIO_Instrument(Instrument_id, nDataElems, DataElemp)
  552. NINT  Instrument_id;
  553. NINT  nDataElems;
  554. SREAL *DataElemp;
  555. {
  556.   NINT ret_val = UIO_OK;
  557.  
  558.   /* USER TO PLACE CODE HERE */
  559.  
  560.   return(ret_val);
  561. }
  562.  
  563. /* FUNCTION */
  564. NINT UIO_Rewind()
  565. {
  566.   NINT ret_val = UIO_OK;
  567.  
  568.   /* USER TO PLACE CODE HERE */
  569.  
  570.   return(ret_val);
  571. }
  572.  
  573.  
  574. /* FUNCTION */
  575. NINT UIO_Explain(LayN, nPEs, Datap)
  576. NINT  LayN;
  577. NINT  nPEs;
  578. SREAL *Datap;
  579. {
  580.   NINT ret_val = UIO_OK;
  581.  
  582.   /* USER TO PLACE CODE HERE */
  583.  
  584.   return(ret_val);
  585. }
  586.  
  587.