www.pudn.com > BPËã·¨Ô´Âë.zip > misc.c


/* **************************************************** */ 
/* file misc.c:  contains pattern manipulation routines */ 
/*               and miscellaneous other functions.     */ 
/*                                                      */ 
/* Copyright (c) 1990-1996 by Donald R. Tveter          */ 
/*                                                      */ 
/* **************************************************** */ 
 
#ifdef INTEGER 
#include "ibp.h" 
#else 
#include "rbp.h" 
#endif 
 
/* built-in function */ 
 
extern int rand(); 
 
/* homemade functions */ 
 
#ifdef INTEGER 
extern REAL unscale(), unscaleint(); 
extern WTTYPE scale(); 
extern char wtlimithit; 
#endif 
 
extern short backoutput(), cbackoutput(); 
extern void backinner(), cbackinner(), saveweights(); 
extern void printnetsize(), restoreweights(); 
extern WTTYPE rdr(); 
extern void dbd_update(), periodic_update(), qp_update(); 
extern REAL readchar(); 
extern int pg(), rclasscheck(), printoutunits(); 
extern UNIT *locateunit(); 
 
extern char *datafile,emptystring,freezing,informat,offby1,outstr[]; 
extern char probtype, ringbell, summary, *testfile; 
extern char *trainfile, update, up_to_date_stats; 
extern char zeroderiv, biasset; 
extern char seednote, runningflag, outsumsflag, saveonminimum,outformat; 
extern char trfiles[], recurinit, benchsummary, wtinitroutine; 
extern short nlayers; 
extern int lastadd,lastprint,lastsave,maxtries,prevnpats,readerror; 
extern int readingpattern,right,saverate,totaliter,window,wrong; 
extern int wtsinuse, wttotal, extraconnect, ioconnects, originallypcc; 
extern long iotime; 
extern SEEDNODE *seedstart; 
extern WTTYPE dbdeta, qpeta, sseta, unknown, toler, toosmall; 
extern WTTYPE kicksize, kickrange, initrange; 
extern LAYER *last, *start; 
extern DATA s[2][2], rs[2][2]; 
#ifdef INTEGER 
extern INT32 totaldiff; 
#else 
extern REAL totaldiff; 
#endif 
extern REAL toloverall; 
extern REAL minimumsofar; 
 
void nullpatterns(list) 
int list; 
{ /* dispose of any patterns before reading more */ 
PATLIST *pl, *nextpl; 
PATNODE *p; 
 
if (start->patstart[list] != NULL) 
 { 
  pl = start->patstart[list]; 
  while (pl != NULL) 
   { 
    nextpl = pl->next; 
    p = pl->pats; 
    free(p); 
    pl = nextpl; 
   }; 
  pl = last->patstart[list]; 
  while (pl != NULL) 
   { 
    nextpl = pl->next; 
    p = pl->pats; 
    free(p); 
    pl = nextpl; 
   }; 
 }; 
start->patstart[list] = NULL; 
last->patstart[list] = NULL; 
s[TOL][list].npats = 0; 
s[MAX][list].npats = 0; 
prevnpats = 0; 
} 
 
void resetpats(list) 
int list; 
{ 
start->currentpat[list] = NULL; 
last->currentpat[list] = NULL; 
} 
 
void findendofpats(layer)  /* purpose is to set all layer->currentpat */ 
LAYER *layer;              /* fields to end of pattern list so more   */ 
{                          /* patterns can be added at the end.       */ 
PATLIST *pl; 
pl = (PATLIST *) layer->patstart[TRAIN]; 
while (pl->next != NULL) pl = pl->next; 
layer->currentpat[TRAIN] = pl; 
} 
 
int copyhidden(u,hidden,layerno) 
UNIT *u, **hidden; 
int layerno; 
{ 
if (*hidden == NULL) 
 { 
  sprintf(outstr,"ran out of hidden units in layer %d\n",layerno); 
  pg(stdout,outstr); 
  return(0); 
 } 
u->oj = (*hidden)->oj; 
*hidden = (*hidden)->next; 
return(1); 
} 
 
int loadpat() 
{ 
  REAL val; 
  int unitnumber; 
  UNIT *otherunit, *hunit, *u; 
  readingpattern = 1; 
  hunit = start->next->units; 
  u = start->units; 
  while (u != NULL) 
   { 
    if (informat == 'r') val = rdr(GE,(REAL) DIFFCODE,'0'); 
    else val = scale(readchar()); 
    if (readerror != 0) goto errorexit; 
    if (val == (REAL) ICODE) 
     { 
      unitnumber = readint(1,start->unitcount,'0'); 
      if (readerror != 0) goto errorexit; 
      otherunit = locateunit(1,unitnumber); 
      u->oj = otherunit->oj; 
     } 
    else if (val == (REAL) OCODE) 
     { 
      unitnumber = readint(1,last->unitcount,'0'); 
      if (readerror != 0) goto errorexit; 
      otherunit = locateunit(nlayers,unitnumber); 
      u->oj = otherunit->oj; 
     } 
    else if (val == (REAL) HCODE) 
     { 
      if (copyhidden(u,&hunit,2) == 0) goto errorexit; 
     } 
    else if (val == (REAL) CAPHCODE) 
     { 
      while (u != NULL) 
       { 
        if (copyhidden(u,&hunit,2) == 0) goto errorexit; 
        u = u->next; 
       }; 
      goto leaveok; 
     } 
    else if (val == (REAL) CAPXCODE) 
     { 
      while (u != NULL) 
       { 
        if (hunit == NULL) return(0); 
        u->oj = unknown; 
        hunit = hunit->next; 
        u = u->next; 
       }; 
      goto leaveok; 
     } 
    else u->oj = val; 
    u = u->next; 
   }; 
 
leaveok: 
 readingpattern = 0; 
 forward(); 
 return(1); 
 
errorexit: 
 readingpattern = 0; 
 return(0); 
} 
 
void nextpat(list) 
int list; 
{ 
if (start->currentpat[list] == NULL) 
 { 
  start->currentpat[list] = start->patstart[list]; 
  last->currentpat[list] = last->patstart[list]; 
 } 
else 
 { 
  start->currentpat[list] = (start->currentpat[list])->next; 
  last->currentpat[list] = (last->currentpat[list])->next; 
 }; 
} 
 
void setinputpat(list) 
int list; 
{ 
register PATNODE *pn; 
register UNIT *u; 
UNIT *hunit; 
PATLIST *pl; 
   
hunit = start->next->units; 
pl = start->currentpat[list]; 
pn = pl->pats; 
u = (UNIT *) start->units; 
while (u != NULL) 
 { 
  if (pn->addr == NULL)  /* load a plain number */ 
   { 
    u->oj = pn->val; 
    pn++; 
   } 
  else 
   { 
    if (pn->unitno > 0)  /* load a value from an input or output unit */ 
     { 
      u->oj = *(pn->addr); 
      pn++; 
     } 
    /* else load unknown or hidden unit values */ 
    else if (pn->unitno == CAPHCODE) 
     {if (!copyhidden(u,&hunit,2)) return;} 
    else if (pn->unitno == HCODE) 
     { 
      {if (!copyhidden(u,&hunit,2)) return;} 
      pn++; 
     } 
    else if (pn->unitno == CAPXCODE) u->oj = unknown; 
    else{sprintf(outstr,"ran out of unit codes, got: %d\n",pn->unitno); 
         pg(stdout,outstr); fflush(stdout);}; 
   }; 
  u = u->next; 
 }; 
} 
 
void setonepat(list) /* set input pattern */ 
int list; 
{ 
register UNIT *u; 
register LAYER *innerlayers; 
 
setinputpat(list); 
innerlayers = start->next; 
while (innerlayers->next != NULL) 
 {  /* set errors on the inner layer units to 0 */ 
  u = (UNIT *) innerlayers->units; 
  while (u != NULL) 
   { 
    u->error = 0; 
    u = u->next; 
   }; 
  innerlayers = innerlayers->next; 
 }; 
} 
 
void clear() 
{ 
LAYER *p, *lowerlayer; 
UNIT *u, *unext, *ulast, *bu; 
WTNODE *w, *wnext, *wprev; 
int i,j, layerno; 
REAL *val; 
 
#ifndef SYMMETRIC 
biasset = 0; 
#endif 
for (i=TRAIN;i<=TEST;i++) for (j=TOL;j<=MAX;j++) 
 { 
  s[j][i].uncertain = 0; 
  s[j][i].iterno = 0; 
  s[j][i].right = 0; 
  s[j][i].wrong = s[j][i].npats; 
  s[j][i].avgerr = 0.0; 
  s[j][i].pctright = 0.0; 
 }; 
#ifdef INTEGER 
wtlimithit = 0; 
#endif 
zeroderiv = 0; 
lastadd = 0; 
toosmall = 0; 
totaliter = 0; 
lastsave = 0; 
lastprint = 0; 
 
/* bring back unused units */ 
p = last; 
while (p != NULL) 
 { 
  u = p->units; 
  while (u != NULL) 
   { 
    u->inuse = 1; 
    u = u->next; 
   }; 
  p = p->backlayer; 
 }; 
 
/* get rid of input weights from units in the hidden layer below */ 
/* that are going to be removed (in the next major loop) */ 
p = last; 
while (p->backlayer != NULL) 
 { 
  u = p->units; 
  while (u != NULL) 
   { 
    w = (WTNODE *) u->wtlist; 
    wprev = w; 
    w = w->next;  /* the first weight will never be removed! */ 
    while (w->next != NULL) /* last weight will never be removed! */ 
     { 
      bu = w->backunit; 
      layerno = bu->layernumber; 
      lowerlayer = start; 
      for (i=1;i<=(layerno - 1);i++) lowerlayer = lowerlayer->next; 
      if (bu->unitnumber > lowerlayer->initialcount) 
       { 
        wprev->next = w->next; 
        wnext = w->next; 
        free(w); 
        wttotal = wttotal - 1; 
        w = wnext; 
       } 
      else 
       { 
        wprev = w; 
        w = w->next; 
       }; 
     }; 
    u = u->next; 
   }; 
  p = p->backlayer; 
 }; 
/* get rid of extra units and their input weights */ 
/*p = start->next; */ 
p = start; 
while (p != last) 
 { 
  if (p->unitcount > p->initialcount) 
   { 
    u = p->units; 
    for (i=1;i<=(p->initialcount-1);i++) u = u->next; 
    ulast = u; 
    u = u->next; 
    ulast->next = NULL; 
    while (u != NULL) 
     { 
      unext = u->next; 
      w = (WTNODE *) u->wtlist; 
      while (w != NULL) 
       { 
        wnext = w->next; 
        free(w); 
        wttotal = wttotal - 1; 
        w = wnext; 
       }; 
      free(u); 
      u = unext; 
     }; 
   }; 
  p->unitcount = p->initialcount; 
  p = p->next; 
 }; 
/* clear the input layer units */ 
u = start->units; 
while (u != NULL) 
 { 
  u->oj = 0; 
  u = u->next; 
 }; 
/* re-initialize the weights and such */ 
wttotal = 0; 
p = start->next; 
while (p != NULL) 
 { 
  u = (UNIT *) p->units; 
  while (u != NULL) 
   { 
    u->oj = 0; 
    w = (WTNODE *) u->wtlist; 
    while (w != NULL) 
     { 
#ifdef SYMMETRIC 
      if (w->next != NULL) 
       { /* skip threshold weight */ 
        *(w->weight) = 0; 
        *(w->olddw) = 0; 
       }; 
#else 
      w->weight = 0; 
      w->olddw = 0; 
      w->slope = 0; 
      wttotal = wttotal + 1; 
      if (w->inuse == 1 || w->inuse == 0 || w->inuse == -1) w->inuse = 1; 
      else w->inuse = 2; 
#endif 
      w = w->next; 
     }; 
    u = u->next; 
   }; 
  p = p->next; 
 }; 
wtsinuse = wttotal; 
} 
 
void stats() 
{ 
 if ((update == 'c' || update == 'C') && up_to_date_stats == '-') 
  { 
   s[TOL][TRAIN].uncertain = 1; 
   s[MAX][TRAIN].uncertain = 1; 
  }; 
 s[TOL][TRAIN].off = -1; 
 s[MAX][TRAIN].off = -1; 
 right = s[TOL][TRAIN].npats - wrong; 
 s[TOL][TRAIN].right = right; 
 s[TOL][TRAIN].wrong = wrong; 
 s[TOL][TRAIN].iterno = totaliter; 
 s[MAX][TRAIN].iterno = totaliter; 
 s[TOL][TRAIN].avgerr = 
    unscaleint(totaldiff) / (REAL) ((right + wrong) * last->unitcount); 
 s[MAX][TRAIN].avgerr = s[TOL][TRAIN].avgerr; 
 s[TOL][TRAIN].pctright = 100.0 * 
    (REAL) right / (REAL) (right + wrong); 
 if (probtype == 'c') s[MAX][TRAIN].pctright = s[MAX][TRAIN].right 
    * 100.0 / (s[MAX][TRAIN].right + s[MAX][TRAIN].wrong); 
} 
 
int printstats(writefile,list,fileid,s) 
FILE *writefile; 
int list, fileid; 
DATA s[2][2]; 
{ 
char *f; 
int patcount; 
 
if (fileid == 1) 
 { 
  if (list == TEST) f = testfile; 
  else if (*trainfile == emptystring) f = datafile; 
  else f = trfiles; 
  patcount = s[TOL][list].npats; 
  if (list == TRAIN) {if (pg(writefile,trfiles)) return(1);} 
  else 
   { 
    pg(writefile,"tf "); 
    pg(writefile,testfile); 
    if (pg(writefile,"\n")) return(1); 
   }; 
 }; 
 
lastprint = totaliter; 
if (writefile != stdout) pg(writefile,"*"); 
sprintf(outstr,"%5d",s[TOL][list].iterno); pg(writefile,outstr); 
if (s[TOL][list].off == -1) pg(writefile," -1 "); else pg(writefile,"    "); 
pg(writefile,"(TOL) "); 
sprintf(outstr,"%6.2f %% ",s[TOL][list].pctright); pg(writefile,outstr); 
if (s[TOL][list].uncertain == 1) pg(writefile,"?? "); 
sprintf(outstr,"(%1d right  ",s[TOL][list].right);pg(writefile,outstr); 
sprintf(outstr,"%1d wrong)",s[TOL][list].wrong); pg(writefile,outstr); 
sprintf(outstr,"  %7.5f err/unit\n",s[TOL][list].avgerr); 
if (pg(writefile,outstr)) return(1); 
if (probtype == 'g') return(0); 
 
lastprint = totaliter; 
if (writefile != stdout) pg(writefile,"*"); 
sprintf(outstr,"%5d",s[MAX][list].iterno); pg(writefile,outstr); 
if (s[MAX][list].off == -1) pg(writefile," -1 "); else pg(writefile,"    "); 
pg(writefile,"(MAX) "); 
sprintf(outstr,"%6.2f %% ",s[MAX][list].pctright); pg(writefile,outstr); 
if (s[TOL][list].uncertain == 1) pg(writefile,"?? "); 
sprintf(outstr,"(%1d right  ",s[MAX][list].right); pg(writefile,outstr); 
sprintf(outstr,"%1d wrong)",s[MAX][list].wrong); pg(writefile,outstr); 
sprintf(outstr,"  %7.5f err/unit\n",s[MAX][list].avgerr); 
if (pg(writefile,outstr)) return(1); else return(0); 
} 
 
void maxerrors() 
{ 
register UNIT *u; 
register short unitnumber; 
register largest; 
register short largestunit, answer; 
register PATNODE *targetptr; 
PATLIST *pl; 
 
largest = scale(-30.0); 
largestunit = 0; 
unitnumber = 1; 
pl = last->currentpat[TRAIN]; 
targetptr = pl->pats; 
u = last->units; 
while (u != NULL) 
 { 
  if (targetptr->val > 0) answer = unitnumber; 
  if (u->oj > largest) 
   { 
    largest = u->oj; 
    largestunit = unitnumber; 
   }; 
  unitnumber++; 
  targetptr++; 
  u = u->next; 
 }; 
if (answer == largestunit) s[MAX][TRAIN].right++; 
else s[MAX][TRAIN].wrong++; 
} 
 
void errors(list,rowsum,tok,mok,answer,largestunit) 
int list; 
REAL *rowsum; 
char *tok,*mok; 
int *answer,*largestunit; 
{ 
register WTTYPE absdiff; 
/* sum should probably be WTTYPE but Zortech C 3.1 has a bug */ 
#ifdef INTEGER 
register INT32 sum; 
#else 
register WTTYPE sum; 
#endif 
register UNIT *u; 
WTTYPE largest; 
PATNODE *targetptr; 
int notclose, unitnumber; 
PATLIST *pl; 
 
notclose = last->unitcount; 
if (probtype == 'c') 
 { 
  unitnumber = 0; 
  largest = scale(-31.0); 
  *largestunit = 0; 
 }; 
sum = 0; 
pl = last->currentpat[list]; 
targetptr = pl->pats; 
u = last->units; 
while (u != NULL) 
 { 
  u->tj = targetptr->val; 
  targetptr++; 
  if (probtype == 'c') 
   { 
    unitnumber = unitnumber + 1; 
    if (u->tj > 0) *answer = unitnumber; 
    if (u->oj > largest) 
     { 
      largest = u->oj; 
      *largestunit = unitnumber; 
     }; 
   }; /* end if (probtype ... */ 
  absdiff = u->tj - u->oj; 
 
  if (absdiff < 0) absdiff = -absdiff; 
  if (absdiff < toler) notclose = notclose - 1; 
  sum = sum + absdiff; 
/*sprintf(outstr,"sum = %d\n",sum); pg(stdout,outstr);*/ 
  u = u->next; 
 }; /* end while (u != NULL) */ 
*rowsum = unscaleint(sum); 
/*sprintf(outstr,"*rowsum = %f\n",*rowsum); pg(stdout,outstr);*/ 
if (notclose == 0) *tok = 1; else *tok = 0; 
if (probtype == 'c') 
 {if (*answer == *largestunit) *mok = 1; else *mok = 0;} 
else *mok = 0; 
} 
 
void initnet() 
{ 
 UNIT *u; 
 LAYER *l; 
 l = start; 
 while (l != NULL) 
  { 
   u = l->units; 
   while (u != NULL) 
    { 
     u->oj = unknown; 
     u = u->next; 
    }; 
   l = l->next; 
  }; 
} 
 
int evalone(patnum,list,printing,recurrentclass) 
int patnum,list,printing,recurrentclass; 
{ 
int i,answer,largestunit; 
REAL rowsum; 
char tok,mok; 
 
resetpats(list); 
if (!recurrentclass) 
 { 
  for (i=1;i<=patnum;i++) nextpat(list); 
  setonepat(list); 
  forward(); 
 } 
errors(list,&rowsum,&tok,&mok,&answer,&largestunit); 
if (printing) 
 {if (printoutunits(patnum,last,list,rowsum,tok,mok)) return(1);} 
else return(0); 
} 
 
int eval(list,printing) 
int list, printing; 
{  
int i, j, patcount, class, best, nclasses, ipct, *addr, patnum; 
REAL sum, rowsum; 
char mok,tok; 
 
sum = 0.0; 
s[TOL][list].iterno = totaliter; 
s[TOL][list].right = 0; 
s[TOL][list].wrong = 0; 
if (probtype == 'c') 
 { 
  s[MAX][list].iterno = totaliter; 
  s[MAX][list].right = 0; 
  s[MAX][list].wrong = 0; 
  nclasses = last->unitcount; 
 }; 
patcount = s[TOL][list].npats; 
if (list == TRAIN && recurinit == '+') initnet(); 
resetpats(list); 
for (i=1;i<=s[TOL][list].npats;i++) 
 { 
  nextpat(list); 
  setonepat(list); 
  forward(); 
  errors(list,&rowsum,&tok,&mok,&class,&best); 
  sum = sum + rowsum; 
  if (tok) s[TOL][list].right++; else s[TOL][list].wrong++; 
  if (probtype == 'c') 
   { 
    if (mok) s[MAX][list].right++; else s[MAX][list].wrong++; 
   }; 
  if (printing) 
   {if (printoutunits(i,last,list,rowsum,tok,mok)) return(1);}; 
 };  /* end for */ 
s[TOL][list].uncertain = 0; 
s[MAX][list].uncertain = 0; 
s[TOL][list].off = 0; 
s[MAX][list].off = 0; 
s[TOL][list].pctright = 100.0 * 
   (REAL) s[TOL][list].right / (REAL) patcount; 
s[TOL][list].avgerr = sum / ((REAL) patcount * last->unitcount); 
s[MAX][list].avgerr = s[TOL][list].avgerr; 
if (probtype == 'c') 
 { 
  s[MAX][list].pctright = 100.0 * 
     (REAL) s[MAX][list].right / (REAL) patcount; 
  s[MAX][list].avgerr = sum / ((REAL) patcount * last->unitcount); 
  s[TOL][list].avgerr = s[MAX][list].avgerr; 
 }; 
return(0); 
} 
 
void evalr(list,printing,n) /* in a recurrent network, given n */ 
int list, printing, n;      /* inputs predict the nth output   */ 
{ 
PATLIST *sfront, *sback, *lback, *pat; 
UNIT *u; 
LAYER *l; 
int i, juststarted, patnum, answer, largestunit, tolright, maxright; 
char tok, mok; 
REAL rowsum, totalerror, avgerr, pctright; 
 
totalerror = 0.0; 
tolright = 0; 
maxright = 0; 
resetpats(list); 
nextpat(list); 
sback = start->currentpat[list]; 
sfront = sback; 
for (i=1;i<=n;i++) if (sfront != NULL) sfront = sfront->next; 
lback = last->currentpat[list]; 
patnum = n - 1; 
while (sfront != NULL) 
 { 
  patnum = patnum + 1; 
  initnet(); /* initialize network unit values to the unknown */ 
  juststarted = 1; 
  last->currentpat[list] = lback; 
  start->currentpat[list] = sback; 
  pat = sback; 
  while (pat != sfront) 
   { 
    if (juststarted) juststarted = 0; else nextpat(list); 
    setonepat(list); 
    forward(); 
    pat = pat->next; 
   }; 
  errors(list,&rowsum,&tok,&mok,&answer,&largestunit); 
  totalerror = totalerror + rowsum; 
  if (tok) tolright = tolright + 1; 
  if (mok) maxright = maxright + 1; 
  if (printing) printoutunits(patnum,last,TEST,rowsum,tok,mok); 
  lback = lback->next; 
  sback = sback->next; 
  sfront = sfront->next;  
 }; 
avgerr = totalerror / (s[TOL][list].npats - n + 1) / last->unitcount; 
pctright = tolright * 100.0 / (s[TOL][list].npats - n + 1); 
sprintf(outstr," TOL: %6.2f %% ",pctright); pg(stdout,outstr); 
if (probtype == 'c') 
 { 
  pctright = maxright * 100.0 / (s[TOL][list].npats - n + 1); 
  sprintf(outstr," MAX: %6.2f %% ",pctright); pg(stdout,outstr); 
 }; 
sprintf(outstr," ERROR: %f\n",avgerr); 
pg(stdout,outstr); 
} 
   
int compactstats(s,recurrentclass) 
DATA s[2][2]; 
int recurrentclass; 
{ /* training patterns */ 
 if (up_to_date_stats == '-' && offby1 == '-') eval(TRAIN,0); 
 sprintf(outstr,"%5d ",totaliter); pg(stdout,outstr); 
 if (s[TOL][TRAIN].off == -1) pg(stdout,"-1 "); else pg(stdout,"   "); 
 sprintf(outstr,"%6.2f %% ",s[TOL][TRAIN].pctright); pg(stdout,outstr); 
 if (probtype == 'c') 
  { 
   sprintf(outstr,"%6.2f %% ",s[MAX][TRAIN].pctright); pg(stdout,outstr); 
  }; 
 sprintf(outstr,"%7.5f ",s[TOL][TRAIN].avgerr); pg(stdout,outstr); 
 if (s[TOL][TRAIN].uncertain == 1) pg(stdout,"? "); else pg(stdout,"  "); 
 if (s[TOL][TEST].npats > 0)  /* if testing patterns exist */ 
  { 
   if (s[TOL][TEST].iterno != totaliter) eval(TEST,0); 
   if (saveonminimum == '+' && s[TOL][TEST].avgerr < minimumsofar) 
    { 
     saveweights(); 
     lastsave = s[TOL][TEST].iterno; 
     minimumsofar = s[TOL][TEST].avgerr; 
    }; 
   sprintf(outstr,"  %6.2f %% ",s[TOL][TEST].pctright); pg(stdout,outstr); 
   if (probtype == 'c') 
    { 
     sprintf(outstr,"%6.2f %% ",s[MAX][TEST].pctright); pg(stdout,outstr); 
    }; 
   sprintf(outstr,"%7.5f ",s[TOL][TEST].avgerr); pg(stdout,outstr); 
  }; 
 if (s[TOL][TRAIN].pctright == 100.0 || 
     s[TOL][TRAIN].avgerr < toloverall) 
  { 
   pg(stdout," DONE"); 
   if (ringbell == '+') putchar(7); 
  }; 
 if(pg(stdout,"\n")) return(1); else return(0); 
} 
  
void kick(size,amount) /* give the network a kick */ 
WTTYPE size, amount; 
{  
LAYER *layer; 
UNIT *u; 
WTNODE *w; 
WTTYPE value, delta; 
int sign; 
 
layer = start->next; 
while (layer != NULL) 
 { 
  u = (UNIT *) layer->units; 
  while (u != NULL) 
   { 
    w = (WTNODE *) u->wtlist; 
    while (w != NULL) 
     { 
#ifdef SYMMETRIC 
      value = *(w->weight); 
#else 
      value = w->weight; 
#endif 
      if (value != 0) sign = 1; 
      else if ((rand() & 32767) > 16383) sign = -1; 
      else sign = 1; 
      delta = (INT32) sign * amount * (rand() & 32767) / 32768; 
      if (value >= size) value = value - delta; 
      else if (value < -size) value = value + delta; 
#ifdef SYMMETRIC 
      if (((UNIT *) w->backunit)->unitnumber != u->unitnumber && 
         w->next != NULL) 
         *(w->weight) = value; 
#else 
      w->weight = value; 
#endif 
      w = w->next; 
     } 
    u = u->next; 
   } 
  layer = layer->next; 
 }  
} 
 
void oneset() /* go through the patterns once and update weights */ 
{ int i; 
  LAYER *layer; 
  register UNIT *u; 
  register WTNODE *w; 
  short numbernotclose; 
 
 layer = last;      /* make all w->totals = 0 */ 
 while (layer->backlayer != NULL) 
  { 
   u = (UNIT *) layer->units; 
   while (u != NULL) 
    { 
     w = (WTNODE *) u->wtlist; 
     while (w != NULL) 
      { 
#ifdef SYMMETRIC 
       *(w->total) = 0; 
#else 
       w->total = 0; 
#endif 
       w = w->next; 
      }; 
     u = u->next; 
    }; 
   layer = layer->backlayer; 
  }; 
 wrong = s[TOL][TRAIN].npats; 
 s[MAX][TRAIN].right = 0; 
 s[MAX][TRAIN].wrong = 0; 
 resetpats(TRAIN); 
 for(i=1;i<=s[TOL][TRAIN].npats;i++) 
  { 
   nextpat(TRAIN); 
   setonepat(TRAIN); 
   forward(); 
   if (update == 'c') numbernotclose = cbackoutput(); 
   else numbernotclose = backoutput(); 
   if (numbernotclose != 0) 
    { 
     if (probtype == 'c') maxerrors(); 
#ifndef SYMMETRIC 
     if (update == 'c') cbackinner(); else backinner(); 
#endif 
    } 
   else /* this one pattern has been learned */ 
    { 
     if (probtype == 'c') s[MAX][TRAIN].right++; 
     wrong = wrong - 1; 
#ifndef SYMMETRIC 
     if (update == 'c') cbackinner(); else backinner(); 
#endif 
    } 
 if (update == 'C' || update == 't' || update == 'T') 
  { 
   if (update == 'C') periodic_update(); 
   else tdupdate(0,0.0); 
   layer = last;      /* make all w->totals = 0 */ 
   while (layer->backlayer != NULL) 
    { 
     u = (UNIT *) layer->units; 
     while (u != NULL) 
      { 
       w = (WTNODE *) u->wtlist; 
       while (w != NULL) 
        { 
#ifdef SYMMETRIC 
         *(w->total) = 0; 
#else 
         w->total = 0; 
#endif 
         w = w->next; 
        }; 
       u = u->next; 
      }; 
     layer = layer->backlayer; 
    }; /* end while */ 
  };  /* end if update == 'C'*/ 
}; /* end for i */ 
if (update == 'C' || update == 'c' || update == 't' || update == 'T') 
 { 
  totaliter = totaliter + 1; 
  if (up_to_date_stats == '+') 
   { 
    eval(TRAIN,0); 
    wrong = s[TOL][TRAIN].wrong; 
   } 
  else 
   { 
    stats(); 
   }; 
  return; 
 }; 
if (up_to_date_stats == '-') stats(); 
if (wrong == 0) return; 
if (s[TOL][TRAIN].avgerr < toloverall) return; 
if (update == 'q') qp_update(); 
else if (update == 'd') dbd_update(); 
else if (update == 'p') periodic_update(); 
totaliter = totaliter + 1; 
if (up_to_date_stats == '+') 
 { 
  eval(TRAIN,0); 
  wrong = s[TOL][TRAIN].wrong; 
 }; 
} 
 
void initialize_etas(thevalue) 
WTTYPE thevalue; 
{ 
LAYER *p; 
UNIT *u; 
WTNODE *w; 
 
p = start->next; 
while (p != NULL) 
 { 
  u = (UNIT *) p->units; 
  while (u != NULL) 
   { 
    w = (WTNODE *) u->wtlist; 
    while (w != NULL) 
     { 
#ifdef SYMMETRIC 
      *(w->eta) = thevalue; 
#else 
      w->eta = thevalue; 
#endif 
      w = w->next; 
     } 
    u = u->next; 
   } 
  p = p->next; 
 } 
} 
 
int run(n,prpatsrate) 
int n;            /* the number of iterations to run */ 
int prpatsrate;   /* rate at which to print output patterns */ 
{ 
int i, wtlimitbefore; 
 
if (runningflag == '+') {if (pg(stdout,"running . . .\n")) return(1);}; 
if (totaliter == 0) 
 { 
  if (update == 'd') initialize_etas(dbdeta); 
  eval(TRAIN,0); 
  minimumsofar = MAXINT; 
 }; 
for (i=1;i<=n;i++) 
 { 
  totaldiff = 0; 
#ifdef INTEGER 
  wtlimitbefore = wtlimithit; 
#endif 
  if (recurinit == '+') initnet(); 
  oneset(); 
/*  if (up_to_date_stats == '-') stats(); why is this here? */ 
  if (wrong == 0) s[TOL][TRAIN].off = 0; 
  if (totaliter % saverate == 0) saveweights(); 
#ifdef INTEGER 
  if (wtlimitbefore == 0 && wtlimithit == 1) 
   { 
    sprintf(outstr,">>>>> WEIGHT LIMIT HIT <<<<< at %d\n",totaliter); 
    if (pg(stdout,outstr)) return(1); 
   }; 
#endif 
  if ((i % prpatsrate == 0) || (i == n) || (wrong == 0) || 
      (s[TOL][TRAIN].avgerr < toloverall)) 
   { 
    if (summary == '+') if (compactstats(s,0)) return(1); 
   }; 
  if (s[TOL][TRAIN].avgerr < toloverall) return(0); 
  if (s[TOL][TRAIN].wrong == 0) return(0); 
#ifndef UNIX 
  if (kbhit() && getch() == 27 /* escape key */) return(1); 
#endif 
 }; 
return(0); 
}