home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / PROG / MISC / DATAREP.ZIP / ASSOC.PAS next >
Encoding:
Pascal/Delphi Source File  |  1990-02-22  |  11.9 KB  |  385 lines

  1. PROGRAM Assoc (Input, Output, Ffile, Gfile, Nfile);
  2.  
  3. {Copyright James Anderson, Department of Psychology, Brown University.}
  4. {This research was primarily supported by National Science            }
  5. {Foundation Grants BNS-82-14728 and BNS-85-18675 to James Anderson,   }
  6. {Department of Cognitive and Linguistic Sciences, Brown University,   }
  7. {Providence, RI 02912.                                                }
  8. {Please acknowledge this grant if you make use of these program       }
  9. {in published material.                                               }
  10.    
  11. CONST   Number_of_neurons  = 200;
  12.  
  13. TYPE    Vector   = ARRAY [1..Number_of_neurons ] OF REAL;
  14.  
  15.     String   = PACKED ARRAY [1..60] OF CHAR;
  16.  
  17.     Stimulus = RECORD
  18.            Name: String;
  19.            Val : Vector;
  20.            END;
  21.  
  22.     Synapse  = RECORD Strength: REAL;
  23.                           From: INTEGER;
  24.                           END;
  25.     
  26.     Neuron   = RECORD Activity: REAL;
  27.                           Synapses: ARRAY [1..Number_of_neurons ] OF Synapse;
  28.                           Noutput: REAL;
  29.                           Learningp: REAL;
  30.                           Upperlimit: REAL;
  31.                           Lowerlimit: REAL;
  32.                           END;
  33.                      
  34. VAR     Neurons      : ARRAY [1..Number_of_neurons ] OF Neuron;
  35.  
  36.     O, Froms, Outp,
  37.                 Gout : Vector;
  38.         Seed, 
  39.           Number_of_synapses, 
  40.           I, K, 
  41.           Nr_in_f_set, Nr_in_g_set, 
  42.           How_often, 
  43.           Nr_of_stimuli, 
  44.           Nr_to_learn : INTEGER;
  45.  
  46.     Ffile, Gfile  :FILE OF Stimulus;
  47.  
  48.         Use_nfile, 
  49.            Correction, 
  50.            Fully_connected: BOOLEAN;
  51.  
  52.     Nfile         : FILE OF Neuron;
  53.  
  54.     F_set, G_set  : ARRAY[0..100] OF Stimulus;
  55.  
  56. PROCEDURE Read_f_file;
  57.     VAR I: INTEGER;
  58.     BEGIN
  59.     WRITELN;
  60.     WRITELN ('The program is reading the FFILE.');
  61.     WRITELN ('The dimensionality of the system is', Number_of_neurons :4);
  62.     OPEN (Ffile, 'Ffile', OLD);
  63.     RESET (Ffile);
  64.     I:= 0;
  65.     WHILE NOT EOF (Ffile) DO
  66.         BEGIN
  67.         I:= I+1;
  68.         F_set[I]:= Ffile^;
  69.         GET (Ffile);
  70.         END;
  71.     Nr_in_f_set:= I;
  72.     WRITELN;
  73.         CLOSE (Ffile);
  74.     END;
  75.  
  76. {It is not necessary to have separate f and g sets in a strictly     }
  77. {autoassociative system, but in other applications, the f and g sets }
  78. {can be different.                                                   }
  79.  
  80. PROCEDURE Read_g_file;
  81.     VAR I: INTEGER;
  82.     BEGIN
  83.     WRITELN;
  84.     WRITELN ('The program is reading the GFILE.');
  85.     OPEN (Gfile, 'Gfile', OLD);
  86.     RESET (Gfile);
  87.     I:= 0;
  88.     WHILE NOT EOF (Gfile) DO
  89.         BEGIN
  90.         I:= I+1;
  91.         G_set [I]:= Gfile^;
  92.         GET (Gfile);
  93.         END;
  94.     Nr_in_g_set:= I;
  95.     WRITELN;
  96.     IF (Nr_in_g_set <> Nr_in_f_set) 
  97.            THEN WRITELN ('WARNING! Nr. of Fs does not equal nr of Gs.');
  98.     IF (Nr_in_g_set >= Nr_in_f_set) 
  99.            THEN Nr_of_stimuli:= Nr_in_f_set;
  100.     IF (Nr_in_g_set <  Nr_in_f_set) 
  101.            THEN Nr_of_stimuli:= Nr_in_g_set;
  102.         CLOSE (Gfile);
  103.     END;
  104.  
  105. PROCEDURE Write_f_and_g;
  106.         VAR I: INTEGER;
  107.         BEGIN
  108.         WRITELN;
  109.         WRITELN ('F and G stimuli used.');
  110.         FOR I:= 1 TO Nr_in_f_set DO
  111.            BEGIN
  112.            WRITELN;
  113.            WRITELN (' F[',I:2,'] : ',F_set [I].Name);
  114.            WRITELN (' G[',I:2,'] : ',G_set [I].Name);
  115.            END;
  116.         WRITELN;
  117.         END;
  118.  
  119. FUNCTION MTH$RANDOM (Seed: INTEGER): REAL; EXTERN;
  120.  
  121. FUNCTION Real_random: REAL;
  122.         BEGIN
  123.         Real_random:= MTH$RANDOM (Seed);
  124.         END;
  125.  
  126. FUNCTION Vector_length (Dimensionality: INTEGER; V: Vector): REAL;
  127.         VAR Sum_of_squares: REAL;
  128.         I: INTEGER;
  129.         BEGIN
  130.         Sum_of_squares:= 0;
  131.         FOR I:= 1 TO Dimensionality DO 
  132.              Sum_of_squares:= V[I] * V[I] + Sum_of_squares;
  133.         Vector_length:= SQRT (Sum_of_squares);
  134.         END;
  135.         
  136. FUNCTION Inner_product (Dimensionality: INTEGER; A,B: Vector): REAL;
  137.         VAR Sum_of_products: REAL;
  138.         I: INTEGER;
  139.         BEGIN
  140.         Sum_of_products := 0;
  141.         FOR I:= 1 TO Dimensionality DO
  142.                 Sum_of_products := Sum_of_products + A[I]*B[I];
  143.         Inner_product:= Sum_of_products;
  144.         END;
  145.  
  146. PROCEDURE Read_nfile;
  147.     VAR I, Nr_of_neurons: INTEGER; 
  148.     BEGIN
  149.     WRITELN;
  150.     WRITELN ('The program is reading the NFILE.');
  151.     WRITELN ('This is a file of TYPE NEURON.');
  152.     OPEN (Nfile, 'Nfile', OLD);
  153.     RESET (Nfile);
  154.     I:= 0;
  155.     WHILE NOT EOF (Nfile) DO
  156.         BEGIN
  157.         I:= I+1;
  158.         Neurons [I]:= Nfile^;
  159.         GET (Nfile);
  160.         END;
  161.     Nr_of_neurons:= I;
  162.     WRITELN ('NFILE contains ',Nr_of_neurons:4,' neurons.');
  163.     IF Nr_of_neurons <> Number_of_neurons  THEN 
  164.             WRITELN ('ERROR! Dimensionality does not agree with file size.');
  165.     WRITELN;
  166.         CLOSE (Nfile);
  167.     END;
  168.  
  169. PROCEDURE Write_nfile;
  170.     VAR I: INTEGER;
  171.     BEGIN
  172.     OPEN (Nfile, 'Nfile', NEW);
  173.     REWRITE (Nfile);
  174.     WRITELN;
  175.     WRITELN ('Writing to neuron output file.');
  176.     FOR I:= 1 TO Number_of_neurons  DO
  177.         BEGIN
  178.         Nfile^:= Neurons [I];
  179.         PUT (Nfile);
  180.         END;
  181.     CLOSE (Nfile);
  182.     END;
  183.  
  184. FUNCTION Check_froms (NR:INTEGER; Neu:Neuron):BOOLEAN;
  185.         VAR I: INTEGER;
  186.         Found: BOOLEAN;
  187.         BEGIN
  188.         Found:= FALSE;
  189.         FOR I:= 1 TO Number_of_synapses DO
  190.              IF Neu.Synapses [I].From = NR THEN Found:= TRUE;
  191.         Check_froms:= Found;
  192.         END;
  193.  
  194. PROCEDURE Setup;
  195.     VAR I,J, Try: INTEGER;
  196.         Try_again: BOOLEAN;
  197.     BEGIN
  198.         FOR I:=1 TO Number_of_neurons  DO
  199.                 BEGIN
  200.                 FOR J:= 1 TO Number_of_neurons  DO
  201.                         BEGIN
  202.                         Neurons [I].Synapses [J].Strength:= 0;
  203.             Neurons [I].Synapses [J].From:=0;
  204.             END;
  205.         IF Fully_connected THEN FOR J:= 1 TO Number_of_synapses DO
  206.                Neurons [I].Synapses [J].From := 
  207.                       1 + (I+J) MOD Number_of_synapses;
  208.  
  209.                 IF NOT Fully_connected THEN
  210.                    BEGIN
  211.                    FOR J:= 1 TO Number_of_synapses DO
  212.                         BEGIN
  213.                         Try_again := TRUE;
  214.                         WHILE Try_again DO 
  215.                                 BEGIN
  216.                                 Try:= TRUNC(Real_random * Number_of_neurons+1);
  217.                                 Try_again:= Check_froms (Try,Neurons [I]);
  218.                                 END;
  219.                         Neurons [I].Synapses [J].From := Try;
  220.                         END;
  221.                    END;
  222.                 Neurons [I].Activity   := 0;
  223.         Neurons [I].Learningp  := 1;
  224.                 Neurons [I].Noutput    := 0;
  225.         Neurons [I].Upperlimit := 0;
  226.                 Neurons [I].Lowerlimit := 0;
  227.                 END;
  228.         WRITELN ('Setup completed.');
  229.     END;
  230.  
  231. PROCEDURE Initialize;
  232.         VAR I,J,K: INTEGER;
  233.         CH: CHAR;
  234.         BEGIN
  235.         WRITELN ('ASSOCIATIATE program.  March 19, 1989.' );
  236.         WRITELN;
  237.         Read_f_file;    Read_g_file; Write_f_and_g;
  238.  
  239.         WRITE ('Seed for RN generator           : ');   READLN (Seed);
  240.         WRITELN;
  241.     WRITE ('Number of associations to learn : ');    READLN (Nr_to_learn);
  242.         WRITELN;
  243.         WRITE ('Use CORRECTION procedure? Y or N: ');   READLN (CH);
  244.         WRITELN;
  245.         IF (CH='Y') OR (CH='y') THEN Correction:= TRUE ELSE Correction:= FALSE;
  246.     WRITE ('Use old Nfile as start? Y or N  : ');    READLN (CH);        
  247.         WRITELN;
  248.  
  249.         {Disk files of type NEU always have Number_of_neurons synapses.}
  250.  
  251.         IF ((CH='Y') OR (CH='y')) THEN
  252.            Use_nfile:= TRUE ELSE Use_nfile:= FALSE; 
  253.  
  254.         IF Use_nfile THEN
  255.            BEGIN
  256.            Number_of_synapses:= Number_of_neurons;
  257.            Read_nfile;
  258.            END; 
  259.  
  260.         WRITE ('Number of synapses              : ');
  261.         READLN (Number_of_synapses);
  262.         WRITELN;
  263.         IF ( (Number_of_synapses < Number_of_neurons) AND (NOT Use_nfile) )  
  264.            THEN Fully_connected:= FALSE;
  265.  
  266.         {Full connectivity simply fills in the connections in order.}
  267.         IF Number_of_synapses = Number_of_neurons THEN Fully_connected:= TRUE;
  268.  
  269.         {Connectivities over 80% may take a long time to connect the
  270.          matrix because connections may not be repeated.}
  271.         IF (Number_of_synapses > (4*Number_of_neurons  DIV 5))
  272.            THEN WRITELN ('Warning!! May take a long time to set up matrix!');
  273.  
  274.     IF NOT Use_nfile THEN Setup;
  275.         END;
  276.  
  277. {This procedure changes the synaptic weights.}
  278.                         
  279. PROCEDURE Memorize (F, G, O: Vector);
  280.         VAR I,J: INTEGER;
  281.     Gterm, LP: REAL;
  282.         BEGIN
  283.  
  284.         {Guess at learning parameter, LP.             }
  285.         {Increase for speed.  If LP is too large,     }
  286.         {the system can become unstable.              }
  287.         LP:=0.5/ SQR(Vector_length (Number_of_neurons ,F)); 
  288.  
  289.         FOR I:= 1 TO Number_of_neurons  DO 
  290.                 BEGIN
  291.                 {If Widrow-Hoff correction technique, then the error  }
  292.                 {is learned, otherwise, the associated output vector  }
  293.                 {is learned.                                          }
  294.  
  295.                 IF Correction THEN Gterm:= (G[I]-O[I])   {Error term. }
  296.                               ELSE Gterm:= G[I];         {Association.}
  297.  
  298.                 FOR J:= 1 TO Number_of_synapses DO
  299.                     Neurons [I].Synapses [J].Strength :=
  300.                        LP * Gterm * F[Neurons [I].Synapses [J].From] +
  301.                                       Neurons [I].Synapses [J].Strength;
  302.                 END;
  303.         END;
  304.  
  305. {Matrix-vector product.}
  306.  
  307. PROCEDURE Calculate (VAR F,O: Vector);
  308.         VAR I,J: INTEGER;
  309.         Sum: REAL;
  310.         BEGIN
  311.         FOR I:= 1 TO Number_of_neurons  DO
  312.             BEGIN
  313.             Sum:= 0;
  314.             FOR J:= 1 TO Number_of_synapses DO
  315.               Sum := Sum + 
  316.                Neurons[I].Synapses[J].Strength*F[Neurons[I].Synapses [J].From];
  317.             O[I]:= Sum;
  318.             END;
  319.         END;
  320.  
  321. PROCEDURE Write_cosine (G, O: Vector);
  322.     VAR LO, LG, Cos_between_OG: REAL;
  323.         BEGIN
  324.     LG:= Vector_length (Number_of_neurons, G);    
  325.         LO:= Vector_length (Number_of_neurons, O);
  326.     Cos_between_OG:= Inner_product (Number_of_neurons, O, G)/ (LO*LG);
  327.     WRITE (Cos_between_OG:9);
  328.     END;
  329.  
  330. BEGIN {Main program}
  331. Initialize;
  332. WRITELN;
  333.  
  334. {If there are a small number of stimuli, then each is presented exactly}
  335. {once, in sequence. Effectively, this can be used to generate an       }
  336. {outer product matrix if the correction (Widrow-Hoff) procedure is     }
  337. {turned off.                                                           }
  338.  
  339. IF Nr_to_learn <= Nr_of_stimuli THEN 
  340.        WRITELN ('Each stimulus presented exactly once.');
  341. IF Nr_to_learn < Nr_of_stimuli THEN
  342.        WRITELN ('Some stimuli not learned. Nr. to Learn = ',
  343.                  Nr_to_learn:5, '   Nr. of Stimuli = ',Nr_of_stimuli:5);
  344.  
  345. {Does weight updating.}
  346.  
  347. FOR K:=1 TO Nr_to_learn DO
  348.     BEGIN
  349.     IF Nr_to_learn <= Nr_of_stimuli 
  350.            THEN I:= K                                       {Learn in sequence.}
  351.            ELSE I:= TRUNC (Real_Random*Nr_of_stimuli + 1);  {Learn random pair.}
  352.     Calculate (F_set [I].Val, Gout);
  353.     Memorize ( F_set [I].Val, G_set [I].Val, Gout);
  354.  
  355.         {Displays every 10th pair so progress can be monitored. }
  356.         How_often:= 10;  
  357.         IF (K MOD How_often = 0) THEN 
  358.            BEGIN 
  359.            WRITE (K:5,'  Nr: ',I:4); 
  360.            WRITE ('   Cosine: ');
  361.            Write_cosine (G_set [I].Val, Gout);
  362.            WRITELN;
  363.            END;
  364.         END;
  365.  
  366. WRITELN;
  367. WRITELN ('Accuracy of recall of input set.');
  368. WRITELN;
  369. {Gives recall accuracy for entire stimulus set for checking purposes.}
  370. {Computes cosine between stored and retrieved association and also   }
  371. {length of retrieved vector.                                         }
  372.  
  373. FOR I:= 1 TO Nr_of_stimuli DO
  374.     BEGIN
  375.     Calculate (F_set [I].Val, Outp);
  376.     WRITELN;
  377.     WRITELN (I:3,'  Name: ', G_set [I].Name);
  378.     WRITE   ('  Cosine: ');
  379.         Write_cosine (G_set [I].Val, Outp);
  380.     WRITELN ('  Length: ', Vector_length (Number_of_neurons, Outp):9 );
  381.     END;
  382.  
  383. Write_nfile;  {Write connections to output.}
  384. END. {main program}
  385.