home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / aijournl / 1988_11 / outstar.c < prev    next >
Text File  |  1988-11-07  |  25KB  |  804 lines

  1.  /***********************************************************
  2.     OUTSTAR Simulator
  3.      
  4.         ⌐Maureen Caudill
  5.         Adaptics
  6.         16776 Bernardo Center Drive
  7.         Suite 110 B
  8.         San Diego, CA  92128
  9.         (617) 451-3752
  10.          July, 1988
  11.  
  12.     Written in Lightspeed C (v. 2.15) on Macintosh
  13.     Version 1.0
  14.     
  15.     This outstar learns to reproduce a specified pattern
  16.     on a grid of border neurodes.  The pattern to be learned
  17.     is read from an external text file called "pattern"
  18.     
  19. ---------------------------------------------------------------------------------
  20.         OPERATION OF THIS SIMULATOR
  21.         
  22.         Read AI Expert Article, November, 1988 for discussion of Grossberg
  23.         Learning, Activation Equations and Instar/Outstar.
  24.         
  25.         This simulator models a biological system.  The outstar neurode stimulates
  26.         each of a 7x10 grid of neurodes at the same time as an external pattern
  27.         stimulates the grid.  The initial weight connections between the outstar
  28.         and the grid neurodes are randomly set between -0.5 and +0.5.  The initial
  29.         activity in the grid is also randomly set to activity between 0.0 and 0.5.
  30.         
  31.         To run the simulator, you need to have a pattern file which contains the
  32.         pattern you want the grid to learn to reproduce when stimulated by the outstar.
  33.         The program begins by initializing the weights, activations, reading the data
  34.         file and so on.  Then the values of the Grossberg learning/activation constants
  35.         are checked, with default values assumed initially. I suggest that you leave 
  36.         these values as they are until you are sure you understand the learning laws.
  37.         
  38.         The menu gives you four choices.
  39.             1.  Train the network for some specified number of time units.
  40.             2.  Allow the activation in the grid to decay for some number of time units
  41.             3.  Test the network by having the outstar stimulate the grid for some number
  42.                 of time units.
  43.            -1.  Reset the network (and possibly change the network constants) to either
  44.                    quit or start over.
  45.          When asked to enter the number of time units (for 1 or 2 or 3), remember that
  46.          a negative number will only display the grid activation after that number of time
  47.          units has passed, while a positive number displays the grid activation after each
  48.          time unit.
  49.          
  50.          The proper operation of the simulator is as follows:
  51.              train the network for some number of time periods.  Remember that the
  52.                  transmission constant t0 determines how many time units must pass before
  53.                  the grid even sees the outstar's stimulus (the external pattern is applied
  54.                  immediately).  Thus, if the t0 constant is 3, you should do NOTHING in less 
  55.                  than 4 time units (3 to travel, and 1 to have an effect on the grid).
  56.              allow the grid activation levels to decay to zero.  No weight changes occur
  57.                  during this time (why?), so you are effectively just "clearing the slate".
  58.              test the network (again for t0+1 time units).  If the performance is inadequate,
  59.                  train again for additional time periods, then allow decay, then test.
  60.     Have fun!
  61.     -----------------------------------------------------------------------------------------    
  62.     
  63. ---------------------------------------------------------------------------------
  64.                             STRUCTURE OF THIS FILE
  65.     
  66.     include files
  67.     constant definitions
  68.     general global storage
  69.     Grossberg activation/learning constant storage (global)
  70.     
  71.     ╤╤ Major functions ╤╤
  72.     initialize()                ;; initialize network operations
  73.     train()                        ;; train the grid for a specified time
  74.     decay()                        ;; allow grid activation to decay a specified time
  75.     test()                        ;; test the grid for a specified time
  76.     ╤╤ Utility functions ╤╤
  77.     compute_activation()        ;; compute current activation for a grid neurode
  78.     change_weight()                ;; modify weight of a grid neurode
  79.     read_pattern()                 ;; read pattern from data file
  80.     parseline()                  ;; parse one line of data from file 
  81.     randomize_wts()                ;; randomize weights on grid neurodes
  82.     randomize_activity()        ;; randomize activity of grid neurodes
  83.     set_constants()                ;; set Grossberg equation constants
  84.       show_constants()            ;; show current values of learning/activity constants
  85.     show_wts()                    ;; print current weights on grid neurodes
  86.     displaygrid()                ;; print the current grid activation
  87.     print_menu()                ;; print menu of operator choices (train, test, decay, quit)
  88.     ╤╤ Main control function ╤╤
  89.     main()                        ;; main control function
  90. ------------------------------------------------------------------------------------
  91. *****************************************************************************************/    
  92.     
  93. #include <math.h>
  94. #include <stdio.h>
  95.  
  96. #define        ROWSIZE        7
  97. #define        COLSIZE        10
  98. #define        STRINGSIZE    80
  99. #define        QUIT        -1
  100. #define        STIMMASK    1
  101. #define        ACTIVATION  1
  102. #define        LEARNING    2
  103. #define        DISPLAYON    1
  104. #define        DISPLAYOFF    2
  105. #define        STIM        1
  106. #define        NOSTIM        0
  107.  
  108. /************* General Global Storage ***************************************************/
  109. double        gridwts[ROWSIZE][COLSIZE];     /*     this stores only the weights from the
  110.                                                single outstar neurode to the grid of rim
  111.                                                neurodes. */
  112. int            pattern[ROWSIZE][COLSIZE];  /*    this contains the pattern to be impressed
  113.                                             on the grid of rim neurodes */
  114. double        activity[ROWSIZE][COLSIZE]; /*    this contains the current activation levels
  115.                                             of each grid neurode */               
  116. int            curtime;                    /*     current time (in integral units)  */
  117. double        outstar;                    /*  activation level of outstar */
  118. char        *inpath = "pattern";        /*  file containing pattern to be learned */
  119. unsigned int    outstar_save;            /*    saves history of outstar's output */
  120.  
  121. /*****************************************************************************************/
  122.  
  123. /************* Grossberg Activation Constants (set by user or default values) ************/
  124. double        A  =  0.9;        /* activation decay constant */
  125. double        T  =  0.0;        /* threshold */
  126. int            t0 =    1;        /* transmission time between neurodes */
  127. double        F  =  0.01;        /* forgetting constant for long term memory */
  128. double        G  =  0.2;        /* learning constant for Hebbian learning term */
  129.  
  130. /*************************************************************
  131.     initialize()
  132.         initializes the system by:
  133.             1.  reading in the pattern file
  134.             2.    randomizing the weights
  135.             3.    setting the current time to 0
  136.             4.    establishing the activation/learning constants
  137. **************************************************************/
  138. initialize()
  139. {
  140.     read_pattern();                /* read in training pattern from file */
  141.     randomize_wts();            /* randomize weights to grid neurodes from outstar */
  142.     randomize_activity();        /* randomize activity of grid neurodes */
  143.     show_wts();                    /* display resulting grid neurode weights */
  144.     curtime = 0;                /* reset current time to 0 */
  145.     displaygrid(curtime);        /* display the initial activity of the grid */
  146.     set_constants();            /* set the constants to user specified values */
  147.     return;
  148. }
  149. /*************************************************************
  150.     train(duration)
  151.         trains the outstar and grid for "duration" timeunits. 
  152.         weights are modified during this training period
  153.         After each synchronous update of the grid, the
  154.         activations are displayed.
  155.         
  156.         If training time is negative, only the grid status after
  157.         all "duration" time units will be displayed.
  158.         
  159. **************************************************************/
  160. train()
  161. {
  162.     int        duration, displayflag;
  163.     int        stoptime;
  164.     int        i,j;
  165.     int        stim_grid, stim_outstar;
  166.  
  167.     /* ask how many time units to train */
  168.     printf("\n How many time units do you want the network to train?  ");
  169.     printf("\n (Integer value < 32767, negative suppresses all but final display)  ");
  170.     scanf("%d", &duration);
  171.  
  172.     displayflag = DISPLAYON;
  173.  
  174.     if (duration<0)
  175.     {
  176.         duration = -duration;
  177.         displayflag = DISPLAYOFF;
  178.     }
  179.     stoptime = curtime+duration;
  180.     for ( ; curtime<stoptime; curtime++)
  181.     {
  182.         stim_grid = STIM;
  183.         stim_outstar = STIM;
  184.         printf("\n Current time = %d",curtime);
  185.         save_outstim(stim_outstar);
  186.         for (i=0; i<ROWSIZE; i++)
  187.         {
  188.             for (j=0; j<COLSIZE; j++)
  189.             {
  190.                 compute_activation(i,j,stim_grid, stim_outstar);
  191.                 change_weight(i,j,stim_outstar);
  192.             }
  193.         }
  194.         if(displayflag == DISPLAYON)
  195.             displaygrid();
  196.     }
  197.     curtime--;          /* decrement to avoid using an extra time unit */
  198.  
  199.     /* when complete, if have not been updating display, do a final display of status */
  200.     if (displayflag == DISPLAYOFF)
  201.         displaygrid();
  202.         
  203.     return;
  204. }
  205.  
  206. /*************************************************************
  207.     decay(duration)
  208.         allows grid activation to decay for "duration" timeunits. 
  209.         no weights are modified during this period, since
  210.         stimulations from the outstar are 0.0
  211.         After each synchronous update of the grid, the
  212.         activations are displayed.
  213.         
  214.         If decay time is negative, only the grid status after
  215.         all "duration" time units will be displayed.
  216.         
  217. **************************************************************/
  218. decay()
  219. {
  220.     int        duration;
  221.     int        displayflag;
  222.     int        stoptime;
  223.     int        i,j;
  224.     int        stim_grid, stim_outstar;
  225.  
  226.     /* ask how many time units to decay */
  227.     printf("\n How many time units do you want the network to decay?  ");
  228.     printf("\n (Integer value < 32767, negative suppresses all but final display)  ");
  229.     scanf("%d", &duration);
  230.         
  231.     displayflag = DISPLAYON;
  232.     if (duration<0)
  233.     {
  234.         duration = -duration;
  235.         displayflag = DISPLAYOFF;
  236.     }
  237.  
  238.     stim_grid = NOSTIM;            /* during decay, no external stimulation of grid */
  239.     stim_outstar = NOSTIM;        /* during decay, the outstar does not stimulate grid */
  240.  
  241.     stoptime = curtime+duration;
  242.     for ( ; curtime<stoptime; curtime++)
  243.     {
  244.         printf("\n Current time = %d",curtime);
  245.         save_outstim(stim_outstar);
  246.         for (i=0; i<ROWSIZE; i++)
  247.         {
  248.             for (j=0; j<COLSIZE; j++)
  249.             {
  250.                 compute_activation(i,j,stim_grid, stim_outstar);
  251.             }
  252.         }
  253.         if(displayflag == DISPLAYON)
  254.             displaygrid();
  255.     }
  256.     curtime--;
  257.     /* when complete, if have not been updating display, do a final display of status */
  258.     if (displayflag == DISPLAYOFF)
  259.         displaygrid();
  260.         
  261.     return;
  262. }
  263.  
  264. /*************************************************************
  265.     test(duration)
  266.         tests the outstar and grid for "duration" timeunits. 
  267.         weights are not modified during this training period
  268.         After each synchronous update of the grid, the
  269.         activations are displayed.
  270.         
  271.         If testing time is negative, only the grid status after
  272.         all "duration" time units will be displayed.
  273.         
  274. **************************************************************/
  275. test()
  276. {
  277.     int        duration, displayflag;
  278.     int        stoptime;
  279.     int        i,j;
  280.     int        stim_grid, stim_outstar;
  281.         
  282.     /* ask how many time units to test */
  283.     printf("\n How many time units do you want the network to test?  ");
  284.     printf("\n (Integer value < 32767, negative suppresses all but final display)  ");
  285.     scanf("%d", &duration);
  286.  
  287.     displayflag = DISPLAYON;
  288.     if (duration<0)
  289.     {
  290.         duration = -duration;
  291.         displayflag = DISPLAYOFF;
  292.     }
  293.     
  294.     stim_grid = NOSTIM;        /* no external stimulation of grid during testing */
  295.     stim_outstar = STIM;    /* outstar does stimulate grid during testing */
  296.  
  297.     stoptime = curtime+duration;
  298.     for ( ; curtime<stoptime; curtime++)
  299.     {
  300.         printf("\n Current time = %d",curtime);
  301.         save_outstim(stim_outstar);
  302.         for (i=0; i<ROWSIZE; i++)
  303.         {
  304.             for (j=0; j<COLSIZE; j++)
  305.             {
  306.                 compute_activation(i,j,stim_grid, stim_outstar);
  307.             }
  308.         }
  309.         if(displayflag == DISPLAYON)
  310.             displaygrid();
  311.     }
  312.     curtime-- ;         /* decrement to avoid using an extra time unit */
  313.  
  314.     /* when complete, if have not been updating display, do a final display of status */
  315.     if (displayflag == DISPLAYOFF)
  316.         displaygrid();
  317.         
  318.     return;
  319. }
  320. /****************************************************************************
  321.     save_outstim(stimout)
  322.         Parameter stimout either has the value STIM (1) or NOSTIM (0).
  323.         save_outstim keeps a 16-time-unit historical record of
  324.         the outputs of the outstar by modifying the global unsigned
  325.         integer "outstar_save".
  326.         Each time unit the outstar is stimulating the grid is represented
  327.         by a "1" in outstar_save; if there is no stimulus, outstar_save has
  328.         a "0".  The 0th bit has the most recent record, the 15th bit has
  329.         the oldest record.
  330. *****************************************************************************/
  331. save_outstim(stimout)
  332. int        stimout;
  333. {
  334.     outstar_save = outstar_save << 1;        /* left shift one bit.  A zero fills
  335.                                                the lowest order bit, and the oldest
  336.                                                (highest order bit) is lost         */
  337.     outstar_save += stimout;                /* add current stimulus value 
  338.                                                 (0 if no stim, 1 if stim)           */
  339.     return;
  340.     
  341. /**************************************************************
  342.     compute_activation(row,col,grid_on,out_on)
  343.         compute the current activation for the specified
  344.         grid neurode
  345.         Parameter "grid_on" is a flag to tell whether or not
  346.         the external stimulus is impressing the pattern on
  347.         the grid.  
  348.         Parameter "out_on" is a flag indicating whether the
  349.         outstar is currently stimulating the grid.
  350.         
  351.         Note that differential equation is calculated as an
  352.         incremental difference equation.
  353. ***************************************************************/
  354. compute_activation(row,col,grid_on,out_on)
  355. int        row,col,grid_on,out_on;
  356. {
  357.     double            change;
  358.     unsigned int    status;
  359.     int                outstim;    /* effective outstar stimulation at current time */
  360.     
  361.     change = -A*activity[row][col] ; /* no matter what, activity will tend to try to decay */
  362.     if (grid_on == STIM)             /* if there is external stimulus, it will counter decay */
  363.         change += pattern[row][col];
  364.     if (out_on == STIM)                 /* if there is outstar stimulus... */
  365.     {
  366.         status = outstar_save;                /* Be sure not to change the global version */
  367.         status = status >> t0;                /* right shift by t0 time units to allow for
  368.                                                transmission time from outstar           */
  369.         outstim = status & STIMMASK;
  370.         change += gridwts[row][col]*outstim - T;
  371.     }
  372.     activity[row][col] += change;            /* new activity = old plus incremental change */
  373.     return;
  374. }
  375.  
  376. /**************************************************************************************
  377.     change_weight(row,col,out_on)
  378.         modify the weight of the specified grid neurode synapse
  379.         Parameter "out_on" is a flag indicating whether or not
  380.         the outstar is currently stimulating the grid.
  381.  
  382.         Note that differential equation is calculated as an
  383.         incremental difference equation.
  384.  
  385. ***************************************************************************************/
  386. change_weight(row,col,out_on)
  387. int        row,col, out_on;
  388. {
  389.     double            change;        /* the incremental change to this weight */
  390.     unsigned int    status;        /* local copy of global outstar output history */
  391.     int                outstim;    /* effective stimulus from outstar at this time */
  392.     
  393.     change = -F * activity[row][col];
  394.     if (out_on == STIM)
  395.     {
  396.         status = outstar_save;                /* Be sure not to change the global version */
  397.         status = status >> t0;                /* right shift by t0 time units to allow for
  398.                                                transmission time from outstar           */
  399.         outstim = status & STIMMASK;
  400.         change += G * activity[row][col] * (outstim - T);
  401.     }
  402.     gridwts[row][col] += change;
  403.     return;
  404. }
  405.  
  406. /*******************************************************************
  407.     read_pattern()
  408.         Read in the input data file and store the patterns in
  409.         in_pats and out_pats.
  410.         
  411.         The format for the data file is as follows:
  412.         line#   data expected
  413.         -----   -----------------------------
  414.         1        In-X-size,in-y-size
  415.         2        1st X row of 1st pattern
  416.         3..        following rows of 1st pattern
  417.         etc.
  418.         
  419.         Each row of data is separated by commas or spaces.
  420.         The data is expected to be ascii text corresponding to
  421.         either a +1 or a 0.  
  422.         
  423.         Sample input for a pattern file (The comments to the
  424.         right may NOT be in the file unless more sophisticated
  425.         parsing of the input is done.):
  426.         
  427.         5,7                        input is 5x7 grid
  428.         0,1,1,1,0                  beginning of pattern for "O"
  429.         1,0,0,0,1
  430.         1,0,0,0,1
  431.         1,0,0,0,1
  432.         1,0,0,0,1
  433.         1,0,0,0,0
  434.         0,1,1,1,0
  435.         
  436.         Clearly, this simple scheme can be expanded or enhanced
  437.         any way you like.
  438.         
  439.         Returns -1 if any file error occurred, otherwise 0.
  440. ********************************************************************/
  441. read_pattern()
  442. {
  443.     FILE    *infile;
  444.     
  445.     int        xinsize,yinsize;
  446.     int        rownum, numcols,x;
  447.     int        value, vals_read, status;
  448.     char    instring[STRINGSIZE];
  449.     
  450.     printf("\n Opening and retrieving data from file.");
  451.     
  452.     infile = fopen(inpath, "r");
  453.     if (infile == NULL)
  454.     {
  455.         printf("\n error in opening file!");
  456.         return -1 ;
  457.     }
  458.     vals_read =fscanf(infile,"%d,%d",&xinsize,&yinsize);
  459.     if (vals_read != 2)
  460.     {
  461.         printf("\n Should read 2 items in line one; did read %d",vals_read);
  462.         return -1;
  463.     }
  464.     if ((xinsize != ROWSIZE) || (yinsize != COLSIZE))
  465.     {
  466.         printf("\n\n ERROR:  Pattern file is invalid!");
  467.         printf("\n Pattern is a %d by %d grid instead of %d by %d",
  468.             xinsize, yinsize, ROWSIZE, COLSIZE);
  469.         return -1;
  470.     }
  471.     numcols = ROWSIZE;
  472.     for (rownum = 0; rownum<COLSIZE; rownum++)
  473.     {
  474.         status = fscanf(infile,"%s",&instring);
  475.         if (status == -1)
  476.         {
  477.             printf("\n  ERROR:  Insufficient data in file!");
  478.             return -1;
  479.         }
  480.         value = parseline(instring,numcols,rownum);
  481.         if (value == -1)
  482.             return -1;
  483.     }
  484.     printf("\n Closing the input file now. ");
  485.     fclose(infile);
  486.     return 0;
  487. }
  488.  
  489. /*******************************************************************
  490.     parseline(string,numele,row)
  491.         parse line of text to derive elements from pattern string.
  492.         Parameters
  493.          "string" is a pointer to string to be parsed.
  494.          "numele" specifies number of elements contained in "string"
  495.          "row" is pointer to correct row of "pattern" for elements.
  496.         Elements in the string must be either "0", "1", <space>, ","
  497.          0,1 puts appropriate values in pattern array
  498.          "<space>", or "," is ignored
  499.          
  500.          Notice that this is an extremely primitive parsing routine.
  501.          This can (and should) be improved or modified as desired.
  502.          
  503.         Return:
  504.          -1 if error, 0 else.
  505. ********************************************************************/
  506. parseline(string,numele,ygrid)
  507. char    string[];
  508. int        numele,ygrid;
  509. {
  510.     int        value;
  511.     int        charnum, ele;
  512.     char    ch;
  513.     
  514.     charnum = 0;
  515.     value = 0;
  516.     ele = 0;
  517.     while ((ele < numele) && (value == 0))
  518.     {
  519.         if (charnum == STRINGSIZE) /* made it to the end without filling all element entries */
  520.             value = -1;
  521.         else
  522.         {    /*This routine does not care if digits are separated or not.
  523.               each instance of a 0 or 1 will be taken as an element entry in
  524.               the pattern.  */
  525.               
  526.             ch = string[charnum];
  527.             switch (ch)
  528.             {
  529.             case '0' :  /* each "0" will be treated as a grid entry */
  530.                         pattern[ele][ygrid] = 0;
  531.                         ele++;
  532.                         break;
  533.             case '1' :  /* each "1" will be treated as a grid entry */
  534.                         pattern[ele][ygrid] = 1;
  535.                         ele++;
  536.                         break;
  537.             default     :  /* all other characters are ignored. */
  538.                         break;
  539.             }
  540.             charnum++;
  541.         }
  542.     }
  543.     return value;
  544. }
  545.  
  546. /*******************************************************************
  547.     randomize_wts()
  548.         Intialize the weights in the grid neurodes to
  549.         random values between -0.25..+0.25
  550. ********************************************************************/
  551. randomize_wts()
  552. {
  553.     int            i,j;
  554.     double        value;
  555.     
  556.     printf("\n Please enter a random number seed (1..32767):  ");
  557.     scanf("%d", &i);
  558.     srand(i);  
  559.  
  560.     for(i=0; i<ROWSIZE; i++)
  561.     {
  562.         for (j = 0; j<COLSIZE; j++)
  563.         {
  564.             value = (rand() / 32767.0 ) - 0.5;
  565.             gridwts[i][j] = value/2;
  566.         }
  567.     }
  568.     return;
  569. }
  570. /*******************************************************************
  571.     randomize_activity()
  572.         Intialize the activity in the grid neurodes to
  573.         random values between 0.0..0.5
  574. ********************************************************************/
  575. randomize_activity()
  576. {
  577.     int            i,j;
  578.     double        value;
  579.     
  580.     for(i=0; i<ROWSIZE; i++)
  581.     {
  582.         for (j = 0; j<COLSIZE; j++)
  583.         {
  584.             value = ( rand() / 32767.0 );
  585.             activity[i][j] = value/2.0;
  586.         }
  587.     }
  588.     return;
  589. }
  590.  
  591. /*******************************************************************
  592.     set_constants()
  593.         displays current (default) values for learning/activation
  594.         constants and requests user changes.  
  595. ********************************************************************/
  596. set_constants()
  597. {
  598.     int        ans;
  599.     float    value;
  600.     
  601.     show_constants(ACTIVATION);
  602.     scanf("%d",&ans);
  603.     while (ans != 0)
  604.     {
  605.         printf("\n    New value for A?  ");
  606.         scanf("%f",&value);            
  607.         A = (double) value;
  608.         printf("\n    New value for T?  ");
  609.         scanf("%f",&value);
  610.         T = (double) value;
  611.         printf("\n    New value for t0?  ");
  612.         scanf("%d",&t0);
  613.         show_constants(ACTIVATION);
  614.         scanf("%d",&ans);
  615.     }
  616.     show_constants(LEARNING);
  617.     scanf("%d",&ans);
  618.     while (ans != 0)
  619.     {
  620.         printf("\n    New value for F?  ");
  621.         scanf("%f",&value);
  622.         F = (double) value;
  623.         printf("\n    New value for G?  ");
  624.         scanf("%f",&value);
  625.         G = (double) value;
  626.         show_constants(LEARNING);
  627.         scanf("%d",&ans);
  628.     }
  629.     return;
  630. }
  631. /*********************************************************************
  632.     show_constants (which)
  633.         displays either activation or learning constants for
  634.         user approval or modification
  635.         Paramter "which" determines which set will be displayed
  636. **********************************************************************/
  637. show_constants(which)
  638. int        which;
  639. {
  640.     if (which == ACTIVATION) 
  641.     {
  642.         printf("\n The current values for the Grossberg activation constants are:");
  643.         printf("\n   Activation Decay Time constant (A):  %6.3f",A);
  644.         printf("\n   Activity Threshold (T):              %6.3f",T);
  645.         printf("\n   Transmission time to grid (t0):      %d",t0);
  646.     }
  647.     if (which == LEARNING)
  648.     {
  649.         printf("\n The current values for the Grossberg learning constants are:");
  650.         printf("\n   Learning Decay 'Forgetting' constant (F):  %6.3f",F);
  651.         printf("\n   Learning Gain constant (G):                %6.3f",G);
  652.     }    
  653.     printf("\n\n Do you wish to change any of these constants? (0 = no) ");
  654.     return;
  655. }
  656.  
  657. /*******************************************************************
  658.     show_wts()
  659.         print out the weights for the grid neurodes on the screen
  660. ********************************************************************/
  661. show_wts()
  662. {
  663.     int        row,col;
  664.     
  665.     printf("\n  The current weights for the grid neurodes are:\n");
  666.     for (col = 0; col < COLSIZE; col++)
  667.     {
  668.         printf ("\n");
  669.         for (row = 0; row < ROWSIZE; row++)
  670.         {
  671.             printf(" %6.3f ",gridwts[row][col]);
  672.         }
  673.     }
  674.     printf("\n\n");
  675.     return;
  676. }
  677.  
  678. /**************************************************************
  679.     displaygrid()
  680.         prints (text-only for portability) the current activity
  681.         of the grid neurodes.  Also displays the current time,
  682.         and the desired pattern.
  683. ***************************************************************/
  684. displaygrid()
  685. {
  686.     int        i,j;
  687.     double    value;
  688.     
  689.     printf("\n  Current pattern and activity at time %d:",curtime);
  690.     printf("\n Scale (0.0 to 1.0):  '  .  _  o  O  Ñ' \n");
  691.     printf("\n Grid activity is:");
  692.     printf("                   ");
  693.     printf("  Desired pattern is:");
  694.     for (j=0; j<COLSIZE; j++)
  695.     {
  696.         printf("\n     ");
  697.         for (i=0; i<ROWSIZE; i++)
  698.         {
  699.             value = activity[i][j];
  700.             if (value < 0.17)
  701.                 printf("   ");
  702.             if ((value >= 0.17) && (value < 0.35))
  703.                 printf(" . ");
  704.             if ((value >= 0.35) && (value < 0.50))
  705.                 printf(" _ ");
  706.             if ((value >= 0.50) && (value < 0.67))
  707.                 printf(" o ");
  708.             if ((value >= 0.67) && (value < 0.83))
  709.                 printf(" O ");
  710.             if (value >= 0.83)
  711.                 printf(" Ñ ");
  712.         }
  713.         printf("                   ");
  714.         for (i=0; i<ROWSIZE; i++)
  715.         {
  716.             switch(pattern[i][j])
  717.             {
  718.             case 0:        printf("   ");
  719.                         break;
  720.             case 1:        printf(" Ñ ");
  721.                         break;
  722.             default:    break;
  723.             }
  724.         }
  725.     }
  726.     printf("\n");
  727.     return;
  728. }
  729.  
  730. /***************************************************************
  731.     print_menu()
  732.         prints out menu of operations for user choice
  733. ****************************************************************/
  734. print_menu()
  735. {
  736.     printf("\n\n\n     Please select an operation:");
  737.     printf("\n\n          1.  Train the network for a period of time.");
  738.     printf("\n              (Both external and outstar stimulate grid)");
  739.     printf("\n\n          2.  Allow the network to decay for a period of time.");
  740.     printf("\n              (Neither external or outstar stimulates grid)");
  741.     printf("\n\n          3.  Test the network for a period of time.");
  742.     printf("\n              (Only outstar stimulates grid)");
  743.     printf("\n\n         -1.  Train the network for a period of time.");
  744.     return;
  745. }
  746.  
  747. /***************************************************************
  748.     main()
  749.         main program
  750. ****************************************************************/
  751. main()
  752. {
  753.     int        yesno;
  754.     int        done, donetraining;
  755.     int        traintime;
  756.     int        choice;
  757.     
  758.     done = 0; donetraining = 0;
  759.     while (done == 0)
  760.     {
  761.         initialize();
  762.         choice = 0;
  763.         /* display the desired grid pattern on the screen */
  764.         print_menu();
  765.         printf("\n\n  Please enter your choice:  ");
  766.         scanf("%d",&choice);
  767.         printf("\n Your selection was %d",choice);
  768.         while (choice != QUIT)
  769.         {
  770.             switch (choice)
  771.             {
  772.             case 1:    
  773.                         train();
  774.                         break;
  775.             case 2:        
  776.                         decay();
  777.                         break;
  778.             case 3:        
  779.                         test();
  780.                         break;
  781.             default:
  782.                 {
  783.                 choice = QUIT;
  784.                 break;
  785.                 }
  786.             }    
  787.             print_menu();
  788.             printf("\n\n  Please enter your choice:  ");
  789.             scanf("%d",&choice);
  790.             printf("\n Your selection was %d",choice);
  791.         }
  792.         printf("\n\n Training session terminated at user request...");
  793.         
  794.         /* want to start over (allows modification of constants)? */
  795.         printf("\n\n Would you like to reset the network and begin again (no = 0)?  ");
  796.         scanf("%d",&yesno);
  797.         if (yesno < 1)
  798.             done = 2;
  799.     }
  800.     printf("\n\n Program complete.");
  801.     /* stop */
  802.     return;
  803. }