home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / misc / b186_1 / Source / c / iac < prev    next >
Text File  |  1987-09-27  |  10KB  |  392 lines

  1. /*
  2.  
  3.        This file is part of the PDP software package.
  4.          
  5.        Copyright 1987 by James L. McClelland and David E. Rumelhart.
  6.        
  7.        Please refer to licensing information in the file license.txt,
  8.        which is in the same directory with this source file and is
  9.        included here by reference.
  10. */
  11.  
  12.  
  13. /* file: iac.c
  14.  
  15.     Do the actual work for interactive activation and competition
  16.     networks.
  17.     
  18.     First implemented by JLM
  19.     
  20.     Date of last revision:  8-12-87/JLM.
  21.  
  22. */
  23.  
  24. #include "general.h"
  25. #include "iac.h"
  26. #include "variable.h"
  27. #include "command.h"
  28. #include "weights.h"
  29. #include "patterns.h"
  30.  
  31. char   *Prompt = "iac: ";
  32. char   *Default_step_string = "cycle";
  33. boolean System_Defined = FALSE;
  34.  
  35.  
  36. float        maxactiv = 1;
  37. float        minactiv = -.2;
  38.  
  39. float  *activation;
  40. float  *netinput;
  41. float  *extinput;
  42. float  *inhibition;
  43. float  *excitation;
  44.  
  45. float   estr = .1;
  46. float   alpha = .1;
  47. float    gamma = .1;
  48. float   decay = .1;
  49. float    rest = -.1;
  50. float    dtr = -.01;  /* decay times rest, for efficiency */
  51. float    omd = .9;    /* 1 - decay, for efficiency */
  52. int    epochno = 0; /* not used in iac */
  53. int    patno = 0;
  54. int     ncycles = 10;
  55. int     cycleno = 0;
  56. int    gb = 0; /* for grossberg mode */
  57.  
  58. /* first get the number of units, then malloc all the necessary
  59.    data structures.
  60. */
  61. define_system() {
  62.     int     i;
  63.  
  64.     activation = (float *) emalloc((unsigned)(sizeof(float) * nunits));
  65.     (void) install_var("activation",Vfloat,(int*)activation,nunits,0,SETSVMENU);
  66.     for (i = 0; i < nunits; i++)
  67.     activation[i] = 0.0;
  68.  
  69.     netinput = (float *) emalloc((unsigned)(sizeof(float) * nunits));
  70.     (void) install_var("netinput",Vfloat,(int*)netinput,nunits,0,SETSVMENU);
  71.     for (i = 0; i < nunits; i++)
  72.     netinput[i] = 0.0;
  73.  
  74.     excitation = (float *) emalloc((unsigned)(sizeof(float) * nunits));
  75.     (void) install_var("excitation",Vfloat,(int*)excitation,nunits,0,SETSVMENU);
  76.  
  77.     inhibition = (float *) emalloc((unsigned)(sizeof(float) * nunits));
  78.     (void) install_var("inhibition",Vfloat,(int*)inhibition,nunits,0,SETSVMENU);
  79.  
  80.     extinput = (float *) emalloc((unsigned)(sizeof(float) * nunits));
  81.     (void) install_var("extinput",Vfloat,(int*)extinput,nunits,0,SETSVMENU);
  82.     for (i = 0; i < nunits; i++)
  83.     excitation[i] = inhibition[i] = extinput[i] = 0.0;
  84.  
  85.     System_Defined = TRUE;
  86.     zarrays();
  87.  
  88.     return(TRUE);
  89. }
  90.  
  91. getinput() {
  92.     register int    j;
  93.     char   *str;
  94.  
  95.     if (!System_Defined)
  96.     if (!define_system())
  97.         return(BREAK);
  98.  
  99.     str = get_command("pattern: ");
  100.     if (str == NULL) return(CONTINUE);
  101.     for (j = 0; j < nunits; j++) {
  102.     if (str[j] == '1' || str[j] == '+')
  103.         extinput[j] = 1.;
  104.     else
  105.         if (str[j] == '-')
  106.         extinput[j] = -1.;
  107.     else
  108.         extinput[j] = 0.;
  109.     }
  110.     return(CONTINUE);
  111. }
  112.  
  113. zarrays() {
  114.     register int    i;
  115.  
  116.     cycleno = 0;
  117.  
  118.     if (!System_Defined)
  119.     if (!define_system())
  120.         return(BREAK);
  121.  
  122.     for (i = 0; i < nunits; i++) {
  123.     excitation[i] = inhibition[i] = netinput[i] = 0;
  124.     activation[i] = rest;
  125.     }
  126.     return(CONTINUE);
  127. }
  128.  
  129. cycle() {
  130.     int     iter;
  131.     char *str;
  132.  
  133.     if (!System_Defined)
  134.     if (!define_system())
  135.         return(BREAK);
  136.  
  137.     for (iter = 0; iter < ncycles; iter++) {
  138.     cycleno++;
  139.         getnet();
  140.     update();
  141.     if (step_size == CYCLE) {
  142.       update_display();
  143.       if (single_flag) {
  144.         if (contin_test() == BREAK) return(BREAK);
  145.       }
  146.     }
  147.     if (Interrupt) {
  148.         update_display();
  149.         Interrupt_flag = 0;
  150.         if (contin_test() == BREAK) return(BREAK);
  151.     }
  152.     }
  153.     if (step_size == NCYCLES) {
  154.         update_display();
  155.     }
  156.     return(CONTINUE);
  157. }
  158.  
  159. getnet() {
  160.     register int    i, j;
  161.     register int wi, *fwp, *nwp; 
  162.     float a,w;
  163.     
  164.     
  165.     for (i = 0; i < nunits; i++) {
  166.     excitation[i] = inhibition[i] = 0;
  167.     }
  168.     for (j = 0; j < nunits; j++) {
  169.     if ( (a = activation[j]) > 0.0) {
  170.       for (i = 0,fwp = first_weight_to,nwp = num_weights_to; 
  171.            i < nunits; i++) {
  172.        wi = j - *fwp++;
  173.        if ( (wi >= *nwp++) || (wi < 0) ) continue;
  174.        if ( (w = weight[i][wi]) > 0.0 ) {
  175.                 excitation[i] += a * w;
  176.        }
  177.        else if (w <0.0) {
  178.                 inhibition[i] += a * w;
  179.        }
  180.       }
  181.     }
  182.     }
  183.     for (i = 0; i < nunits; i++) {
  184.            excitation[i] *= alpha;
  185.     inhibition[i] *= gamma;
  186.     if (gb) {
  187.         if (extinput[i] > 0) excitation[i] += estr*extinput[i];
  188.         else if (extinput[i] < 0) inhibition[i] += estr*extinput[i];
  189.     }
  190.     else {
  191.             netinput[i] =  excitation[i] + inhibition[i] + 
  192.                         estr * extinput[i];
  193.     }
  194.     }
  195. }
  196.  
  197. update () {
  198.     register float *act, *ex, *in, *net, *end;
  199.     
  200.     if (gb) {
  201.       for (act=activation, ex=excitation, in=inhibition,end = act+nunits;
  202.            act < end; act++) {
  203.     *act = (*ex++) * (maxactiv - (*act)) + (*in++)*((*act)-minactiv) 
  204.         + omd*(*act) + dtr;
  205.     /* omd * a + dtr equals a - decay*(a - rest) */
  206.     if (*act > maxactiv) *act = maxactiv;
  207.     else if (*act < minactiv) *act = minactiv;
  208.       }
  209.     }
  210.     else {
  211.       for (act = activation, net = netinput, end = act + nunits;
  212.            act < end; act++, net++) {
  213.     if (*net > 0) {
  214.         *act = (*net) * (maxactiv - (*act)) + omd*(*act) + dtr;
  215.         if (*act > maxactiv) *act = maxactiv;
  216.     }
  217.     else {
  218.         *act = (*net) * ((*act) - minactiv) + omd*(*act) + dtr;
  219.         if (*act < minactiv) *act = minactiv;
  220.     }
  221.       }
  222.     }
  223. }
  224.  
  225. input() {
  226.     int     i;
  227.     char   *str,tstr[100];
  228.  
  229.     if (!System_Defined)
  230.     if (!define_system())
  231.         return(BREAK);
  232.     if (!nunames) {
  233.         return(put_error("Must provide unit names. "));
  234.     }
  235. again:
  236.     str = get_command("Do you want to reset all inputs?: (y or n)");
  237.     if (str == NULL) goto again;
  238.     if (str[0] == 'y') {
  239.         for (i = 0; i < nunits; i++)
  240.         extinput[i] = 0;
  241.     }
  242.     else if (str[0] != 'n') {
  243.         put_error ("Must enter y or n!");
  244.     goto again;
  245.     }
  246.  
  247. gcname: 
  248.     str = get_command("give unit name or number: ");
  249.     if (str == NULL || (strcmp(str,"end") == 0) ) {
  250.     update_display();
  251.     return(CONTINUE);
  252.     }
  253.     if (sscanf(str,"%d",&i) == 0) {
  254.         for (i = 0; i < nunames; i++) {
  255.         if (startsame(str, uname[i])) break;
  256.         }
  257.     }
  258.     if (i >= nunames) {
  259.     if (put_error("unrecognized name -- try again.") == BREAK) {
  260.         return(BREAK);
  261.     }
  262.     goto gcname;
  263.     }
  264. gcval: 
  265.     sprintf(tstr,"enter input strength of %s:  ",uname[i]);
  266.     str = get_command(tstr);
  267.     if (str == NULL) {
  268.         sprintf(err_string,"no strength specified of %s.",uname[i]);
  269.         if (put_error(err_string) == BREAK) {
  270.         return(BREAK);
  271.     }
  272.     goto gcname;
  273.     }
  274.     if (sscanf(str, "%f", &extinput[i]) != 1) {
  275.     if (put_error("unrecognized value.") == BREAK) {
  276.         return(BREAK);
  277.     }
  278.     goto gcval;
  279.     }
  280.     goto gcname;
  281. }
  282.  
  283. setinput() {
  284.     register int    i;
  285.     register float  *pp;
  286.  
  287.     for (i = 0, pp = ipattern[patno]; i < nunits; i++, pp++) {
  288.             extinput[i] = *pp;
  289.     }
  290.     strcpy(cpname,pname[patno]);
  291. }
  292.  
  293. test_pattern() {
  294.     char   *str;
  295.  
  296.     if (!System_Defined)
  297.         if (!define_system())
  298.             return(BREAK);
  299.  
  300.     if(ipattern[0] == NULL) {
  301.        return(put_error("No file of test patterns has been read in."));
  302.     }
  303. again:
  304.     str = get_command("Test which pattern? (name or number): ");
  305.     if(str == NULL) return(CONTINUE);
  306.     if ((patno = get_pattern_number(str)) < 0) {
  307.         return(put_error("Invalid pattern specification."));
  308.     }
  309.     setinput();
  310.     zarrays();
  311.     cycle();
  312.     return(CONTINUE);
  313.  
  314. }
  315.  
  316. reset_system() {
  317.     clear_display();
  318.     zarrays();
  319. /*    reset_display(); moving vector reset -- out of service */
  320.     update_display();
  321.     return(CONTINUE);
  322. }
  323.  
  324. constrain_weights() {
  325. }
  326.  
  327.  
  328. init_system() {
  329.     int get_unames(),test_pattern(),read_weights(),write_weights(),
  330.     change_decay(), change_rest();
  331.  
  332.     epsilon_menu = NOMENU;
  333.  
  334.     (void) install_command("cycle",cycle, BASEMENU, (int *)NULL);
  335.     (void) install_command("input", input, BASEMENU,(int *) NULL);
  336.     (void) install_command("test", test_pattern, BASEMENU,(int *) NULL);
  337.     (void) install_command("network", define_network, GETMENU,(int *) NULL);
  338.     (void) install_command("weights", read_weights, GETMENU,(int *) NULL);
  339.     (void) install_command("patterns", get_patterns, GETMENU,(int *) NULL);
  340.     (void) install_command("unames", get_unames, GETMENU,(int *) NULL);
  341.     (void) install_command("reset", reset_system, BASEMENU,(int *) NULL);
  342.     (void) install_command("weights", write_weights, SAVEMENU,(int *) NULL);
  343.     (void) install_var("gb",Int,(int *) & gb, 0, 0, SETMODEMENU);
  344.     (void) install_var("patno", Int,(int *) & patno, 0, 0, SETSVMENU);
  345.     init_patterns();
  346.     (void) install_var("cycleno", Int,(int *) & cycleno, 0, 0, SETSVMENU);
  347.     (void) install_var("ncycles", Int,(int *) & ncycles, 0, 0, SETPCMENU);
  348.     (void) install_var("nunits", Int,(int *) & nunits, 0, 0, SETCONFMENU);
  349.     (void) install_var("ninputs", Int,(int *) & ninputs, 0, 0, SETCONFMENU);
  350.     (void) install_var("estr", Float,(int *) & estr, 0, 0,
  351.                                    SETPARAMMENU);
  352.     (void) install_var("alpha", Float,(int *) & alpha, 0, 0, SETPARAMMENU);
  353.     (void) install_var("gamma", Float,(int *) & gamma, 0, 0, SETPARAMMENU);
  354.     (void) install_var("decay", Float,(int *) & decay, 0, 0, NOMENU);
  355.     (void) install_command("decay",change_decay, SETPARAMMENU, (int *) NULL);
  356.     (void) install_var("max",Float, (int *) & maxactiv, 0, 0, 
  357.                                    SETPARAMMENU);
  358.     (void) install_var("min",Float, (int *) & minactiv, 0, 0, 
  359.                             SETPARAMMENU);
  360.     (void) install_var("rest", Float,(int *) & rest, 0, 0, NOMENU);
  361.     (void) install_command("rest",change_rest, SETPARAMMENU, (int *) NULL);
  362.     
  363. }
  364.  
  365. change_rest() {
  366.     struct Variable *varp;
  367.  
  368.     if ((varp = lookup_var("rest")) != NULL) {
  369.     change_variable("rest",(int *) varp);
  370.     }
  371.     else {
  372.     return(put_error("rest is not defined"));
  373.     }
  374.     dtr = decay * rest;
  375.     return(CONTINUE);
  376. }
  377.  
  378. change_decay() {
  379.     struct Variable *varp;
  380.  
  381.     if ((varp = lookup_var("decay")) != NULL) {
  382.     change_variable("decay",(int *) varp);
  383.     }
  384.     else {
  385.     return(put_error("decay is not defined"));
  386.     }
  387.     dtr = decay * rest;
  388.     omd = 1 - decay;
  389.     return(CONTINUE);
  390. }
  391.  
  392.