home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / misc / b186_1 / Source / c / weights < prev   
Text File  |  1994-02-15  |  22KB  |  835 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: weights.c
  14.  
  15.     read in network descriptions, and set up constraints.
  16.     
  17.     First version implemented by Elliot Jaffe.
  18.     
  19.     Date of last revision: 8-12-87/JLM.
  20. */
  21.  
  22. /*LINTLIBRARY*/
  23.  
  24. /* the following is the form for network description files.
  25.  
  26. definitions:
  27. nunits <int>
  28. ninputs <int>
  29. noutputs <int>
  30. maxconstraints <int>
  31. constraints:
  32. <char> <float> or <char> [random positive negative linked]
  33. ...
  34. end
  35. network:
  36. <strings of . and chars as defined in definitions:>
  37. end
  38. biases:
  39. <a single line of . and chars as biases for units>
  40. end
  41. sigmas:
  42. <a single line of .'s and chars specifying sigmas -- harmony theory only>
  43. end
  44. <EOF>
  45. */
  46.  
  47.  
  48. #include "general.h"
  49. #include "command.h"
  50. #include "weights.h"
  51. #include "variable.h"
  52.  
  53. float **weight = NULL;
  54. char   **wchar;            /* pointers to vectors of chars
  55.                        that are used in resetting weights*/
  56. float  *bias = NULL;
  57. char   *bchar;                /* like wchar */
  58. float **epsilon;
  59. float  *bepsilon = NULL;    /* thresh epsilon array */
  60. float  **wed = NULL;
  61. float  *bed = NULL;
  62. float  *sigma = NULL;        /* strength parameter for knowledge atoms */
  63.  
  64. struct constants    constants[26];
  65.  
  66. float **positive_constraints;
  67. float **negative_constraints;
  68.  /* Array of struct constraint, for keeping links together */
  69. struct constraint  *constraints = NULL;
  70.  
  71. float   lrate = 0.5;
  72.  
  73. float   wrange = 1;
  74.  
  75. int     nunits = 0;
  76. int     ninputs = 0;
  77. int     noutputs = 0;
  78. int    maxpos = MAXCONSTRAINTS;
  79. int    maxneg = MAXCONSTRAINTS;
  80. int     nlinks = 0;
  81. static  nposconstr = 0;
  82. static  nnegconstr = 0;
  83. int     epsilon_menu = SETWTMENU;
  84. char    net_descr_name[BUFSIZ];
  85.  
  86. int bp;    /* TRUE if program is bp */
  87.  
  88. # define ENLARGE_POS -1
  89. # define ENLARGE_NEG -2
  90.  
  91. define_bp_network() {
  92.     bp = 1;
  93.     define_net();
  94. }
  95.  
  96. define_network() {
  97.     bp = 0;
  98.     define_net();
  99. }
  100.  
  101. define_net() {
  102.     char   *sp;
  103.     char    string[BUFSIZ];
  104.     FILE * sv_instream;
  105.     struct Variable *lookup_var ();
  106.     int     i;
  107.     boolean defined_weights = FALSE;
  108.  
  109.     sv_instream = in_stream;
  110.     sp = get_command("filename for network description: ");
  111.     if ( sp == NULL) return(CONTINUE);
  112.     strcpy(net_descr_name,sp);
  113.  
  114.     if ((in_stream = fopen(sp, "r")) == NULL) {
  115.     in_stream = sv_instream;
  116.     return(put_error("Can't open network file."));
  117.     }
  118.  
  119.     nlinks = 0;
  120.  
  121.     for (i = 0; i < 26; i++) {
  122.     constants[i].random = FALSE;
  123.     constants[i].positive = FALSE;
  124.     constants[i].negative = FALSE;
  125.     constants[i].link = FALSE;
  126.     constants[i].value = 0.0;
  127.     }
  128.  
  129.     constants['r' - 'a'].random = TRUE;
  130.     constants['p' - 'a'].random = TRUE;
  131.     constants['p' - 'a'].positive = TRUE;
  132.     constants['n' - 'a'].random = TRUE;
  133.     constants['n' - 'a'].negative = TRUE;
  134.  
  135.     while (fscanf(in_stream, "%s", string) != EOF) {
  136.     if (!strcmp(string, "definitions:")) {
  137.         if (read_definitions() == BREAK) {
  138.             fclose(in_stream); in_stream = sv_instream; 
  139.         return(BREAK);
  140.         }
  141.     }
  142.     else
  143.         if (!strcmp(string, "constraints:")) {
  144.         if (read_constraints(constants) == BREAK) {
  145.                 fclose(in_stream); in_stream = sv_instream; 
  146.             return(BREAK);
  147.         }
  148.         }
  149.     else
  150.         if (!strcmp(string, "network:")) {
  151.         defined_weights = read_network(constants);
  152.         if (!defined_weights) {
  153.          if (put_error(err_string) == BREAK) {
  154.                 fclose(in_stream); in_stream = sv_instream; 
  155.              return(BREAK);
  156.          }
  157.         }
  158.         }
  159.     else
  160.         if (!strcmp(string, "biases:")) {
  161.         if (read_biases(constants) == BREAK) {
  162.                 fclose(in_stream); in_stream = sv_instream; 
  163.             return(BREAK);
  164.         }
  165.         }
  166.     else
  167.         if (!strcmp(string, "sigmas:")) {
  168.         if (read_sigmas(constants) == BREAK) {
  169.                 fclose(in_stream); in_stream = sv_instream; 
  170.             return(BREAK);
  171.         }
  172.         }
  173.     else
  174.         if (!strcmp(string, "end")) {
  175.         /* just skip over it */
  176.         }
  177.     else {
  178.         sprintf(err_string,
  179.           "error reading network file: I don't understand %s\n",string);
  180.         if (put_error(err_string) == BREAK) {
  181.             fclose(in_stream); in_stream = sv_instream; 
  182.             return(BREAK);
  183.         }
  184.     }
  185.     }
  186.     fclose(in_stream);
  187.     in_stream = sv_instream;
  188.     if (nlinks)
  189.     constrain_weights();
  190.     return(CONTINUE);
  191. }
  192.  
  193. read_definitions() {
  194.     char    string[BUFSIZ];
  195.     struct Variable *varp,
  196.                    *lookup_var ();
  197.  
  198.     while (fscanf(in_stream, "%s", string) != EOF) {
  199.     if (!strcmp(string, "end"))
  200.         return(CONTINUE);
  201.     if ((varp = lookup_var(string)) != NULL) {
  202.         change_variable(string,(int *) varp);
  203.     }
  204.     else {
  205.         sprintf(err_string,
  206.             "Error: unknown variable in network file, %s\n", string);
  207.         return(put_error(err_string));
  208.     }
  209.     }
  210. }
  211.  
  212. read_network(con)
  213. struct constants   *con;
  214. {
  215.     int     i,r,s,block,since_first,last_weight_to,tempint;
  216.     int        rstart,rnum,rend,sstart,snum,send,con_index;
  217.     char    ch,all_ch,*strp;
  218.     char    string[BUFSIZ];
  219.     int        needline = 1;
  220.     float   *tmp; char *ctmp;
  221.  
  222.     (void) srand(random_seed);
  223.     weight = ((float **)  emalloc((unsigned int)(sizeof(float *) * nunits)));
  224.     
  225.     epsilon = ((float **) emalloc((unsigned int)(sizeof(float *)) * nunits));
  226.     
  227.     wchar = ((char **) emalloc((unsigned int)(sizeof(char *) * nunits)));
  228.  
  229.     first_weight_to = (int *) emalloc((unsigned int)(sizeof(int) * nunits));
  230.     for (r = 0; r < nunits; r++)
  231.     first_weight_to[r] = nunits;
  232.     num_weights_to = (int *) emalloc((unsigned int)(sizeof(int) * nunits));
  233.     for (r = 0; r < nunits; r++)
  234.     num_weights_to[r] = 0;
  235.  
  236.     (void) install_var("weight",PVweight,(int *) weight,nunits,nunits,
  237.                             SETWTMENU);
  238.     (void) install_var("epsilon", PVweight,(int *) epsilon, nunits, nunits, 
  239.                                    epsilon_menu);
  240.     if (bp) {
  241.         wed = ((float **) emalloc((unsigned int)(sizeof(float *) * nunits)));
  242.         (void) install_var("wed",PVweight,(int *) wed,nunits,nunits,
  243.                             SETSVMENU);
  244.     }
  245.     
  246.     rstart = 0; rend = nunits -1; sstart = 0; send = nunits -1;
  247.     for (block = 0; ; block++) {
  248. gbagain:
  249.       if (fscanf(in_stream,"%s",string) == EOF) {
  250.         sprintf(err_string,"error in network description");
  251.         return(FALSE);
  252.       }
  253.       if (strcmp("end",string) == 0) {
  254.           if (block) return(TRUE);
  255.     else {
  256.      sprintf(err_string,"error in network description");
  257.     }
  258.     return(FALSE);
  259.       }
  260.       all_ch = '\0';
  261.       if (string[0] == '%') {
  262.         fscanf(in_stream,"%d%d%d%d",&rstart,&rnum,&sstart,&snum);
  263.     rend = rstart + rnum -1;
  264.     send = sstart + snum -1;
  265.     if (string[1]) {
  266.         all_ch = string[1];
  267.     }
  268.       }
  269.       else {
  270.        if (!block) {
  271.     needline = 0;
  272.        }
  273.        else {
  274.         sprintf(err_string,"error in network description");
  275.         return(FALSE);
  276.        }
  277.       }
  278.       for (r = rstart; r <= rend; r++) {
  279.       if (!all_ch) {
  280.         if (needline) {
  281.              if (fscanf(in_stream,"%s",string) == EOF) {
  282.            sprintf(err_string,"not enough units in network description");
  283.            return(FALSE);
  284.          }
  285.         }
  286.         else needline = 1;
  287.       }
  288.       else {
  289.         for (s = 0; s < snum; s++) string[s] = all_ch;
  290.         string[s] = '\0';
  291.       }
  292.       first_weight_to[r] = sstart;
  293.       last_weight_to = send;      
  294.       num_weights_to[r] = 1 + last_weight_to - first_weight_to[r];
  295.       weight[r] = ((float *)
  296.           emalloc ((unsigned int)(sizeof(float) * num_weights_to[r])));
  297.       epsilon[r] = ((float *)
  298.           emalloc ((unsigned int)(sizeof(float) * num_weights_to[r])));
  299.       wchar[r] = ((char *)
  300.           emalloc ((unsigned int)(sizeof(char) * num_weights_to[r])));
  301.       if (bp) {
  302.       wed[r] = ((float *)
  303.           emalloc ((unsigned int)(sizeof(float) * num_weights_to[r])));
  304.       }
  305.       for(s = 0; s < num_weights_to[r]; s++) {
  306.          weight[r][s] = 0.0;
  307.          epsilon[r][s] = 0.0;
  308.          wchar[r][s] = '.';
  309.          if (bp) wed[r][s] = 0.0;
  310.       }
  311.       for (strp = string,s = sstart,since_first = 0; s <= send; s++) {
  312.                 /* loop over the from units */
  313.         ch = *strp++;
  314.         wchar[r][since_first] = ch;
  315.         if (ch == '.') {
  316.         since_first++;
  317.         }
  318.         else {
  319.         /* first check if this is realy a character */
  320.         if (!isalpha(ch)) {
  321.             sprintf(err_string,"non_alpha character in network");
  322.             return(FALSE);
  323.         }
  324.  
  325.  
  326.         /* upper case means this weight is non-changable */
  327.         if (isupper(ch)) {
  328.         /* make it lower case */
  329.             ch = tolower(ch);
  330.             epsilon[r][since_first] = 0;
  331.         }
  332.         else {
  333.             epsilon[r][since_first] = lrate;
  334.         }
  335.  
  336.         /* now set up the char based on the stored con definitions */
  337.         if (con[ch - 'a'].random) {
  338.             if (con[ch - 'a'].positive) {
  339.             if (nposconstr >= maxpos) {
  340.                 enlarge_constraints(ENLARGE_POS);    
  341.             }
  342.             weight[r][since_first] = wrange * rnd();
  343.             positive_constraints[nposconstr++] = 
  344.                  &weight[r][since_first];
  345.             }
  346.             else
  347.             if (con[ch - 'a'].negative) {
  348.                 if (nnegconstr >= maxneg){
  349.                     enlarge_constraints(ENLARGE_NEG);
  350.                 }
  351.                 weight[r][since_first] = 
  352.                      wrange * (rnd() - 1);
  353.                 negative_constraints[nnegconstr++] = 
  354.                      &weight[r][since_first];
  355.             }
  356.             else
  357.             weight[r][since_first] = wrange * (rnd() -.5);
  358.         }
  359.         else {
  360.             weight[r][since_first] = con[ch - 'a'].value;
  361.         }
  362.         if (con[ch - 'a'].link) {
  363.             con_index = (con[ch - 'a'].link - 1);
  364.             if (constraints[con_index].num >= constraints[con_index].max) {
  365.                 enlarge_constraints(con_index);
  366.             }
  367.             
  368.             tempint = constraints[con_index].num;
  369.             constraints[con_index].cvec[tempint] 
  370.                   = &weight[r][since_first];
  371.  
  372.             if (bp) {
  373.             constraints[con_index].ivec[tempint] 
  374.                   = &wed[r][since_first];
  375.             }
  376.  
  377.                 tempint = constraints[con_index].num + 1;
  378.             constraints[con_index].num = tempint;
  379.             /* this kludge (tempint) is for the MS compiler */
  380.         }
  381.         since_first++;
  382.         }
  383.       }
  384.       }
  385.     }
  386. }
  387.  
  388. read_biases(con)
  389. struct constants   *con;
  390. {
  391.     int     j,rstart,rend,rnum,block,con_index,tempint;
  392.     char    ch,all_ch,*strp;
  393.     char    string[BUFSIZ];
  394.  
  395.     bias = (float *) emalloc((unsigned int)(sizeof(float) * nunits));
  396.     (void) install_var("bias", Vfloat,(int *) bias, nunits, 0, SETWTMENU);
  397.  
  398.     bepsilon = (float *) emalloc((unsigned int)(sizeof(float) * nunits));
  399.     (void) install_var("bepsilon", Vfloat,(int *) bepsilon, nunits, 0, 
  400.                                 epsilon_menu);
  401.     bchar = (char *) emalloc((unsigned int)(sizeof(char) * nunits));
  402.  
  403.     if (bp) {
  404.         bed = (float *) emalloc((unsigned int)(sizeof(float) * nunits));
  405.         (void) install_var("bed", Vfloat,(int *) bed,nunits,0,SETSVMENU);
  406.     }
  407.     
  408.     for (j = 0; j < nunits; j++) {
  409.     bias[j] = 0.0;
  410.     bepsilon[j] = 0;
  411.     bchar[j] = '.';
  412.     if (bp) bed[j] = 0.0;
  413.     }
  414.  
  415.     rstart = 0; rend = nunits -1;
  416.   for (block = 0; ; block++) {
  417. gtagain:
  418.     if (fscanf(in_stream,"%s",string) == EOF) {
  419.     return(put_error("problem in bias description"));
  420.     }
  421.     if (strcmp(string,"end") == 0) {
  422.         if (block) return (CONTINUE);
  423.         else return(put_error("problem in bias description"));
  424.     }
  425.     if (string[0] == '%') {
  426.         fscanf(in_stream,"%d%d",&rstart,&rnum);
  427.     rend = rstart + rnum -1;
  428.     if (string[1] != '\0') {
  429.         all_ch = string[1];
  430.         for (j = 0; j < rnum; j++) {
  431.         string[j] = all_ch;
  432.         }
  433.         string[j] = '\0';
  434.     }
  435.     else goto gtagain;
  436.     }
  437.     for (strp = string, j = rstart; j <= rend; j++, strp++) {
  438.     ch = *strp;
  439.     bchar[j] = ch;
  440.     if (ch == '.') {
  441.         bias[j] = 0;
  442.         bepsilon[j] = 0;
  443.     }
  444.     else {
  445.     /* first check if this is realy a character */
  446.         if (!isalpha(ch)) {
  447.         return(put_error("non_alpha character in bias"));
  448.         }
  449.  
  450.     /* upper case means this weight is non-changable */
  451.         if (isupper(ch)) {
  452.         /* make it lower case */
  453.         ch = tolower(ch);
  454.         bepsilon[j] = 0;
  455.         }
  456.         else {
  457.         bepsilon[j] = lrate;
  458.         }
  459.  
  460.         /* now set up the char based on the stored con definitions */
  461.         if (con[ch - 'a'].random) {
  462.             if (con[ch - 'a'].positive) {
  463.             bias[j] = wrange * rnd();
  464.             if (nposconstr >= maxpos) {
  465.                 enlarge_constraints(ENLARGE_POS);    
  466.             }
  467.             positive_constraints[nposconstr++] = &bias[j];
  468.             }
  469.             else
  470.             if (con[ch - 'a'].negative) {
  471.                 bias[j] = wrange * (rnd() - 1);
  472.                 if (nnegconstr >= maxneg){
  473.                     enlarge_constraints(ENLARGE_NEG);
  474.                 }
  475.                 negative_constraints[nnegconstr++] = &bias[j];
  476.             }
  477.             else
  478.             bias[j] = wrange * (rnd() -.5);
  479.         }
  480.         else {
  481.             bias[j] = con[ch - 'a'].value;
  482.         }
  483.         if (con[ch - 'a'].link) {
  484.         con_index = (con[ch - 'a'].link - 1);
  485.         if (constraints[con_index].num >= constraints[con_index].max){
  486.             enlarge_constraints(con_index);
  487.             }
  488.         tempint = constraints[con_index].num;
  489.         constraints[con_index].cvec[tempint] = &bias[j];
  490.         if (bp) constraints[con_index].ivec[tempint] = &bed[j];
  491.         constraints[con_index].num++;
  492.         }
  493.     }
  494.     }
  495.   }
  496. }
  497.  
  498. read_sigmas(con) struct constants   *con; {
  499.     int     j;
  500.     char    ch, all_ch, *strp;
  501.     char    string[BUFSIZ];
  502.     int        rstart, rend, rnum, block;
  503.  
  504.     sigma = (float *) emalloc((unsigned int)(sizeof(float) * nunits));
  505.     for (j = 0; j < nunits; j++) {
  506.       sigma[j] = 1.0;         /* default sigma is 1.0 */
  507.     }
  508.     (void) install_var("sigma", Vfloat,(int *) sigma, nunits, 0, 
  509.                SETWTMENU);
  510.     rstart = 0; rend = nunits -1;
  511.   for (block = 0; ; block++) {
  512. gsagain:      
  513.     if (fscanf(in_stream, "%s", string) == EOF) {
  514.     return(put_error("problem in sigma description"));
  515.     }
  516.     if (strcmp(string,"end") == 0) {
  517.         if (block) return (CONTINUE);
  518.         else return(put_error("problem in sigma description"));
  519.     }
  520.     if (string[0] == '%') {
  521.         fscanf(in_stream,"%d%d",&rstart,&rnum);
  522.     rend = rstart + rnum -1;
  523.     if (string[1] != '\0') {
  524.         all_ch = string[1];
  525.         for (j = 0; j < rnum; j++) {
  526.         string[j] = all_ch;
  527.         }
  528.         string[j] = '\0';
  529.     }
  530.     else goto gsagain;
  531.     }
  532.     for (strp = string, j = rstart; j <= rend; j++, strp++) {
  533.     ch = *strp;
  534.     if (ch == '.') {
  535.       sigma[j] = 1.0;
  536.     }
  537.     else {
  538.     /* first check if this is really a character */
  539.         if (!isalpha(ch)) {
  540.         return(put_error("non_alpha character in bias"));
  541.         }
  542.         if (isupper(ch)) {
  543.         /* make it lower case */
  544.         ch = tolower(ch);
  545.         }
  546.         sigma[j] = con[ch - 'a'].value;
  547.         if (sigma[j] < 0) {
  548.           return(put_error("can't set sigma less than 0!"));
  549.         }
  550.     }
  551.     }
  552.   }
  553. }
  554.  
  555. read_constraints(con)
  556. struct constants   *con;
  557. {
  558.     char    ch;
  559.     float   flt;
  560.     int     isflt;
  561.     char    string[BUFSIZ];
  562.     char    str[5][30];
  563.     int     i,j,ch_ind;
  564.     int        nstr;
  565.  
  566.     while (fgets(string, BUFSIZ, in_stream) != NULL) {
  567.         if (string[0] == NULL || string[0] == '\n') {
  568.         if (fgets(string, BUFSIZ, in_stream) == NULL) {
  569.             break;
  570.         }
  571.     }
  572.     if (strncmp(string,"end",3) == 0) break;
  573.  
  574.     ch = '\0';
  575.  
  576.     for (i = 0; i < 5; i++) str[i][0] = '\0';
  577.  
  578.     (void) sscanf(string, "%c %s %s %s %s %s", 
  579.                   &ch, str[0], str[1], str[2], str[3], str[4]);
  580.     ch = (isupper(ch)) ? tolower(ch) : ch;
  581.     ch_ind = ch - 'a';
  582.     con[ch_ind].random = con[ch_ind].positive = 
  583.         con[ch_ind].negative = con[ch_ind].link = FALSE;
  584.     con[ch_ind].value = 0.0;
  585.     for (i = 0; (i < 5) && (str[i][0] != '\0'); i++) {
  586.         if ( (isflt = sscanf(str[i],"%f",&flt)) == 1) {
  587.         con[ch_ind].value = flt;
  588.         }
  589.         else
  590.         if (startsame(str[i], "random"))
  591.             con[ch_ind].random = TRUE;
  592.         else
  593.         if (startsame(str[i], "positive"))
  594.             con[ch_ind].positive = TRUE;
  595.         else
  596.         if (startsame(str[i], "negative"))
  597.             con[ch_ind].negative = TRUE;
  598.         else
  599.         if (startsame(str[i], "linked"))
  600.             con[ch_ind].link = ++nlinks;
  601.         else {
  602.         sprintf(err_string,
  603.           "unknown type for constant %c, %s\n", ch, str[i]);
  604.         if (put_error(err_string) == BREAK) {
  605.             return(BREAK);
  606.         }
  607.         }
  608.     }
  609.     }
  610.     if (nlinks) {
  611.     constraints = (struct constraint   *) 
  612.       emalloc ((unsigned int)(sizeof (struct constraint) * (nlinks + 1)));
  613.     for (i = 0; i < nlinks; i++) {
  614.         constraints[i].num = 0;
  615.         constraints[i].max = MAXCONSTRAINTS;
  616.         constraints[i].cvec = ((float **) 
  617.             emalloc((unsigned int)(sizeof(float *) * MAXCONSTRAINTS)));
  618.         constraints[i].ivec = ((float **) 
  619.             emalloc((unsigned int)(sizeof(float *) * MAXCONSTRAINTS)));
  620.         for (j = 0; j < constraints[i].max; j++) {
  621.         constraints[i].cvec[j] = NULL;
  622.         constraints[i].ivec[j] = NULL;
  623.         }
  624.     }
  625.     }
  626.     else {
  627.     constraints = NULL;
  628.     }
  629.     positive_constraints = ((float **) 
  630.             emalloc((unsigned int)(sizeof(float *) * MAXCONSTRAINTS)));
  631.     for (i = 0; i < MAXCONSTRAINTS; i++)
  632.     positive_constraints[i] = NULL;
  633.     negative_constraints = ((float **) 
  634.             emalloc((unsigned int)(sizeof(float *) * MAXCONSTRAINTS)));
  635.     for (i = 0; i < MAXCONSTRAINTS; i++)
  636.     negative_constraints[i] = NULL;
  637.     return(CONTINUE);
  638. }
  639.  
  640. change_lrate() {
  641.     struct Variable *varp;
  642.     int     i,
  643.             j;
  644.  
  645.     if ((varp = lookup_var("lrate")) != NULL) {
  646.     change_variable("lrate",(int *) varp);
  647.     }
  648.     else {
  649.     return(put_error("BIG PROBLEM: lrate is not defined"));
  650.     }
  651.  
  652.     if (epsilon != NULL) {
  653.     for (i = 0; i < nunits; i++) {
  654.         for (j = 0; j < num_weights_to[i]; j++) {
  655.         if (epsilon[i][j] != 0.0)
  656.             epsilon[i][j] = lrate;
  657.         }
  658.     }
  659.     }
  660.     if (bepsilon != NULL) {
  661.     for (i = 0; i < nunits; i++) {
  662.         if (bepsilon[i] != 0.0)
  663.         bepsilon[i] = lrate;
  664.     }
  665.     }
  666. }
  667.  
  668. /* given a defined system, we will write the matrix and the biases 
  669.    out to a file.  The file format is one floating point number per line,
  670.    with the weight matrix in row major format followed by the biases.
  671. */
  672.  
  673. write_weights() {
  674.     int     i,j,end;
  675.     char   *str = NULL;
  676.     char fname[BUFSIZ];
  677.     char *star_ptr;
  678.     char tstr[40];
  679.     FILE * iop;
  680.  
  681.     if (weight == NULL) {
  682.     return(put_error("cannot save undefined network"));
  683.     }
  684.  
  685. nameagain:
  686.     str = get_command("weight file name: ");
  687.     if (str == NULL) return(CONTINUE);
  688.     strcpy(fname,str);
  689.     if ( (star_ptr = strchr(fname,'*')) != NULL) {
  690.         strcpy(tstr,star_ptr+1);
  691.         sprintf(star_ptr,"%d",epochno);
  692.     strcat(fname,tstr);
  693.     }
  694.     if ((iop = fopen(fname, "r")) != NULL) {
  695.         fclose(iop);
  696.         get_command("file exists -- clobber? ");
  697.     if (str == NULL || str[0] != 'y') {
  698.        goto nameagain;
  699.     }
  700.     }
  701.     if ((iop = fopen(fname, "w")) == NULL) {
  702.     return(put_error("cannot open file for output"));
  703.     }
  704.  
  705.     for (i = 0; i < nunits; i++) {
  706.        for (j = 0; j < num_weights_to[i]; j++) {
  707.     fprintf(iop, "%f\n", weight[i][j]);
  708.        }
  709.     }
  710.  
  711.     if (bias) {
  712.       for (i = 0; i < nunits; i++) {
  713.      fprintf(iop, "%f\n", bias[i]);
  714.       }
  715.     }
  716.  
  717.     if (sigma) {
  718.       for (i = 0; i < nunits; i++) {
  719.      fprintf(iop, "%f\n", sigma[i]);
  720.       }
  721.     }
  722.  
  723.     (void) fclose(iop);
  724.     return(CONTINUE);
  725. }
  726.  
  727.  
  728. read_weights() {
  729.     int     i,j,end;
  730.     char   *str = NULL;
  731.     FILE * iop;
  732.  
  733.     if(!System_Defined)
  734.        if(!define_system())
  735.       return(BREAK);
  736.  
  737.     if (weight == NULL) {
  738.     return(put_error("cannot restore undefined network"));
  739.     }
  740.  
  741.     if((str = get_command("File name for stored weights: ")) == NULL)
  742.     return(CONTINUE);
  743.  
  744.     if ((iop = fopen(str, "r")) == NULL) {
  745.         sprintf(err_string,"Cannot open weight file %s.",str);
  746.     return(put_error(err_string));
  747.     }
  748.  
  749.     for (i = 0; i < nunits; i++) {
  750.     if(num_weights_to[i] == 0) continue;
  751.     for (j = 0; j < num_weights_to[i]; j++) {
  752.       if (fscanf(iop, "%f", &weight[i][j]) == 0) {
  753.       fclose(iop);
  754.         return(put_error("weight file is not correct for this network"));
  755.       }
  756.     }
  757.     }
  758.  
  759.     end = nunits;
  760.     
  761.     if (bias != NULL) {
  762.       for (i = 0; i < end; i++) {
  763.     if (fscanf(iop, "%f", &bias[i]) == 0) {
  764.         fclose(iop);
  765.         return(put_error("weight file is not correct for this network"));
  766.     }
  767.       }
  768.     }
  769.  
  770.     if (sigma != NULL) {
  771.       for (i = 0; i < end; i++) {
  772.     if (fscanf(iop, "%f", &sigma[i]) == 0) {
  773.         fclose(iop);
  774.         return(put_error("weight file is not correct for this network"));
  775.     }
  776.       }
  777.     }
  778.  
  779.     (void) fclose(iop);
  780.     update_display();
  781.     return(CONTINUE);
  782. }
  783.  
  784. /* realloc positive_constraints, negative_constraints, and link constraints
  785.    this is called whenever the allocated constraint lists run out of
  786.    space for additional constraints  14-May-87 MAF / 15-May-87 JLM */
  787.  
  788. #define CON_INCR 100 /* increment in size of constriant */
  789.  
  790. enlarge_constraints(con_index) int con_index; {
  791.  
  792.     int j;
  793.  
  794.     if (con_index == ENLARGE_POS) {
  795.     maxpos += CON_INCR;
  796.     positive_constraints = ((float **) erealloc 
  797.       ((char *) positive_constraints,
  798.           (unsigned int) ((maxpos - CON_INCR) * sizeof(float *)),
  799.           (unsigned int) (maxpos * sizeof(float *))));
  800.     for (j = maxpos - CON_INCR; j < maxpos; j++) {
  801.       positive_constraints[j] = NULL;
  802.     }
  803.     }
  804.     else if (con_index == ENLARGE_NEG) {
  805.     maxneg += CON_INCR;
  806.     negative_constraints = ((float **) erealloc 
  807.       ((char *) negative_constraints,
  808.          (unsigned int) ((maxneg -CON_INCR) * sizeof (float *)),
  809.          (unsigned int) (maxneg * sizeof(float *))));
  810.     for (j = maxneg - CON_INCR; j < maxneg; j++) {
  811.       negative_constraints[j] = NULL;
  812.     }
  813.     }
  814.     else {
  815.     constraints[con_index].max += CON_INCR;
  816.         constraints[con_index].cvec = ((float **) erealloc 
  817.       ((char *)constraints[con_index].cvec,
  818.        (unsigned int)
  819.          ((constraints[con_index].max - CON_INCR) * sizeof(float *)),
  820.        (unsigned int)
  821.          (constraints[con_index].max * sizeof(float *))));
  822.         constraints[con_index].ivec = ((float **) erealloc 
  823.       ((char *)constraints[con_index].ivec,
  824.        (unsigned int)
  825.          ((constraints[con_index].max - CON_INCR) * sizeof(float *)),
  826.        (unsigned int)
  827.          (constraints[con_index].max * sizeof(float *))));
  828.     for (j = constraints[con_index].max - CON_INCR; 
  829.          j < constraints[con_index].max; j++) {
  830.       constraints[con_index].cvec[j] = NULL;
  831.       constraints[con_index].ivec[j] = NULL;
  832.        }
  833.    }
  834. }
  835.