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


/* ************************************************** */ 
/* file bp.c:  contains the main program and network  */ 
/*             creation routines.                     */ 
/*                                                    */ 
/* Copyright (c) 1990-96 by Donald R. Tveter          */ 
/*                                                    */ 
/* ************************************************** */ 
 
#ifdef INTEGER 
#include "ibp.h" 
#else 
#include "rbp.h" 
#endif 
 
/* built-in C functions */ 
 
extern int rand(); 
extern void srand(); 
 
#ifdef INTEGER 
extern int scale(); 
extern REAL unscale(); 
#endif 
 
extern WTTYPE rdr(); 
extern int pg(), printoutunits(), readch(), readint(), eval(); 
extern int readpats(), evalone(), printstats(), popfile(), pushfile(); 
extern REAL readreal(); 
extern char *readstr(); 
extern int loadpat(), run(); 
extern void menus(), texterror(), help(), restoreweights(); 
extern void saveweights(), parameters(), printweights(); 
 
char sysstr[129];     /* string passed to OS with ! command */ 
 
int bufferend;        /* index of last character in input line */ 
int bufferptr;        /* position of next character in buffer */ 
char buffer[BUFFSIZE];/* holds contents of one input line */ 
char trfiles[RXSTRSIZE];/* data file name(s) */ 
int ch;               /* general purpose character variable */ 
FILE *copy;           /* file pointer to copy file */ 
char copyflag;        /* + for copying, - for no copy */ 
int copyfilecount;    /* to number the copy files */ 
jmp_buf cmdloopstate; /* to save state in case of a SIGINT */ 
FILE *data;           /* file for original data */ 
char *datafile;       /* copy of the data file name saved here */ 
 
WTTYPE dbdeta;        /* the initial eta value for the DBD method */ 
WTTYPE kappa;         /* the DBD learning parameter */ 
WTTYPE decay;         /* the decay parameter for the DBD method */ 
WTTYPE etamax;        /* the maximum eta for the DBD method */ 
WTTYPE theta1;        /* the DBD parameter */ 
WTTYPE theta2;        /* 1 - theta1 */ 
WTTYPE noise;         /* noise parameter for dbd */ 
 
char deriv;           /* flags type of derivative to use */ 
char echo;            /* controls echoing of characters during input */ 
char emptystring;     /* for unused string values */ 
 
WTTYPE eta;           /* basic learning rate */ 
WTTYPE eta2;          /* learning rate for lower layers */ 
WTTYPE alpha;         /* momentum term */ 
 
char recurinit;       /* intialize input and output at start of training */ 
int extraconnect;     /* flags the use of connections between */ 
                      /* non-adjacent layers */ 
char *inputfile;      /* name of file to take extra commands from */ 
FILE *filestack[MAXFILES];  /* allows for nested reads from files */ 
int filetimes[MAXFILES];    /* number of times to read file */ 
int filestackptr;     /* has the index of the current file */ 
int format[MAXFORMAT];/* each value in format indicates where to put */ 
                      /* a blank for compressed output mode or a */ 
                      /* carriage return for real output */ 
int timestoread;      /* number of times to read an input file */ 
char incrementseed;   /* + advances seed, - resets to first value */ 
char informat;        /* controls format to read numbers */ 
WTTYPE initrange;     /* initial range of random weights */ 
WTTYPE kicksize;      /* the minimum size weights that are affected */ 
WTTYPE kickrange;     /* the range weights are initialized to */ 
char wtinitroutine;   /* flags weight initialization algorithm */ 
 
long iotime;          /* time used up printing */ 
short nlayers;        /* number of layers in network */ 
int ioconnects;       /* flags existence of input/output connections */ 
int originallypcc;    /* saves kind of net to start with */ 
 
LAYER *last;          /* has address of the output layer */ 
LAYER *start;         /* has address of the input layer */ 
int stmsize;          /* number of h layer units in a recurrent net */ 
 
int lastadd;          /* iteration where last node was added */ 
REAL lastadderr;      /* error at the last hidden unit addition */ 
int lastprint;        /* last iteration pattern responses printed */ 
int lastsave;         /* last time weights were saved */ 
int lineno;           /* counts lines for paging */ 
int maxhidden;        /* maximum number of hidden units allowed */ 
int maxiter;          /* maximum iterations when not benchmarking */ 
char netbuild;        /* the type of net to build */ 
char offby1;          /* + means out of date stats for training set */ 
char outformat;       /* controls format to print output */ 
char outstr[OUTSTRSIZE]; /* the output string */ 
int pagesize;         /* size of page for pg */ 
char runningflag;     /* +/- to print the "running . . ." message */ 
REAL pasterror;       /* error from window iterations ago */ 
int pccnet;           /* flags pseudo-cascade-correlation net */ 
char probtype;        /* flags general or classification pattern format */ 
char debugoutput;     /* turns on any debugging code I need */ 
int prevnpats;        /* previous number of patterns, initially 0 */ 
int printrate;        /* printrate when not benchmarking */ 
WTTYPE unknown;       /* value for x in compressed input */ 
 
REAL qpdecayh;        /* the quickprop weight decay hidden layer */ 
REAL qpdecayo;        /* the quickprop weight decay output layer */ 
WTTYPE qpeta;         /* the quickprop eta */ 
WTTYPE qpnoise;       /* quickprop noise (integer version only) */ 
WTTYPE mu;            /* the quickprop acceleration factor */ 
char qpslope;         /* flags using slope in quickprop all the time */ 
 
int readerror;        /* flags an error in reading a value */ 
int readingpattern;   /* flags reading pattern state */ 
WTTYPE classoff;      /* target value for class off value */ 
WTTYPE classon;       /* target value for class on value */ 
char ringbell;        /* flag to ring bell when finished */ 
int right;            /* number of training patterns learned */ 
DATA s[2][2];         /* contains stats on pattern learning */ 
DATA rs[2][2];        /* stats on recurrent pattern learning */ 
int saverate;         /* rate at which to save weights */ 
char saveonminimum;   /* flags saving weights on minimum of test set */ 
REAL minimumsofar;    /* lowest test set error so far */ 
unsigned seed;        /* seed for generating random weights */ 
SEEDNODE *seedstart;  /* the list of user defined seeds */ 
#ifdef LOOKUP 
WTTYPE sigmoid[7808]; /* table to look up the sigmoid's value */ 
#endif 
 
WTTYPE stdthresh;     /* the bias WEIGHT value */ 
WTTYPE hbiasact;      /* hidden layer bias activation VALUE */ 
WTTYPE obiasact;      /* output layer bias activation VALUE */ 
char biasset;         /* flags the setting of the bias WEIGHT */ 
char summary;         /* flags summary output mode */ 
int testpat;          /* pattern to skip when benchmarking; else 0 */ 
char *testfile;       /* file to take test patterns from */ 
WTTYPE toler;         /* tolerance based on targets */ 
REAL toloverall;      /* tolerance based on average error */ 
WTTYPE toosmall;      /* weights smaller than toosmall were removed */ 
#ifdef INTEGER 
INT32 totaldiff;      /* totals errors to find average error per unit */ 
#else 
REAL totaldiff; 
#endif 
int totaliter;        /* counts total iterations for the program */ 
char *trainfile;      /* file to take training patterns from */ 
REAL trigger;         /* trigger slope for dynamic node creation */ 
char update;          /* flags type of update rule to use */ 
char up_to_date_stats;/* + does an extra forward pass after update */ 
int window;           /* window over which trigger slope is computer */ 
int wrong;            /* number of training patterns unlearned */ 
char wtfilename[FILENAMESIZE]="weights"; /* whole name for weight file */ 
char *wtfile;         /* base file name for weights file */ 
int wtfilecount;      /* counts weight files as they are written */ 
char wtformat;        /* controls format to save and restore weights */ 
#ifdef INTEGER 
char wtlimithit;      /* flags whether the limit has been hit */ 
#endif 
int wttotal;          /* number of weights in the network */ 
int wtsinuse;         /* number of weights in use */ 
char zeroderiv;       /* flags zero deriviative when using A ap */ 
 
char ah;              /* hidden layer activation function */ 
char ao;              /* output layer activation function */ 
WTTYPE Dh;            /* hidden layer D */ 
WTTYPE Do;            /* output layer D */ 
 
REAL poft;            /* temporal difference previous value */ 
 
/* given a layer no. and unit no. locateunit returns the address */ 
UNIT *locateunit(layerno,unitno) 
int layerno, unitno; 
{int i; 
 UNIT *u; 
 LAYER *layer; 
  
if (layerno < 0 || layerno > nlayers) 
 { 
  pg(stdout,"bad layer number\n"); 
  return(NULL); 
 }; 
layer = start; 
for(i=1;i<=(layerno-1);i++) layer = layer->next; 
u = (UNIT *) layer->units; 
while (u != NULL && u->unitnumber != unitno) u = u->next; 
if (u == NULL) 
 { 
  sprintf(outstr,"there is no unit %3d in layer %3d\n",unitno,layerno); 
  pg(stdout,outstr); 
 }; 
return(u);      
} 
 
#ifdef SYMMETRIC 
 
INT32 wtaddress(i,j,biasunit,type,size) /* Returns the address of a */ 
int i,j;                                /* weight (1), olddw (2),   */ 
int biasunit;                           /* eta (3), total (4),      */ 
int type;                               /* or slope (5)             */ 
int size;                               /* One is created if it     */ 
                                        /* doesn't already exist.   */ 
{ int k; 
  INT32 addr; 
  UNIT *u; 
  WTNODE *w; 
 
if (biasunit) addr = (INT32) malloc(size); 
else if (j >= i) addr = (INT32) malloc(size); 
else /* the item already exists, so find its address */ 
 { 
  u = locateunit(2,j); 
  w = (WTNODE *) u->wtlist; 
  k = 1; 
  while (k < i) 
   { 
    w = w->next; 
    k = k + 1; 
   }; 
  if (type == 1) addr = (INT32) w->weight; 
  else if (type == 2) addr = (INT32) w->olddw; 
  else if (type == 3) addr = (INT32) w->eta; 
  else if (type == 4) addr = (INT32) w->total; 
  else if (type == 5) addr = (INT32) w->slope; 
  else pg(stdout,"bad type in wtaddress\n"); 
 }; 
return(addr); 
} 
 
void setweight(w,i,j,biasunit) /* set initial values in w */ 
WTNODE *w; 
short i, j; 
int biasunit; 
{WTTYPE *s; 
 
s = (WTTYPE *) wtaddress(i,j,biasunit,1,WTSIZE); 
*s = 0; 
w->weight = s; 
s = (WTTYPE *) wtaddress(i,j,biasunit,2,WTSIZE); 
*s = 0; 
w->olddw = s; 
s = (WTTYPE *) wtaddress(i,j,biasunit,3,WTSIZE); 
*s = eta; 
w->eta = s; 
s = (WTTYPE *) wtaddress(i,j,biasunit,5,WTSIZE); 
*s = 0; 
w->slope = s; 
w->inuse = 1; 
#ifdef INTEGER 
w->total = (INT32 *) wtaddress(i,j,biasunit,4,sizeof(INT32)); 
#else 
w->total = (REAL *) wtaddress(i,j,biasunit,4,sizeof(REAL)); 
#endif 
} 
 
#else 
 
void setweight(w,i,j,biasunit) /* set initial values in w */ 
WTNODE *w; 
short i,j; 
int biasunit; 
{ 
w->weight = 0; 
w->olddw = 0; 
w->slope = 0; 
w->eta = dbdeta; 
if (biasunit) w->inuse = 2; else w->inuse = 1; 
} 
 
#endif 
 
LAYER *mklayer(prevlayer,n)  /* creates a layer of n units, pointers */ 
LAYER *prevlayer;            /* and weights back to the units in the */ 
int n;                       /* previous layer and links this new */ 
                             /* layer into the list of layers */ 
{UNIT *front, *p, *q, *bias, *prev, *ptr; 
 WTNODE *wfront, *wprev, *w; 
 LAYER *lptr; 
 int i, j, count; 
 
/* make a list of nodes in this layer */ 
 
count = 1; 
front = (UNIT *) malloc(sizeof(UNIT)); 
front->unitnumber = count; 
front->layernumber = nlayers; 
front->oj = 0; 
front->tj = 0; 
front->translate = 0; 
front->userscale = scale(1.0); 
front->wtlist = NULL; 
prev = front; 
for(i=1;inext = ptr; 
  ptr->unitnumber = count; 
  ptr->layernumber = nlayers; 
  ptr->wtlist = NULL; 
  ptr->translate = 0; 
  ptr->userscale = scale(1.0); 
  front->oj = 0; 
  front->tj = 0; 
  prev = ptr; 
 }; 
prev->next = NULL; 
 
/* make a LAYER node to point to this list of units */ 
 
lptr = (LAYER *) malloc(sizeof(LAYER)); 
lptr->unitcount = n; 
lptr->initialcount = n; 
lptr->D = scale(1.0); 
lptr->biasact = scale(1.0); 
lptr->patstart[TRAIN] = NULL; 
lptr->currentpat[TRAIN] = NULL; 
lptr->patstart[TEST] = NULL; 
lptr->currentpat[TEST] = NULL; 
lptr->backlayer = prevlayer; 
lptr->next = NULL; 
lptr->units = front;   /* connect the list of units */ 
 
/* return if this is the input layer */ 
 
if (prevlayer == NULL) return(lptr); 
prevlayer->next = lptr; 
 
/* If we are working on a deeper layer, for every node in this layer, */ 
/* create a linked list back to units in the previous layer. */ 
 
i = 1; 
q = front; 
while (q != NULL) /* do a unit */ 
 {     
  j = 1;            /* handle first connection */ 
  p = (UNIT *) prevlayer->units; 
  wfront = (WTNODE *) malloc(sizeof(WTNODE)); 
  wttotal = wttotal + 1; 
  q->wtlist = wfront; 
  wprev = wfront; 
  wfront->backunit = p; 
  setweight(wfront,i,j,0); 
  p = p->next; 
  while (p != NULL) /* handle rest of connections */ 
   { 
    j = j + 1; 
    w = (WTNODE *) malloc(sizeof(WTNODE)); 
    wttotal = wttotal + 1; 
    wprev->next = w; 
    w->backunit = p; 
    setweight(w,i,j,0); 
    wprev = w; 
    p = p->next; 
   }; 
  j = j + 1; 
  bias = (UNIT *) malloc(sizeof(UNIT));   /* create a bias unit */ 
  bias->oj = scale(1.0); 
  bias->inuse = 1; 
  bias->layernumber = nlayers; 
  bias->unitnumber = 32767;           /* bias unit is unit 32767 */ 
  w = (WTNODE *) malloc(sizeof(WTNODE)); /* connect to end of list */ 
  wttotal = wttotal + 1; 
  wprev->next = w; 
  w->backunit = bias; 
  setweight(w,n+2,i,1); 
  w->next = NULL; 
  q = q->next; 
  i = i + 1; 
 }; 
return(lptr); 
} 
 
#ifndef SYMMETRIC 
 
void connect(a,b,range)  /* add a connection from unit a to unit b */ 
UNIT *a, *b;             /* connections go in increasing order */ 
WTTYPE range; 
 
{WTNODE *wnew, *w, *wprev; 
 UNIT *wunit; 
 int farenough; 
 
wnew = (WTNODE *) malloc(sizeof(WTNODE)); 
wttotal = wttotal + 1; 
wnew->eta = dbdeta; 
wnew->weight = range * (rand() & 32767) / 32768; 
if ((rand() & 32767) > 16383) wnew->weight = -wnew->weight; 
wnew->olddw = 0; 
wnew->slope = 0; 
wnew->inuse = 1; 
wnew->backunit = a; 
w = (WTNODE *) b->wtlist; 
wprev = NULL; 
wunit = (UNIT *) w->backunit; 
farenough = 0;                  /* insert the weight in order */ 
while (w != NULL && !farenough) 
 if (wunit->layernumber > a->layernumber) farenough = 1; 
 else if (wunit->layernumber == a->layernumber) 
  while (w != NULL && !farenough) 
   { 
    if (wunit->unitnumber < a->unitnumber && 
        wunit->layernumber == a->layernumber) 
     { 
      wprev = w; 
      w = w->next; 
      wunit = (UNIT *) w->backunit; 
     } 
    else farenough = 1; 
   } 
  else 
   { 
    wprev = w; 
    w = w->next; 
    wunit = (UNIT *) w->backunit; 
   }; 
if (wprev == NULL) 
 { 
  wnew->next = w; 
  b->wtlist = wnew; 
 } 
else 
 { 
  wnew->next = w; 
  wprev->next = wnew; 
 }; 
} 
 
void addunit(layerno,range) 
int layerno;  /* add hidden unit to end of the layer */ 
WTTYPE range; 
{ 
 LAYER *lptr, *prevlayer, *nextlayer; 
 UNIT *u, *prevu, *p, *bias; 
 WTNODE *wnode; 
 int i, unitno; 
 
lptr = start; 
for (i=1;i <= (layerno - 1); i++) lptr = lptr->next; 
unitno = lptr->unitcount; 
lptr->unitcount = unitno + 1; 
prevu = locateunit(layerno,unitno); 
if (prevu == NULL) return; 
u = (UNIT *) malloc(sizeof(UNIT)); 
prevu->next = u; 
u->next = NULL; 
u->unitnumber = unitno + 1; 
u->layernumber = layerno; 
u->inuse = 1; 
u->wtlist = NULL; 
if (layerno > 1) 
 { 
  bias = (UNIT *) malloc(sizeof(UNIT)); 
  bias->inuse = 1; 
  bias->oj = scale(1.0); 
  bias->layernumber = layerno; 
  bias->unitnumber = 32767;           /* bias unit is unit 32767 */ 
  wnode = (WTNODE *) malloc(sizeof(WTNODE)); 
  wttotal = wttotal + 1; 
  wnode->weight = range * (rand() & 32767) / 32768; 
  if ((rand() & 32767) > 16383) wnode->weight = -wnode->weight; 
  wnode->olddw = 0; 
  wnode->slope = 0; 
  wnode->eta = dbdeta; 
  wnode->inuse = 2; 
  wnode->next = NULL; 
  wnode->backunit = bias; 
  u->wtlist = wnode; 
  prevlayer = lptr->backlayer; 
  p = (UNIT *) prevlayer->units; 
  while (p != NULL) 
   { 
    connect(p,u,range); 
    p = p->next; 
   }; 
 }; 
nextlayer = lptr->next; 
p = (UNIT *) nextlayer->units; 
while (p != NULL) 
 { 
  connect(u,p,range); 
  p = p->next; 
 }; 
lastadd = totaliter; 
lastadderr = s[TOL][TRAIN].avgerr; 
}       
 
#endif 
 
void init() 
{int i,j; 
 SEEDNODE *snode; 
 
poft = scale(0.0);     /* part of a temporal difference test */ 
 
alpha = scale(0.9);    /* gradient descent parameters */ 
eta = scale(0.5); 
eta2 = eta; 
 
decay = scale(0.5);    /* DBD parameters */ 
dbdeta = scale(0.5); 
etamax = scale(30.0); 
kappa = scale(0.5); 
theta1 = scale(0.5); 
theta2 = scale(1.0) - theta1; 
 
mu = scale(1.75);      /* quickprop parameters */ 
qpdecayh = 0; 
qpdecayo = 0; 
qpeta = scale(0.5); 
qpnoise = 0; 
qpslope = '+'; 
 
classoff = 0; 
classon = scale(1.0); 
debugoutput = '-'; 
inputfile = "(none)"; 
bufferend = 0; 
bufferptr = BUFFSIZE + 1; 
ch = ' '; 
copyflag = '-'; 
copyfilecount = 0; 
deriv = 'd'; 
echo = '-'; 
 
extraconnect = 0; 
format[0] = 0; 
for(i=1;i<=MAXFORMAT-1;i++) format[i] = format[i-1] + 10; 
incrementseed = '-'; 
informat = 'r'; 
initrange = scale(1.0); 
kickrange = 0; 
kicksize = 0; 
wtinitroutine = '0'; 
lastadd = 0; 
lastprint = 0; 
lastsave = 0; 
probtype = 'g'; 
noise = 0; 
offby1 = '-'; 
outformat = 'r'; 
pagesize = 24; 
pccnet = 0; 
ioconnects = 0; 
stmsize = 0; 
recurinit = '-'; 
prevnpats = 0; 
printrate = 10; 
 
ringbell = '-'; 
saverate = MAXINT; 
minimumsofar = MAXINT; 
saveonminimum = '-'; 
seedstart = (SEEDNODE *) malloc(sizeof(SEEDNODE)); 
snode = (SEEDNODE *) malloc(sizeof(SEEDNODE)); 
seedstart->next = snode; 
snode->val = 0; 
srand(0); 
snode->next = NULL; 
#ifdef LOOKUP 
{ 
 int i; double x,y; 
 for (i=0;i<=7807;i++) 
  { 
   x = (double) i / 1024.0; 
   y = 1.0 / (1.0 + exp(-x)); 
   sigmoid[i] = (WTTYPE) (y * 1024.0 + 0.5); 
  }; 
} 
#endif 
 
for (i=TRAIN;i<=TEST;i++) for (j=TOL;j<=MAX;j++) 
 { 
  s[j][i].uncertain = 0; 
  s[j][i].npats = 0; 
  s[j][i].iterno = 0; 
  s[j][i].right = 0; 
  s[j][i].wrong = 0; 
  s[j][i].avgerr = 0.0; 
  s[j][i].pctright = 0.0; 
 }; 
stdthresh = 0; 
biasset = 0; 
sysstr[0] = '\0'; 
summary = '+'; 
timestoread = 1; 
toler = scale(0.1); 
toloverall = 0.0; 
toosmall = 0;            /* size of weights too small to use */ 
trigger = 0.1; 
unknown = scale(0.5); 
update = 'p'; 
up_to_date_stats = '-'; 
wtfilecount = 0; 
wtfile = "weights"; 
trfiles[0] = '\0'; 
runningflag = '+'; 
wtformat = 'r'; 
#ifdef INTEGER 
wtlimithit = 0; 
#endif 
wttotal = 0; 
zeroderiv = 0; 
maxiter = 100; 
 
ah = 's'; 
ao = 's'; 
hbiasact = scale(1.0); 
obiasact = scale(1.0); 
Dh = scale(1.0); 
Do = scale(1.0); 
} 
 
int nonetwork() 
{ 
if (start != NULL) return(0); 
pg(stdout,"there is no network\n"); 
return(1); 
} 
 
int nopatterns() 
{ 
if (s[TOL][TRAIN].npats != 0) return(0); 
pg(stdout,"there are no patterns\n"); 
return(1); 
} 
 
void setbiasact(layer) /* sets the bias unit ACTIVATION VALUE */ 
LAYER *layer; 
{ 
 UNIT *u; 
 WTNODE *w; 
  
 u = layer->units; 
 while (u != NULL) 
  { 
   w = u->wtlist; 
   while (w != NULL) 
    { 
     if (w->backunit->unitnumber == 32767) 
        w->backunit->oj = layer->biasact; 
     w = w->next; 
    }; 
   u = u->next; 
  }; 
} 
 
int patternencode(list) /* finds addresses of pattern values found */ 
int list;               /* within the net */ 
{ 
 PATNODE *pn; 
 PATLIST *pl; 
 int i, n, finished; 
 UNIT *u; 
 resetpats(list); 
 pl = start->currentpat[list]; 
 nextpat(list); 
 while (pl != NULL) 
  { 
   pn = pl->pats; 
   n = start->unitcount; 
   i = 1; 
   finished = 0; 
   while (i <= n && !finished) 
    { 
     if (pn->addr != NULL && pn->addr != (WTTYPE *) -1) 
      { 
       u = locateunit((int) pn->layer, (int) pn->unitno); 
       pn->addr = &(u->oj); 
      }; 
     i = i + 1; 
     pn++; 
     if (pn->unitno == CAPXCODE || pn->unitno == CAPHCODE) finished = 1; 
    }; 
   nextpat(list); 
  }; 
} 
 
/* for a SIGINT, restart in cmdloop */ 
#ifdef UNIX 
void restartcmdloop() 
#else 
void restartcmdloop(int dummy) 
#endif 
{ 
while (data != stdin) popfile(); 
signal(SIGINT,restartcmdloop); 
longjmp(cmdloopstate,1); 
} 
  
void cmdloop()    /* read commands and process them */ 
{ 
int finished, layerno, unitno, layer1, layer2, node1, node2; 
int i, itemp, itemp2; 
WTTYPE temp, temp2, *target; 
PATLIST *pl; 
REAL rtemp; 
LAYER *p; 
UNIT *u, *n1, *n2; 
WTNODE *w; 
SEEDNODE *snode, *sprev; 
 
setjmp(cmdloopstate); /* restart here from SIGINT */ 
finished = 0; 
do{ 
   if (data == stdin) pg(stdout,"[ACDFGMNPQTW?!acdefhlmopqrstw]? "); 
   if (data == stdin) lineno = 0; 
   while(ch == ' ' || ch == '\n') ch = readch(); 
   switch (ch) { 
 
case EOF: 
popfile(); 
if (data == stdin) pg(stdout,"taking commands from stdin now\n"); 
break; 
 
case '?': menus('?'); break; 
 
case '!': 
i = 0; 
do ch = readch(); while (ch == ' '); 
if (ch == '\n') 
 { 
  system(sysstr); 
  break; 
 } 
else if (ch == '"') break; /* loading string but not executing */ 
while ((ch != '\n' && ch != '"') && i <= 80) 
 { 
  sysstr[i] = ch; 
  ch = readch(); 
  i = i + 1; 
 }; 
if (ch == '"') sysstr[i-1] = '\0'; 
else 
 { 
  sysstr[i] = '\0'; 
  system(sysstr); 
 }; 
bufferptr = bufferptr - 1; 
break; 
 
case '*': break;  /* * on a line is a comment */ 
 
case 'a': 
do ch = readch(); while (ch == ' '); 
if (ch == '0' || ch == '.') 
 { 
  bufferptr = bufferptr - 1; 
  temp = rdr(GE,0.0,'a'); 
  if (!readerror) alpha = temp; 
  goto enda; 
 } 
else bufferptr = bufferptr - 1; 
if (nonetwork()) goto enda; 
while (ch != '\n' && ch != '*') 
 { 
  ch = readch(); 
  if (ch == 'a') 
   { 
    do ch = readch(); while (ch == ' '); 
    if (ch == 'l' || ch == 's') 
       { 
        p = start; 
        while (p != NULL) {p->activation = ch; p = p->next;}; 
        ah = ch; 
        ao = ch; 
       } 
    else if (ch == 'h') 
     { 
      do ch = readch(); while (ch == ' '); 
      if (ch == 'l' || ch == 's') 
         { 
          p = start; 
          while (p != last) {p->activation = ch; p = p->next;}; 
          ah = ch; 
         } 
      else texterror(); 
     } 
    else if (ch == 'o') 
     { 
      do ch = readch(); while (ch == ' '); 
      if (ch == 'l' || ch == 's') 
         { 
          last->activation = ch; 
          ao = ch; 
         } 
      else texterror(); 
     } 
    else texterror(); 
   } 
  else if (ch == 'D') 
   { 
    do ch = readch(); while (ch == ' '); 
    if (ch == 'h') 
     { 
      temp = rdr(GT,0.0,'a'); 
      if (readerror) goto enda; 
      p = start; 
      while (p != last) {p->D = temp; p = p->next;}; 
      Dh = temp; 
     } 
    else if (ch == 'o') 
     { 
      temp = rdr(GT,0.0,'a'); 
      if (readerror) goto enda; 
      last->D = temp; 
      Do = temp; 
     } 
    else if (ch >= '0' && ch <= '9') 
     { 
      bufferptr = bufferptr - 1; 
      temp = rdr(GT,0.0,'a'); 
      if (readerror) goto enda; 
      p = start; 
      while (p != NULL) {p->D = temp; p = p->next;}; 
      Do = temp; 
      Dh = temp; 
     } 
    else texterror(); 
   } 
  else if (ch == 'd') 
   { 
    do ch = readch(); while (ch == ' '); 
    if (ch == 'd' || ch == 'f' || ch == 'c' || ch == 'o') deriv = ch; 
    else texterror(); 
    if (deriv == 'o') deriv = 'c'; 
   } 
  else if (ch == 'i') 
   { 
    do ch = readch(); while (ch == ' '); 
    if (ch == '+' || ch == '-') recurinit = ch; 
    else texterror(); 
   } 
  else if (ch == 'u') 
   { 
    do ch = readch(); while (ch == ' '); 
    if (ch == 'j') ch = 'd'; 
#ifdef SYMMETRIC 
    if (ch == 'C' || ch == 'c' || ch == 'p') update = ch; 
#else 
    if (ch == 'C' || ch == 'c' || ch == 'p' || ch == 'd' || ch == 'q') 
       update = ch; 
#endif 
    else texterror(); 
   } 
  else if (ch == '*' || ch == '\n' || ch == ' '); 
  else texterror(); 
 } 
bufferptr = bufferptr - 1; 
enda: break; 
 
case 'c': {int initialize; 
if (nonetwork()) goto endc; 
initialize = 0; 
do ch = readch(); while (ch == ' '); 
if (ch == '\n' || ch == '*') goto clearnet; 
else if (ch == 'i') 
 { 
  initialize = 1; 
  do ch = readch(); while (ch == ' '); 
  if (ch == '\n' || ch == '*') goto clearnet; 
  else 
     { 
      bufferptr = bufferptr - 1; 
      temp2 = rdr(GE,scale(0.0),'c'); 
      if (readerror) goto endc; 
      initrange = temp2; 
     }; 
 }; 
 
clearnet: 
clear(); 
srand(seed); 
if (initialize == 1) 
 { 
  kick((WTTYPE) 0,initrange); 
  sprintf(outstr,"seed = %d, range = -%5.2f to +%5.2f\n",seed, 
          unscale(initrange), unscale(initrange)); 
  pg(stdout,outstr); 
 } 
else {sprintf(outstr,"seed = %d\n",seed); pg(stdout,outstr);}; 
endc: break;}; 
 
#ifndef SYMMETRIC 
case 'd': 
while (ch != '\n' && ch != '*') 
 { 
  ch = readch(); 
  if (ch == 'd') 
   { 
    temp = rdr(GT,0.0,'d'); 
    if (!readerror) decay = temp; 
   } 
  else if (ch == 'e') 
   { 
    temp = rdr(GT,0.0,'d'); 
    if (!readerror && !nonetwork()) 
     { 
      dbdeta = temp; 
      initialize_etas(dbdeta); 
     }; 
   } 
  else if (ch == 'k') 
   { 
    temp = rdr(GT,0.0,'d'); 
    if (!readerror) kappa = temp; 
   } 
  else if (ch == 'm') 
   { 
    temp = rdr(GT,0.0,'d'); 
    if (!readerror) etamax = temp; 
   } 
  else if (ch == 't') 
   { 
    temp = rdr(GE,0.0,'d'); 
    if (!readerror) 
     { 
      theta1 = temp; 
      theta2 = scale(1.0) - theta1; 
     }; 
   } 
  else if (ch == '*' || ch == '\n' || ch == ' '); 
  else texterror(); 
 } 
bufferptr = bufferptr - 1; 
break; 
#endif 
 
case 'e': 
temp = rdr(GT,0.0,'e'); 
if (!readerror) eta = temp; 
do ch = readch(); while (ch == ' '); 
bufferptr = bufferptr - 1; 
if (ch != '\n' && ch != '*') 
 { 
  temp = rdr(GT,0.0,'r'); 
  if (!readerror) eta2 = temp; 
 } 
else eta2 = eta; 
break; 
 
case 'f': 
while (ch != '\n' && ch != '*') 
 { 
  ch = readch(); 
  if (ch == 'B') 
   { 
    itemp = 0; 
    do ch = readch(); while (ch == ' '); 
    while (ch >= '1' && ch <= '9') 
     { 
      bufferptr = bufferptr - 1; 
      itemp2 = readint(format[itemp],MAXINT,'f'); 
      if (readerror) goto endf; 
      itemp = itemp + 1; 
      if (itemp < MAXFORMAT) format[itemp] = itemp2; 
      else pg(stdout,"format too long\n"); 
      do ch = readch(); while (ch == ' '); 
     }; 
    if (itemp < MAXFORMAT-1) 
       for (i=itemp+1;i<=MAXFORMAT-1; i++) format[i] = format[i-1] + 10; 
   } 
  else if (ch == 'b') 
   { 
    do ch = readch(); while (ch == ' '); 
    if (ch == '+' || ch == '-') ringbell = ch; else texterror(); 
   } 
  else if (ch == 'c') 
   { 
    do ch = readch(); while (ch == ' '); 
    if (ch == '+') 
     { 
      if (copy != NULL) fflush(copy); 
      else copy = fopen("copy","w"); 
      if (copy == NULL) 
       {sprintf(outstr,"cannot open file:  %s\n",outstr); pg(stdout,outstr); }; 
      copyflag = '+'; 
     } 
    else if (ch == '-') 
     { 
      copyflag = '-'; 
      if (copy != NULL) 
       { 
        fflush(copy); 
        fclose(copy); 
       } 
     } 
    else texterror(); 
   } 
  else if (ch == 'd') 
   {/* with fd+ I can turn on a piece of debugging code (if it exists) */ 
    do ch = readch(); while (ch == ' '); 
    if (ch == '+' || ch == '-') debugoutput = ch; 
    else 
     { 
      texterror(); 
      goto endf; 
     } 
   } 
  else if (ch == 'e') 
   { 
    do ch = readch(); while (ch == ' '); 
    if (ch == '+' || ch == '-') echo = ch; 
   } 
  else if (ch == 'i') 
   { 
    do ch = readch(); while (ch == ' '); 
    if (ch == 'c' || ch == 'r') informat = ch; else texterror(); 
   } 
  else if (ch == 'O') 
   { 
    do ch = readch(); while (ch == ' '); 
    if (ch == '+' || ch == '-') offby1 = ch; 
    else texterror(); 
   } 
  else if (ch == 'o') 
   { 
    do ch = readch(); while (ch == ' '); 
    if (ch == 'a' || ch == 'c' || ch == 'r' || ch == 'e' || ch == 's') 
       outformat = ch; 
    else texterror(); 
   } 
  else if (ch == 'P') 
   { 
    itemp = readint(0,MAXINT,'f'); 
    if (!readerror) pagesize = itemp; 
   } 
  else if (ch == 'p') 
   { 
    do ch = readch(); while (ch == ' '); 
    if (ch == 'c' || ch == 'g') probtype = ch; 
    else texterror(); 
   } 
  else if (ch == 'R') 
   { 
    do ch = readch(); while (ch == ' '); 
    if (ch == '+' || ch == '-') runningflag = ch; 
    else texterror(); 
   } 
  else if (ch == 's') 
   { 
    do ch = readch(); while (ch == ' '); 
    if (ch == '+' || ch == '-') summary = ch; 
    else texterror(); 
   } 
  else if (ch == 'u') 
   { 
    do ch = readch(); while (ch == ' '); 
    if (ch == '+' || ch == '-') up_to_date_stats = ch; else texterror(); 
   } 
  else if (ch == 'x') 
   { 
    temp = rdr(GT,(REAL) SKIPCODE,'f'); 
    if (!readerror) unknown = temp; 
   } 
  else if (ch == ' ' || ch == '*' || ch == '\n'); 
  else texterror(); 
 } 
bufferptr = bufferptr - 1; 
endf: 
break; 
 
case 'h': help(); break; 
 
case 'l': 
if (nonetwork()) break; 
layerno = readint(1,nlayers,'l');  
if (readerror) break; 
p = start; 
for (i=2;i<=layerno;i++) p = p->next; 
printoutunits(0,p,-1,0.0,(char) 0,(char) 0); 
break; 
 
/* make a network */ 
 
case 'm': {LAYER *layer; int itemp, itemp2; 
nlayers = 0; 
wttotal = 0; 
pccnet = 0; 
ioconnects = 0; 
ch = readch(); 
p = NULL; 
while (ch != 'x' && ch != '\n' && ch != '*') 
 { 
  itemp = readint(1,MAXINT,'m'); 
  if (readerror) 
   { 
    wttotal = 0; 
    start = NULL; 
    goto endm; 
   }; 
  /* check for + number for a recurrent net */ 
  if (nlayers == 0) 
   { 
    do ch = readch(); while (ch == ' '); 
    if (ch != '+') 
     { 
      bufferptr = bufferptr - 1; 
      stmsize = 0; 
     } 
    else 
     { 
      itemp2 = readint(1,MAXINT,'m'); 
      if (readerror) 
       { 
        wttotal = 0; 
        start = NULL; 
        goto endm; 
       }; 
      stmsize = itemp2; 
      itemp = itemp + itemp2; 
     }; 
   }; 
  nlayers = nlayers + 1; 
  p = mklayer(p,itemp); 
  if (nlayers == 1) start = p; 
  ch = readch(); 
  while (ch == ' ') ch = readch(); 
  if (ch >= '0' && ch <= '9') bufferptr = bufferptr - 1; 
 }; 
last = p; 
 
#ifndef SYMMETRIC 
 
if (ch == 'x') 
 { 
  n1 = start->units; 
  while (n1 != NULL) 
   { 
    n2 = last->units; 
    while (n2 != NULL) 
     { 
      connect(n1,n2,(WTTYPE) 0); 
      n2 = n2->next; 
     }; 
    n1 = n1->next; 
   } 
  ioconnects = 1; 
 }; 
 
#endif 
 
wtsinuse = wttotal; 
bufferptr = bufferptr - 1; 
nullpatterns(TRAIN); 
nullpatterns(TEST); 
/* should really free up the old network structure as well */ 
last->activation = ao; 
last->D = Do; 
layer = last->backlayer; 
while (layer != start) 
 { 
  layer->D = Dh; 
  layer->activation = ah; 
  layer = layer->backlayer; 
 }; 
clear(); 
endm: break;}; 
 
case 'o': 
do ch = readch(); while (ch == ' '); 
 { 
  PATNODE *targetpn; 
  bufferptr = bufferptr - 1; /* unget the character */ 
  if (nonetwork() || nopatterns()) break; 
  itemp = readint(1,s[TOL][TRAIN].npats,'o'); 
  if (readerror) break; 
  resetpats(TRAIN); 
  for (i=1;i<=itemp;i++) nextpat(TRAIN); 
  /* setoutputpat(); */ 
  u = (UNIT *) last->units; 
  pl = last->currentpat[TRAIN]; 
  targetpn = pl->pats; 
  itemp2 = 0; /* unit counter */ 
  i = 1;      /* format counter */ 
  while (u != NULL) 
   { 
    sprintf(outstr,"%5.2f",unscale(targetpn->val)); pg(stdout,outstr); 
    targetpn++; 
    itemp2 = itemp2 + 1; 
    if (format[i] == itemp2) 
     { 
      if (outformat == 'r') pg(stdout,"\n"); else pg(stdout," "); 
      if (i < MAXFORMAT - 1) i = i + 1; 
     }; 
    u = u->next; 
   } 
  pg(stdout,"\n"); 
 }; 
endo: 
break; 
 
case 'p': 
do ch = readch(); while (ch == ' '); 
bufferptr = bufferptr - 1; 
if (ch == 'a' || ch == '\n' || ch == '*') 
 {int stopprinting; 
  if (nonetwork() || nopatterns()) break; 
  stopprinting = eval(TRAIN,1); 
  if (!stopprinting) printstats(stdout,TRAIN,0,s); 
 } 
else 
 { 
  itemp = readint(0,s[TOL][TRAIN].npats,'p'); 
  if (readerror) break; 
  if (nonetwork() || nopatterns()) break; 
  if (itemp == 0) {eval(TRAIN,0); printstats(stdout,TRAIN,0,s);} 
  else evalone(itemp,TRAIN,1,0); 
 }; 
break; 
 
case '.': 
case '0': 
case '1': 
case '2': 
case '3': 
case '4': 
case '5': 
case '6': 
case '7': 
case '8': 
case '9': 
case 'x': 
case '-': 
case '\\': {int status; 
if (nonetwork()) break; 
if (ch != '\\') bufferptr = bufferptr - 1; 
status = loadpat(); 
if (status == 1) printoutunits(0,last,-1,0.0,(char) 0,(char) 0); 
break;} 
 
case 'q': 
ch = readch(); 
if (ch == '\n') return; 
#ifndef SYMMETRIC 
else if (ch != 'p') texterror(); 
else 
 { 
  while (ch != '\n' && ch != '*') 
   { 
    ch = readch(); 
    if (ch == 'd') 
     {REAL rtemp; 
      do ch = readch(); while (ch == ' '); 
      if (ch == 'h') 
       { 
        rtemp = readreal(GE,0.0,'q'); 
        if (readerror) goto endq; 
        qpdecayh = rtemp; 
       } 
      else if (ch == 'o') 
       { 
        rtemp = readreal(GE,0.0,'q'); 
        if (readerror) goto endq; 
        qpdecayo = rtemp; 
       } 
      else if (ch >= '0' && ch <= '9') 
       { 
        bufferptr = bufferptr - 1; 
        rtemp = readreal(GE,0.0,'q'); 
        if (readerror) goto endq; 
        qpdecayh = rtemp; 
        qpdecayo = rtemp; 
       } 
     } 
    else if (ch == 'e') 
     { 
      temp = rdr(GT,0.0,'d'); 
      if (!readerror && !nonetwork()) qpeta = temp; 
     } 
    else if (ch == 'm') 
     { 
      temp = rdr(GT,0.0,'d'); 
      if (!readerror) mu = temp; 
     } 
    else if (ch == 'n') 
     { 
      temp = rdr(GE,0.0,'d'); 
      if (!readerror) qpnoise = temp; 
     } 
    else if (ch == 's') 
     { 
      do (ch = readch()); while (ch == ' '); 
      if (ch == '+' || ch == '-') qpslope = ch; 
      else texterror(); 
     } 
    else if (ch == '*' || ch == '\n' || ch == ' '); 
    else texterror(); 
   } 
  }; 
endq: 
bufferptr = bufferptr - 1; 
break; 
#endif 
 
case 'r': /* r for run, rw for restore weights */ 
do ch = readch(); while (ch == ' '); 
if (ch == '\n' || ch == '*') 
 { 
  if (nonetwork() || nopatterns()) goto endr; 
  run(maxiter,printrate); 
 } 
else if (ch == 'w') 
 { 
  do ch = readch(); while (ch == ' '); 
  bufferptr = bufferptr - 1; 
  if (ch == '*' || ch == '\n') /* nothing */ ; 
  else 
   { 
    wtfile = readstr(); 
    strcpy(wtfilename,wtfile); 
    if (saveonminimum == '+') 
     {int i, ok, temp; 
      i = 0; 
      while (wtfile[i] != '\0') i = i + 1; 
      while (wtfile[i] != '.') i = i - 1; 
      wtfile[i] = '\0'; 
      ok = sscanf(&wtfilename[i+1],"%d",&temp); 
      if (ok == 1) wtfilecount = temp; 
      else 
       { 
        wtfilecount = 0; 
        pg(stdout,"weight file number error; number starts a 0\n"); 
       }; 
     }; 
   }; 
  if (nonetwork()) break; else restoreweights(); 
 } 
else if (ch == 't') 
 { 
  do ch = readch(); while (ch == ' '); 
  if (ch == '{') {/* nothing */} 
  else 
   { 
    bufferptr = bufferptr - 1; 
    trainfile = readstr(); 
    itemp = MAXINT; 
    if (!pushfile(trainfile,1)) goto endr; 
    strcat(trfiles,"rt "); 
    strcat(trfiles,trainfile); 
    strcat(trfiles,"\n"); 
   }; 
  nullpatterns(TRAIN); 
  readingpattern = 1; 
  itemp2 = readpats(TRAIN,'r'); 
  readingpattern = 0; 
  s[TOL][TRAIN].npats = itemp2; 
  s[MAX][TRAIN].npats = itemp2; 
  sprintf(outstr,"%d training patterns read\n\n",itemp2); pg(stdout,outstr); 
  goto endr; 
 } 
else if (ch == 'x') 
 { 
  if (nonetwork()) break; 
  trainfile = readstr(); 
  if (!pushfile(trainfile,1)) goto endr; 
  strcat(trfiles,"rx "); 
  strcat(trfiles,trainfile); 
  strcat(trfiles,"\n"); 
  prevnpats = s[TOL][TRAIN].npats; 
  findendofpats(last); 
  findendofpats(start); 
  readingpattern = 1; 
  itemp2 = readpats(TRAIN,'r'); 
  sprintf(outstr,"%d patterns added\n\n",itemp2); pg(stdout,outstr); 
  readingpattern = 0; 
  itemp = prevnpats + itemp2; 
  s[TOL][TRAIN].npats = itemp; 
  s[MAX][TRAIN].npats = itemp; 
  goto endr; 
 } 
else if (ch >= '1' && ch <= '9') 
 { 
  bufferptr = bufferptr - 1; 
  itemp = readint(1,MAXINT,'r');  
  if (!readerror) maxiter = itemp; else goto endr; 
  itemp = readint(1,MAXINT,'r'); 
  if (!readerror) printrate = itemp; else goto endr; 
  do ch = readch(); while (ch == ' '); 
  if (ch == '"') goto endr; else bufferptr = bufferptr - 1; 
  if (!nonetwork() && !nopatterns()) run(maxiter,printrate); 
 } 
else texterror(); 
endr: 
break; 
 
case 's':  /* s  for seed, sw  for save weights */ 
do ch = readch(); while (ch == ' '); 
if (ch == 'w') 
 { 
  do ch = readch(); while (ch == ' '); 
  bufferptr = bufferptr - 1; 
  if (ch == '*' || ch == '\n') /* nothing */ ; else wtfile = readstr(); 
  if (nonetwork()) break; else saveweights(); 
 } 
else if (ch == 'e' || ch == 'a') 
 {char *savefile; 
  FILE *sf; 
  saveweights(); 
  do ch = readch(); while (ch == ' ' || ch == '\n'); 
  bufferptr = bufferptr - 1; 
  savefile = readstr(); 
  sf = fopen(savefile,"w"); 
  if (sf == NULL) 
   { 
    sprintf(outstr,"cannot open the file: %s\n",savefile); 
    goto ends; 
   }; 
  parameters(sf); 
  fflush(sf); 
  fclose(sf); 
 } 
else if (ch == 'i' || (ch >= '0' && ch <= '9')) 
 { 
  bufferptr = bufferptr - 1; 
  sprev = seedstart; 
  while (ch != '\n' && ch != '*') 
   { 
    do ch = readch(); while (ch == ' '); 
    if (ch == 'i') 
     { 
      do ch = readch(); while (ch == ' '); 
      if (ch == '+' || ch == '-') incrementseed = ch; 
      else {texterror(); goto ends;}; 
     } 
    else if (ch >= '0' && ch <= '9') 
     { 
      bufferptr = bufferptr - 1; 
      seed = readint(0,MAXINT,'s'); 
      if (readerror) goto ends; 
      snode = (SEEDNODE *) malloc(sizeof(SEEDNODE)); 
      snode->val = seed; 
      snode->next = NULL; 
      sprev->next = snode; 
      sprev = snode; 
     } 
    else if (ch == '\n' || ch == '*'); 
    else {texterror(); goto ends;}; 
   }; 
  snode = seedstart->next; 
  seed = snode->val; 
 } 
else if (ch == 'b') 
 {WTTYPE temp; LAYER *layer; UNIT *u; 
 if (nonetwork()) break; 
 temp = rdr(GT,(REAL) -unscale(32767),'s'); 
 if (readerror) break; 
 stdthresh = temp; 
 layer = start->next; 
 while (layer != NULL) 
  { 
   u = (UNIT *) layer->units; 
   while (u != NULL) 
    { 
     w = (WTNODE *) u->wtlist; 
     while (w->next != NULL) w = w->next; 
#ifdef SYMMETRIC 
     *(w->weight) = stdthresh; 
#else 
     w->weight = stdthresh; 
#endif 
     u = u->next; 
    }; 
   layer = layer->next; 
  }; 
  biasset = 1; 
 } 
else texterror(); 
ends: 
endsw: 
break; 
 
case 't': 
do ch = readch(); while (ch == ' '); 
if ((ch == 'a' || ch == '\n' || ch == '*') && (!nonetwork())) 
 { 
  if (s[TOL][TEST].npats == 0) pg(stdout,"no test patterns\n"); 
  else 
   { 
    eval(TEST,1); 
    printstats(stdout,TEST,0,s); 
    bufferptr = bufferptr - 1; 
   }; 
 } 
else if (ch == 'o') 
 { 
  rtemp = readreal(GE,0.0,'t'); 
  if (readerror) break; 
  toloverall = rtemp; 
 } 
else if (ch == 'f') 
 { 
  do ch = readch(); while (ch == ' '); 
  bufferptr = bufferptr - 1; 
  testfile = readstr(); 
  nullpatterns(TEST); 
  if (!pushfile(testfile,1)) goto endt; 
  readingpattern = 1; 
  itemp = readpats(TEST,'t'); 
  readingpattern = 0; 
  sprintf(outstr,"%d test patterns read\n",itemp); pg(stdout,outstr); 
  s[TOL][TEST].npats = itemp; 
  s[MAX][TEST].npats = itemp; 
 } 
else if (ch == 'r') 
 { 
  do ch = readch(); while (ch == ' '); 
  if (ch == 'p') itemp2 = 1; 
  else {itemp2 = 0; bufferptr = bufferptr - 1;}; 
  itemp = readint(1,s[TOL][TEST].npats,'t'); 
  if (!readerror) evalr(TEST,itemp2,itemp); 
 } 
else 
 { 
  bufferptr = bufferptr - 1; 
  rtemp = readreal(GE,0.0,'t'); 
  if (readerror) break; 
  else if (rtemp > 0 && rtemp < 1.0) toler = scale(rtemp); 
  else 
   { 
    bufferptr = bufferptr - 1; 
    if (s[TOL][TEST].npats == 0) 
     { 
      pg(stdout,"there is no test set\n"); 
      break; 
     }; 
    if (rtemp == 0.0) {eval(TEST,0); printstats(stdout,TEST,0,s);} 
    else 
     { 
      itemp = rtemp; 
      if (itemp > s[TOL][TEST].npats) 
       pg(stdout,"not that many patterns in the test set\n"); 
      else evalone(itemp,TEST,1,0); 
     }; 
   }; 
 }; 
endt: break; 
 
case 'w': 
{int i; 
 if (nonetwork()) break; 
 layerno = readint(2,nlayers,'w'); 
 if (readerror) break; 
 unitno = readint(1,MAXINT,'w'); 
 if (readerror) break; 
 u = locateunit(layerno,unitno); 
 if (u != NULL) printweights(u,layerno); 
 break; 
}; 
 
case 'g': /* a maze (game) problem for temporal difference */ 
{int ngames, nlevels, ndoors; 
 ngames = readint(1,10,'x'); 
 nlevels = readint(1,10,'x'); 
 ndoors = readint(1,10,'x'); 
 maze(ngames,nlevels,ndoors); 
 ch = ' '; 
 break; 
}; 
 
case 'z': /* reads in non-user set (hidden) parameters */ 
{REAL rtemp; int itemp; 
 rtemp = readreal(GE,0.0,'z'); 
 if (readerror) break; 
 minimumsofar = rtemp;  /* minimum test set error */ 
}; 
break; 
 
default: if (ch >= 'A' && ch <= 'Z') menus(ch); else texterror(); 
break; 
      }; 
    if (ch != '\n') do ch = readch(); while (ch != '\n'); 
  }while (!finished); 
} 
 
void main(argc,argv) 
int argc; 
char *argv[]; 
{ 
setbuf(stdout,NULL);  /* set unbuffered output */ 
#if defined(UNIX) && defined(HOTKEYS) 
initraw(); 
#endif 
lineno = 0; 
pg(stdout,"Basis of AI Backprop (c) 1990-96 by Donald R. Tveter\n"); 
pg(stdout,"   drt@mcs.com - http://www.mcs.com/~drt/home.html\n"); 
pg(stdout,"              April 10, 1996 version.\n"); 
filestackptr = 0; 
filestack[0] = stdin; 
data = stdin; 
emptystring = '\0'; 
trainfile = &emptystring; 
testfile = &emptystring; 
if (argc == 1) 
 { 
  printf("no data file, stdin assumed\n"); 
  datafile = "stdin"; 
 } 
else 
 { 
  datafile = argv[1]; 
  pushfile(datafile,1); 
 }; 
init(); 
signal(SIGINT,restartcmdloop); /* restart from interrupt */ 
cmdloop(); 
if (copy != NULL) 
 { 
  fflush(copy); 
  fclose(copy); 
 } 
}