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);
}