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


/* ************************************************** */ 
/* file io.c:  contains most input/output functions   */ 
/*                                                    */ 
/* Copyright (c) 1990-96 by Donald R. Tveter          */ 
/*                                                    */ 
/* ************************************************** */ 
 
#ifdef INTEGER 
#include "ibp.h" 
#else 
#include "rbp.h" 
#endif 
 
#if defined(UNIX) && defined(HOTKEYS) 
 
#ifdef BSD 
struct termios raw;    /* characteristics for hotkeys */ 
struct termios noraw;  /* original characteristics */ 
#elif defined NEXT 
struct sgttyb raw;     /* characteristics for hotkeys */ 
struct sgttyb noraw;   /* original characteristics */ 
#else /* the System V solution */ 
struct termio raw;    /* characteristics for hotkeys */ 
struct termio noraw;  /* original characteristics */ 
#endif 
 
char onechar[1];      /* the buffer for the hotkey character */ 
#endif 
 
extern UNIT *locateunit(); 
extern WTTYPE userscaleup(); 
 
extern char buffer[], outstr[], *inputfile, sysstr[]; 
extern char copyflag,deriv,*datafile,echo,informat; 
extern char outformat, probtype, update, *wtfile, wtformat, zeroderiv; 
extern char offby1, ringbell, up_to_date_stats, summary, biasset; 
extern char wtlimithit, runningflag, seednote; 
extern char saveonminimum, wtfilename[], trfiles[]; 
extern char recurinit; 
extern int bufferend, bufferptr, filestackptr, format[]; 
extern int filetimes[], wtfilecount, timestoread, maxiter; 
extern FILE *data, *filestack[]; 
extern LAYER *last, *start; 
extern int extraconnect,ioconnects,lastsave,pagesize,pccnet,prevnpats; 
extern int readerror, readingpattern, totaliter; 
extern int printrate, saverate; 
extern int lineno, stmsize; 
extern long iotime; 
extern short nlayers; 
extern WTTYPE unknown, toler, toosmall, stdthresh; 
extern WTTYPE initrange, kickrange, kicksize; 
extern WTTYPE alpha, eta, eta2; 
extern WTTYPE decay, dbdeta, kappa, etamax, theta1; 
extern WTTYPE qpeta, qpnoise, mu; 
extern WTTYPE classoff, classon; 
extern WTTYPE hbiasact, obiasact; 
extern char qpslope; 
extern FILE *copy; 
extern REAL qpdecayh, qpdecayo; 
extern REAL toloverall, minimumsofar; 
extern DATA s[2][2]; 
extern WTTYPE Dh, Do; 
extern char ah, ao; 
extern int wtsinuse, wttotal; 
extern char incrementseed; 
extern unsigned seed; 
extern SEEDNODE *seedstart; 
 
#if defined(UNIX) && defined(HOTKEYS) 
 
#ifdef BSD 
void initraw() 
{ 
 int i; 
 tcgetattr(0,&noraw); 
 raw.c_iflag = noraw.c_iflag; 
 raw.c_oflag = noraw.c_oflag; 
 raw.c_cflag = noraw.c_cflag; 
 raw.c_lflag = noraw.c_lflag & ~ ECHO; 
 raw.c_lflag = raw.c_lflag & ~ ICANON; 
 for (i=0;i 31.999 || x < -32.0) 
 { 
  sprintf(outstr,"magnitude of %f is too large for the integer",x); 
  pg(stdout,outstr); 
  pg(stdout," representation\n"); 
  readerror = 1; 
  if (x > 31.999) return(MAXSHORT); else return(MINSHORT); 
 }; 
if (x > 0.0) s = x * 1024 + 0.5; 
else s = x * 1024 - 0.5; 
if (x != 0.0 && s == 0) 
 { 
  sprintf(outstr,"warning:  magnitude of %f is too small for",x); 
  pg(stdout,outstr); 
  pg(stdout," the integer representation\n"); 
  return(0); 
 }; 
return(s); 
} 
 
REAL unscale(x)  /* returns the REAL value of short x */ 
short x; 
{return((REAL) x / 1024.0);} 
 
REAL unscaleint(x)  /* returns the REAL value of INT32 x */ 
INT32 x; 
{ return((REAL) x / 1024.0); } 
 
#endif 
 
int pushfile(filename,timestoread) 
char *filename; 
int timestoread; 
{ 
FILE *file; 
 
bufferptr = 0; 
bufferend = 0; 
buffer[0] = '\n'; 
file = fopen(filename,"r"); 
if (file == NULL) 
 { 
  sprintf(outstr,"cannot open:  %s\n",filename); pg(stdout,outstr); 
  return(0); 
 }; 
filestackptr = filestackptr + 1; 
if (filestackptr > MAXFILES) 
 { 
  pg(stdout,"can't stack up any more files\n"); 
  filestackptr = filestackptr - 1; 
  fclose(file); 
  return(0); 
 }; 
filestack[filestackptr] = file; 
filetimes[filestackptr] = timestoread; 
data = file; 
return(1); 
}  
 
void popfile() 
{ 
bufferptr = 0; 
bufferend = 0; 
buffer[0] = '\n'; 
if (s[TOL][TRAIN].wrong == 0) /* break the "loop" */ 
   filetimes[filestackptr] = 1; 
filetimes[filestackptr] = filetimes[filestackptr] - 1; 
if (filetimes[filestackptr] > 0) rewind(data); 
else if (filestackptr > 0) 
 { 
  fclose(data); 
  filestackptr = filestackptr - 1; 
 } 
else pg(stdout,"\nunexpected EOF:  to quit the program, type q\n"); 
data = filestack[filestackptr]; 
} 
 
int readch() /* returns the next character in the input buffer */ 
{  
 int i, ch2; 
 
if (bufferptr > bufferend) /* then read next line into buffer */ 
 { 
#ifdef HOTKEYS 
  if (data == stdin) 
   { 
    ch2 = getch(); 
    if (ch2 <= 26 || (ch2 >= 63 && ch2 <= 90)) /* HOTKEY characters */ 
     { 
      if (ch2 == 2) buffer[0] = 'b'; 
      else if (ch2 == 9) buffer[0] = 'i'; 
      else if (ch2 == 18) buffer[0] = 'r'; 
      else buffer[0] = ch2; 
      buffer[1] = '\n'; 
      buffer[2] = '\0'; 
      i = 1; 
      printf("%s",buffer);  
      goto entryfromhotkeys; 
     } 
    else /* all other characters */ 
     { 
      putchar(ch2); 
      i = 0; 
      buffer[i] = ch2; 
#ifdef UNIX 
      while (ch2 != '\n' && i < (BUFFSIZE-1)) 
#else 
      while (ch2 != 13 && i < (BUFFSIZE-1)) 
#endif 
       { 
        ch2 = getch(); 
        if (ch2 == 8 && i >= 0) 
         { 
          i = i - 1; 
          putchar(8); 
         } 
        else if (ch2 == 8) {/* do nothing */} 
#ifdef UNIX 
        else if (ch2 != '\n') 
#else 
        else if (ch2 != 13) 
#endif 
         { 
          putchar(ch2); 
          i = i + 1; 
          buffer[i] = ch2; 
         }; 
       }; 
      putchar('\n'); 
      i = i + 1; 
      goto entryfromhotkeys; 
     }; 
   } 
  else 
#endif 
  ch2 = getc(data); 
  if (ch2 == EOF) return(ch2); 
  i = 0; 
  while(ch2 != '\n' && i < (BUFFSIZE-1)) 
   { 
#ifdef UNIX 
    if (ch2 == 13) ch2 = ' '; /* turn a ctrl-M into a blank */ 
#endif 
    if (ch2 == '\t') ch2 = ' '; 
    buffer[i] = ch2; 
    i = i + 1; 
    ch2 = getc(data); 
   }; 
entryfromhotkeys: 
  if (i == (BUFFSIZE-1)) pg(stdout,"line too long\n"); 
  buffer[i] = '\n'; 
  buffer[i+1] = '\0'; 
  bufferend = i; 
  bufferptr = 0; 
  if (echo == '+') for(i = 0; i <= bufferend; i++) putchar(buffer[i]); 
  if (copy && ((data == stdin) || (echo == '+'))) 
   for (i=0;i<=bufferend;i++) putc(buffer[i],copy); 
 } 
ch2 = buffer[bufferptr]; 
bufferptr = bufferptr + 1; 
return(ch2); 
} 
 
void texterror() 
{ 
pg(stdout,"unexpected text:  "); 
pg(stdout,&buffer[bufferptr-1]); 
bufferptr = bufferend; 
} 
 
char *readstr() 
{ 
short i,start,end; 
char *addr, *addr2; 
i = bufferptr; 
while (buffer[i] == ' ') i = i + 1; 
start = i; 
while (buffer[i] != ' ' && buffer[i] != '\n') i = i + 1; 
end = i-1; 
addr = (char *) malloc((int) end-start+2); 
addr2 = addr; 
for (i=start;i<=end;i++) *addr++ = buffer[i]; 
bufferptr = end + 1; 
*addr = '\0'; 
return(addr2); 
} 
 
int scanfordigit() 
{ 
int sign, ch2; 
 
sign = 1; 
 
restart: 
do ch2 = readch(); while (ch2 == ' ' || ch2 == '\n'); 
if ((ch2 >= '0' && ch2 <= '9') || ch2 == '.') 
 { 
  bufferptr = bufferptr - 1; 
  return(sign); 
 }; 
          switch (ch2) { 
case '}': readerror = 3; 
          return(0); 
case EOF: readerror = 2; 
          return(0); 
case '*': while (ch2 != '\n') ch2 = readch(); 
          goto restart; 
case '-': sign = -sign; 
          goto restart; 
case 'h': 
case 'x': 
case 'X': 
case 'H': 
case 'd': 
case 's': bufferptr = bufferptr - 1; 
          return(0); 
default:  readerror = 1; 
          return(0); 
          }; 
} 
 
int readint(min,max,command) 
int min, max; 
char command; 
{ 
int sign, number, ch2; 
 
readerror = 0; 
sign = scanfordigit(); 
if (readerror) 
 { 
  if (readerror == 1) texterror(); 
  return(0); 
 }; 
number = 0; 
do ch2 = readch(); while (ch2 == ' '); 
while (ch2 >= '0' && ch2 <= '9') 
 { 
  number = number * 10 + (ch2 - '0'); 
  ch2 = readch(); 
 }; 
bufferptr = bufferptr - 1; 
number = sign * number; 
if (number < min || number > max) 
 { 
  sprintf(outstr,"out of range value: %d",number); pg(stdout,outstr); 
  if (data == stdin) pg(stdout,"\n"); 
  else {sprintf(outstr," in %c command\n",command); pg(stdout,outstr);}; 
  readerror = 1; 
 }; 
return(number); 
} 
 
REAL readreal(op,min,command) 
int op; 
REAL min; 
int command; 
{ 
REAL fractpart, divisor, intpart, sign; 
double number; 
int ch2, numread, i; 
 
readerror = 0; 
sign = (REAL) scanfordigit(); 
if (readerror || (sign == 0 && !readingpattern)) 
 { 
  if (readerror == 1) texterror(); 
  return(0); 
 }; 
ch2 = readch(); 
if (ch2 == 'H' && readingpattern) return(unscale(CAPHCODE)); 
else if (ch2 == 'X' && readingpattern) return(unscale(CAPXCODE)); 
else if (ch2 == 'h' && readingpattern) return(unscale(HCODE)); 
else if (ch2 == 'i' && readingpattern) return(unscale(ICODE)); 
else if (ch2 == 'o' && readingpattern) return(unscale(OCODE)); 
else if (ch2 == 'd' && readingpattern) return(unscale(DIFFCODE)); 
else if (ch2 == 's' && readingpattern) return(unscale(SKIPCODE)); 
else if (ch2 == 'x' && readingpattern) return(unscale(unknown)); 
i = 0; 
while ((ch2 >= '0' && ch2 <='9') || ch2 == '+' || ch2 == '-' || 
       ch2 == 'e' || ch2 == 'E' || ch2 == '.') 
 { 
  outstr[i] = ch2; 
  i = i+1; 
  ch2 = readch(); 
 }; 
outstr[i] = 0; 
bufferptr = bufferptr - 1; 
numread = sscanf(outstr,"%lf",&number); 
if (numread == 0) 
 { 
  pg(stdout,"bad real value\n"); 
  readerror = 1; 
  return(0.0); 
 }; 
number = sign * number; 
if (op == GT && number > min) return(number); 
else if (op == GE && number >= min) return(number); 
else 
 { 
  sprintf(outstr,"erroneous value: %f",number); pg(stdout,outstr); 
  if (data == stdin) pg(stdout,"\n"); 
  else {sprintf(outstr," in %c command\n",command); pg(stdout,outstr);}; 
  readerror = 1; 
  return(0.0); 
 }; 
} 
 
WTTYPE rdr(op,min,command) /* reads REAL real numbers and converts */ 
int op;                    /* them to 16-bit integers if necessary */ 
REAL min; 
int command; 
{ 
REAL x; 
WTTYPE ix; 
  
x = readreal(op,min,command); 
if (readerror) return(0); 
ix = scale(x); 
if (readerror) return(0); 
return(ix); 
} 
 
REAL readchar()   /* reads data in compressed format */ 
{ 
int ch2; 
readerror = 0; 
ch2 = readch(); 
do { 
          switch (ch2) { 
case '\n': 
case ' ': ch2 = readch(); 
          break; 
case '1': return(1.0); 
case '0': return(0.0); 
case 'X': return(unscale(CAPXCODE)); 
case 'x': return(unscale(unknown)); 
case '*': do ch2 = readch(); while(ch2 != '\n'); 
          break; 
case 'H': return(unscale(CAPHCODE)); 
case 'h': return(unscale(HCODE)); 
case 's': return(unscale(SKIPCODE)); 
case 'd': return(unscale(DIFFCODE)); 
case EOF: readerror = 2; 
          return(0.0); 
case '}': readerror = 3; 
          return(0.0); 
default:  texterror(); 
          readerror = 1; 
          return(0.0);}; 
} while (0 == 0); 
} 
 
void readapat(pn,relation,minimum,command,informat) 
PATNODE *pn; 
int relation; 
REAL minimum; 
int command; 
char informat; 
{ 
  REAL val; 
  int unitnumber; 
  UNIT *u; 
  if (informat == 'r') val = rdr(relation,minimum,command); 
  else val = scale(readchar()); 
  if (val == ICODE) 
   { 
    recurinit = '+'; 
    pn->layer = 1; 
    pn->val = ICODE; 
    unitnumber = readint(1,start->unitcount,'r'); 
    if (readerror != 0) return; 
    pn->unitno = unitnumber; 
    u = locateunit(1,unitnumber); 
    pn->addr = &(u->oj); 
   } 
  else if (val == HCODE) 
   { 
    recurinit = '+'; 
    pn->addr = (WTTYPE *) -1; 
    pn->layer = 2; 
    pn->val = HCODE; 
    pn->unitno = HCODE; 
   } 
  else if (val == CAPXCODE) 
   { 
    pn->addr = (WTTYPE *) -1; 
    pn->layer = 2; 
    pn->val = CAPXCODE; 
    pn->unitno = CAPXCODE; 
   } 
  else if (val == CAPHCODE) 
   { 
    recurinit = '+'; 
    pn->addr = (WTTYPE *) -1; 
    pn->layer = 2; 
    pn->val = CAPHCODE; 
    pn->unitno = CAPHCODE; 
   } 
  else if (val == OCODE) 
   { 
    recurinit = '+'; 
    pn->layer = nlayers; 
    pn->val = OCODE; 
    unitnumber = readint(1,last->unitcount,'r'); 
    if (readerror != 0) return; 
    pn->unitno = unitnumber; 
    u = locateunit((int) pn->layer,unitnumber); 
    pn->addr = &(u->oj); 
   } 
  else if (val == SKIPCODE) 
   { 
    pn->addr = (WTTYPE *) -1; 
    pn->layer = 0; 
    pn->val = SKIPCODE; 
    pn->unitno = SKIPCODE; 
   } 
  else if (val == DIFFCODE) 
   { 
    pn->addr = (WTTYPE *) -1; 
    pn->layer = nlayers; 
    pn->val = DIFFCODE; 
    pn->unitno = DIFFCODE; 
   } 
  else 
   { 
    pn->addr = NULL; 
    pn->val = val; 
    pn->layer = 0;   /* unused */ 
    pn->unitno = 0;  /* unused */ 
   }; 
} 
 
void readpatson(layer,list,command) 
LAYER *layer; 
int list; 
int command; 
 
{PATLIST *pl, *prev; 
 PATNODE *pn; 
 int i, answer, veclength; 
 
pl = (PATLIST *) malloc(sizeof(PATLIST)); 
pl->next = NULL; 
pl->pats = NULL;     /* no patterns read yet */ 
if (layer->patstart[list] == NULL) 
 { 
  prev = NULL; 
  layer->patstart[list] = pl; 
 } 
else 
 { 
  prev = layer->currentpat[list]; 
  prev->next = pl; 
 }; 
layer->currentpat[list] = pl; 
 
veclength = layer->unitcount; 
pn = (PATNODE *) malloc(veclength * sizeof(PATNODE)); 
pl->pats = pn; 
if (layer == last && probtype == 'c') 
 { 
  answer = readint(1,veclength,command); 
  if (readerror != 0) return; 
  for (i=1;i<=veclength;i++) 
   { 
    if (i == answer) pn->val = classon; else pn->val = classoff; 
    pn->addr = NULL; 
    pn->layer = nlayers; 
    pn->unitno = i; 
    pn++; 
   }; 
  return; 
 }; 
for (i=1;i<=veclength;i++) 
 { 
  readapat(pn,GE,(REAL) HCODE,command,informat); 
  if ((readerror == 3 || readerror == 2) && i == 1 && layer == start) 
   { 
    if (prev != NULL) prev->next = NULL; 
    free(pn); 
    free(pl); 
    readerror = readerror + 2; 
    return; 
   } 
  else if (readerror != 0) return; 
  if (pn->unitno == CAPHCODE || pn->unitno == CAPXCODE) return; else pn++; 
 }; 
return; 
} 
 
int readpats(list,command) 
int list, command; 
{ int i, j; 
  PATLIST *pl; 
 
/* look for scaling parameters, if any, in a TRAINing set */ 
 
if (list == TRAIN) 
   { 
    REAL temp; 
    WTTYPE trans, sca; 
    int ch1, ch2, k, col, nfactors; 
    UNIT *u; 
    ch1 = readch(); 
    if (ch1 == '\n') ch1 = readch(); 
    ch2 = readch(); 
    if (ch1 != '*' || ch2 != '$') bufferptr = bufferptr - 2; 
    else /* there are scaling parameters */ 
       { 
        nfactors = readint(0,MAXINT,'r'); 
        do ch1 = readch(); while (ch1 != '\n'); 
        u = start->units; 
        for (k=1;k<=nfactors;k++) 
           { 
            if (u == NULL) 
               { 
                pg(stdout,"not enough input units for these patterns\n"); 
                exit(99); 
               }; 
            ch1 = readch(); 
            ch2 = readch(); 
            if (ch1 != '*' || ch2 != '$') 
               { 
                pg(stdout,"error in input scaling list\n"); 
                goto readthepatterns; 
               } 
            else 
               { 
                col = readint(k,k,'r'); 
                if (readerror == 1) 
                   { 
                    pg(stdout,"error in scaling list\n"); 
                    goto readthepatterns; 
                   }; 
                trans = rdr(GE,(REAL) -MAXINT,'r'); 
                if (readerror == 1) 
                   { 
                    pg(stdout,"error in scaling list\n"); 
                    goto readthepatterns; 
                   } 
                else u->translate = trans; 
                sca = rdr(GE,(REAL) -MAXINT,'r'); 
                if (readerror == 1) 
                   { 
                    pg(stdout,"error in scaling list\n"); 
                    goto readthepatterns; 
                   } 
                else u->userscale = sca; 
                u = u->next; 
                do ch1 = readch(); while (ch1 != '\n'); 
               }; 
           }; 
/* do the output unit scaling factors if its not a classification problem */ 
        if (probtype != 'c') 
           { 
            u = last->units; 
            for (k=1;k<=last->unitcount;k++) 
               { 
                ch1 = readch(); 
                ch2 = readch(); 
                if (ch1 != '*' || ch2 != '$') 
                   { 
                    pg(stdout,"error in output scaling list\n"); 
                    goto readthepatterns; 
                   } 
                else 
                   { 
                    col = readint(k,k,'r'); 
                    if (readerror == 1) 
                       { 
                        pg(stdout,"error in scaling list\n"); 
                        goto readthepatterns; 
                       }; 
                    trans = rdr(GE,(REAL) -MAXINT,'r'); 
                    if (readerror == 1) 
                       { 
                        pg(stdout,"error in scaling list\n"); 
                        goto readthepatterns; 
                       } 
                    else u->translate = trans; 
                    sca = rdr(GE,(REAL) -MAXINT,'r'); 
                    if (readerror == 1) 
                       { 
                        pg(stdout,"error in scaling list\n"); 
                        goto readthepatterns; 
                       } 
                    else u->userscale = sca; 
                    u = u->next; 
                    do ch1 = readch(); while (ch1 != '\n'); 
                   }; /* end else */ 
               }; /* end for */ 
       }; /* ends prob type */ 
     }; /* else there are scaling parameters */ 
   }; /* if its a training set file */ 
 
readthepatterns: 
i = 0; 
readerror = 0; 
while (readerror == 0) 
 { 
  readpatson(start,list,command); 
  if (readerror) break; 
  readpatson(last,list,command); 
  if (readerror) break; 
  i = i + 1; 
 }; 
if (readerror == 5) return(i); 
else if (readerror == 4) 
 { 
  popfile(); 
  return(i); 
 }; 
 
/* failure for some reason */ 
 
sprintf(outstr,"error while reading pattern %d",i+1); pg(stdout,outstr); 
if (readerror == 1) pg(stdout,"\n"); 
else if (readerror == 2) pg(stdout,":  unexpected end of file\n"); 
else if (readerror == 3) pg(stdout,":  unexpected }\n"); 
if (readerror == 2) popfile(); 
if (i > 0) 
 { 
  pl = (PATLIST *) start->patstart[list]; 
  for (j=1;j<=prevnpats + i - 1;j++) pl = pl->next; 
  pl->next = NULL; 
  pl = (PATLIST *) last->patstart[list]; 
  for (j=1;j<=prevnpats + i - 1;j++) pl = pl->next; 
  pl->next = NULL; 
 }; 
return(i); 
} 
 
int pg(f,str) /* paging and making a copy function */ 
FILE *f; 
char *str; 
{ 
char *ch3,action,cr; 
int i; 
long clockbefore, clockafter; 
int nbackspaces = 5; 
 
if (f != stdout) {fprintf(f,"%s",str); return(0);}; 
clockbefore = clock(); 
action = 0; 
ch3 = str; 
while (*ch3 != '\0') 
 { 
  if (*ch3 == '\n') 
   { 
    putchar('\n'); 
    if (copyflag == '+') putc('\n',copy); 
    lineno = lineno + 1; 
    if (pagesize > 0 && lineno > 0 && lineno % pagesize == 0) 
     { 
      printf("More?"); 
#ifdef HOTKEYS 
      action = getch(); 
#else 
      action = getchar(); 
      if (action != '\n') cr = getchar(); 
#endif 
      for(i=1;i<=nbackspaces;i++) putchar(8); 
      for(i=1;i<=nbackspaces;i++) putchar(' '); 
      for(i=1;i<=nbackspaces;i++) putchar(8); 
      if (action == 'q') goto stoppaging; 
      else if (action == 'c') lineno = -MAXINT; 
#ifdef UNIX 
      else if (action == '\n') lineno = lineno - 1; 
#else 
      else if (action == 13) lineno = lineno - 1; 
#endif 
      else if (action == 4) lineno = pagesize / 2; 
      else lineno = 0; 
     } 
   } 
  else {putchar(*ch3); if (copyflag == '+') putc(*ch3,copy); }; 
  ch3++; 
 }; 
stoppaging: 
clockafter = clock(); 
iotime = iotime + clockafter - clockbefore; 
if (action == 'q') return(1); else return(0); 
} 
 
void printnetsize(f) /* the size of the network */ 
FILE *f; 
{LAYER *p; 
pg(f,"m "); 
p = start; 
if (stmsize > 0) 
 { 
  sprintf(outstr," %1d+%1d",p->unitcount-stmsize,stmsize); 
  pg(f,outstr); 
  p = p->next; 
 }; 
while (p != NULL) 
 { 
  sprintf(outstr," %1d",p->unitcount); 
  pg(f,outstr); 
  p = p->next; 
 }; 
if (ioconnects) pg(f," x"); 
if (pccnet) pg(f," p"); 
} 
 
void listseeds(f) 
FILE *f; 
{ 
 SEEDNODE *s; 
 s = seedstart->next; 
 pg(f,"s"); 
 while (s != NULL) 
  { 
   sprintf(outstr," %1d",s->val); pg(f,outstr); 
   s = s->next; 
  }; 
} 
 
int printoutunits(patnum,layer,list,error,tok,mok) 
int patnum; 
LAYER *layer; 
int list; 
REAL error; 
char tok,mok; 
{ 
short unitno, fmtbreaknum; 
UNIT *u; 
WTTYPE upper, middle, diff; 
 
int i; 
WTTYPE *target; 
PATLIST *pl; 
#ifdef INTEGER 
float tempreal; 
#endif 
 
upper = scale(1.0) - toler; 
middle = scale(0.5); 
unitno = 0; 
fmtbreaknum = 1; 
/* 
if (layer == last && patnum > 0) 
 { 
  pl = last->currentpat[list]; 
  target = pl->pats; 
  u = (UNIT *) layer->units; 
  for (i=1;i<=last->unitcount;i++) 
   { 
    u->tj = *target++; 
    u = u->next; 
   }; 
 }; 
*/ 
if (patnum) {sprintf(outstr,"%5d ",patnum); pg(stdout,outstr);} 
else pg(stdout,"      "); 
u = (UNIT *) layer->units; 
while (u != NULL) 
 { 
  diff = u->tj - u->oj; 
  unitno = unitno + 1; 
  if (outformat == 'r' || outformat == 's') 
   { 
    sprintf(outstr,"%6.3f ",unscale(u->oj)); pg(stdout,outstr); 
    if (format[fmtbreaknum] == unitno) 
     { 
      if (pg(stdout,"\n      ")) return(1); 
      if (fmtbreaknum < MAXFORMAT - 1) fmtbreaknum = fmtbreaknum + 1; 
     } 
   } 
  else if (outformat == 'e') 
   { 
    sprintf(outstr,"%12.4e ",unscale(u->oj)); pg(stdout,outstr); 
    if (format[fmtbreaknum] == unitno) 
     { 
      if (pg(stdout,"\n      ")) return(1); 
      if (fmtbreaknum < MAXFORMAT - 1) fmtbreaknum = fmtbreaknum + 1; 
     } 
   } 
  else if (outformat == 'a') 
   { 
    if (diff < toler) pg(stdout,"c"); 
    else if (u->oj > upper) pg(stdout,"1"); 
    else if (u->oj < toler) pg(stdout,"0"); 
    else if (u->oj > u->tj) pg(stdout,"^"); 
    else pg(stdout,"v"); 
    if (format[fmtbreaknum] == unitno) 
     { 
      pg(stdout," "); 
      if (fmtbreaknum < MAXFORMAT - 1) fmtbreaknum = fmtbreaknum + 1; 
     } 
   } 
  else  
   { 
    if (u->oj > upper) pg(stdout,"1"); 
    else if (u->oj > middle) pg(stdout,"^"); 
    else if (u->oj < toler) pg(stdout,"0"); 
    else pg(stdout,"v"); 
    if (format[fmtbreaknum] == unitno) 
     { 
      pg(stdout," "); 
      if (fmtbreaknum < MAXFORMAT - 1) fmtbreaknum = fmtbreaknum + 1; 
     } 
   } 
  u = u->next; 
 }; 
if (patnum > 0) 
 { 
  sprintf(outstr," e %5.3f",error); pg(stdout,outstr); 
  if (tok) pg(stdout," ok"); else pg(stdout,"   "); 
  if (mok) pg(stdout," ok"); 
  if (pg(stdout,"\n")) return(1); else return(0); 
 }; 
if (pg(stdout,"\n")) return(1);  
if (pg(stdout,"\n")) return(1); else return(0); 
} 
 
void saveweights()  /* saves weights on the file weights */ 
{ 
UNIT *u, *bu; 
LAYER *layer; 
WTNODE *w; 
WTTYPE wvalue, evalue, dvalue, svalue; 
int wtsize, unitno, layerno, i; 
short wtinuse; 
FILE *wtfileptr; 
 
wtsize = WTSIZE; 
sprintf(wtfilename,"%s",wtfile); 
wtfileptr = fopen(wtfilename,"wb"); 
if (wtfileptr == NULL) 
 { 
  sprintf(outstr,"cannot open: %s\n",wtfilename); pg(stdout,outstr); 
  return; 
 }; 
fprintf(wtfileptr,"%d%c",totaliter,wtformat); 
layer = start; 
fprintf(wtfileptr,"  m %1d",layer->unitcount); 
layer = layer->next; 
while (layer != NULL) 
 { 
  fprintf(wtfileptr," %1d",layer->unitcount); 
  layer = layer->next; 
 }; 
if (ioconnects) fprintf(wtfileptr," x"); 
fprintf(wtfileptr," aah%c",start->next->activation); 
fprintf(wtfileptr," ao%c",last->activation); 
fprintf(wtfileptr," bh %f",unscale(start->next->biasact)); 
fprintf(wtfileptr," bo %f",unscale(last->biasact)); 
fprintf(wtfileptr," Dh %f",unscale(start->next->D)); 
fprintf(wtfileptr," Do %f",unscale(last->D)); 
fprintf(wtfileptr,"  file = %s",datafile); 
#ifdef DOSMOD   /* I don't remember this */ 
fputc('\r',wtfileptr); 
#endif 
fputc('\n',wtfileptr); 
 
layer = start->next; 
while (layer != NULL) 
 { 
  u = (UNIT *) layer->units; 
  while (u != NULL) 
   { 
    w = (WTNODE *) u->wtlist; 
    while (w != NULL) 
     { 
#ifdef SYMMETRIC 
      wvalue = *(w->weight); 
      evalue = *(w->eta); 
      dvalue = *(w->olddw); 
      svalue = *(w->slope); 
      wtinuse = w->inuse; 
#else 
      wvalue = w->weight; 
      evalue = w->eta; 
      dvalue = w->olddw; 
      svalue = w->slope; 
      wtinuse = w->inuse; 
#endif 
      if (wtformat == 'r' || wtformat == 'R') 
       { 
        fprintf(wtfileptr,"%14.6e",unscale(wvalue)); 
        fprintf(wtfileptr,"%3d",w->inuse); 
        if (wtformat == 'R') 
         { 
          fprintf(wtfileptr," %14.6e",unscale(evalue)); 
          fprintf(wtfileptr," %14.6e",unscale(dvalue)); 
          fprintf(wtfileptr," %14.6e",unscale(svalue)); 
         }; 
        bu = w->backunit; 
        fprintf(wtfileptr,"  %1d ",bu->layernumber); 
        if (bu->unitnumber == 32767) fprintf(wtfileptr,"b to "); 
        else fprintf(wtfileptr,"%1d to ",bu->unitnumber); 
        fprintf(wtfileptr,"%1d %1d",u->layernumber,u->unitnumber); 
#ifdef DOSMOD 
        fputc('\r',wtfileptr); 
#endif 
        fputc('\n',wtfileptr); 
       } 
      w = w->next; 
     }; 
    u = u->next; 
   }; 
  layer = layer->next; 
 }; 
fflush(wtfileptr); 
fclose(wtfileptr); 
lastsave = totaliter; 
} 
 
void restoreweights()    /* restore weights */ 
{ 
FILE *wtfileptr; 
UNIT *u; 
LAYER *layer; 
WTNODE *w; 
int ch2, fileformat, wtsize, numread, i, layerno, unitno; 
WTTYPE wvalue, evalue, dvalue, svalue; 
int wtinuse; 
double temp; 
unsigned char *cptr; 
 
/* 
if (numwtfiles == '+') sprintf(wtfilename,"%s.%1d",wtfile,wtfilecount); 
else sprintf(wtfilename,"%s",wtfile); 
*/ 
wtfileptr = fopen(wtfilename,"rb"); 
if (wtfileptr == NULL) 
 { 
  sprintf(outstr,"cannot open: %s\n",wtfilename); 
  pg(stdout,outstr); 
  return; 
 }; 
numread = fscanf(wtfileptr,"%d",&totaliter); 
if (numread == EOF) goto unexpectedeof; 
if (numread == 0) goto badread; 
fileformat = fgetc(wtfileptr); 
if (fileformat == EOF) goto unexpectedeof; 
if (fileformat != wtformat) pg(stdout,"note: weight format mismatch\n"); 
wtsize = WTSIZE; 
do ch2 = fgetc(wtfileptr); while (ch2 != '\n'); 
layer = start->next; 
while (layer != NULL) 
 { 
  u = (UNIT *) layer->units; 
  while (u != NULL) 
   { 
    u->inuse = 1; 
    w = (WTNODE *) u->wtlist; 
    while (w != NULL) 
     { 
      if (fileformat == 'r' || fileformat == 'R') 
       { 
        numread = fscanf(wtfileptr,"%lf",&temp); 
        if (numread == EOF) goto unexpectedeof; 
        if (numread == 0) goto badread; 
        wvalue = scale((REAL) temp); 
#ifdef ALTCODE 
        { 
         do ch2 = fgetc(wtfileptr); while (ch2 == ' '); 
         wtinuse = 1; 
         if (ch2 == '-') 
          { 
           wtinuse = -1; 
           ch2 = fgetc(wtfileptr); 
          }; 
         if (ch2 == 0) wtinuse = 0; 
         else if (ch2 == '1') wtinuse = wtinuse; 
         else if (ch2 == '2') wtinuse = wtinuse * 2; 
         else pg(stdout,"bad weight in use flag\n"); 
        } 
#else 
        numread = fscanf(wtfileptr,"%d",&wtinuse); 
        if (numread == EOF) goto unexpectedeof; 
        if (numread == 0) goto badread; 
#endif 
        if (fileformat == 'R') 
         { 
          numread = fscanf(wtfileptr,"%lf",&temp); 
          if (numread == EOF) goto unexpectedeof; 
          if (numread == 0) goto badread; 
          evalue = scale((REAL) temp); 
          numread = fscanf(wtfileptr,"%lf",&temp); 
          if (numread == EOF) goto unexpectedeof; 
          if (numread == 0) goto badread; 
          dvalue = scale((REAL) temp); 
          numread = fscanf(wtfileptr,"%lf",&temp); 
          if (numread == EOF) goto unexpectedeof; 
          if (numread == 0) goto badread; 
          svalue = scale((REAL) temp); 
         }; 
        do ch2 = fgetc(wtfileptr); while (ch2 != '\n'); 
        if (ch2 == '\n') 
         { 
          ch2 = fgetc(wtfileptr); 
          if (ch2 != '\r') ungetc(ch2,wtfileptr); 
         }; 
       } 
#ifdef SYMMETRIC 
      *(w->weight) = wvalue; 
      if (fileformat == 'R') 
       { 
        *(w->olddw) = dvalue; 
        *(w->eta) = evalue; 
       } 
      else *(w->olddw) = 0; 
#else 
      w->weight = wvalue; 
      w->inuse = wtinuse; 
      if (fileformat == 'R') 
       { 
        w->olddw = dvalue; 
        w->eta = evalue; 
        w->slope = svalue; 
       } 
      else w->olddw = 0; 
#endif 
      w = w->next; 
     }; 
    u = u->next; 
   }; 
  layer = layer->next; 
 }; 
fclose(wtfileptr); 
lastsave = totaliter; 
return; 
badread: pg(stdout,"\n>>>>> scanf read error <<<<<\n\n"); 
fclose(wtfileptr); 
return; 
unexpectedeof: pg(stdout,"\n>>>>> ran out of weights <<<<<\n\n"); 
fclose(wtfileptr); 
} 
 
void printweights(u,layerno) /* print the weights leading into unit u */ 
UNIT *u; 
int layerno; 
 
{ 
WTNODE *w; 
UNIT *bunit; 
WTTYPE value; 
LAYER *layer; 
int i; 
short wtinuse, unitinuse; 
#ifdef INTEGER 
INT32 sum, input; 
#else 
REAL sum, input; 
#endif 
 
w = (WTNODE *) u->wtlist; 
sum = 0; 
pg(stdout,"layer unit  inuse  unit value    weight   inuse   input from unit\n"); 
while (w != NULL) 
 { 
  bunit = (UNIT *) w->backunit; 
  unitinuse = w->backunit->inuse; 
#ifdef SYMMETRIC 
  value = *(w->weight); 
  wtinuse = 1; 
#else 
  value = w->weight; 
  wtinuse = w->inuse; 
#endif 
 
#ifdef INTEGER 
  if (wtinuse && unitinuse) 
   { 
    input = (INT32) value * bunit->oj; 
    input = input / 1024; 
   } 
  else input = 0; 
#else 
  if (wtinuse && unitinuse) input = value * bunit->oj; else input = 0; 
#endif 
  sum = sum + input; 
  sprintf(outstr,"%3d   ",bunit->layernumber); pg(stdout,outstr); 
  if (bunit->unitnumber == 32767) pg(stdout,"  b  "); 
  else {sprintf(outstr,"%3d  ",bunit->unitnumber); pg(stdout,outstr);}; 
  sprintf(outstr,"%4d   ",unitinuse); pg(stdout,outstr); 
  sprintf(outstr,"%10.5f  %10.5f  ",unscale(bunit->oj),unscale(value)); 
  pg(stdout,outstr); 
  sprintf(outstr," %3d ",wtinuse); pg(stdout,outstr); 
  sprintf(outstr,"%14.5f\n",unscaleint(input)); 
  if (pg(stdout,outstr)) return; 
  w = w->next; 
 }; 
pg(stdout,"                                              "); 
sprintf(outstr,"sum = %9.5f\n",unscaleint(sum)); 
if (pg(stdout,outstr)) return; 
layer = start; 
for (i=2;i<=layerno;i++) layer = layer->next; 
if (layer->D != scale(1.0)) 
 { 
#ifdef INTEGER 
  sum = sum * layer->D / 1024; 
#else 
  sum = sum * layer->D; 
#endif 
  pg(stdout,"                                            "); 
  sprintf(outstr,"sum = %9.5f with D = %7.3f\n",unscaleint(sum),unscale(layer->D)); 
  if (pg(stdout,outstr)) return; 
 }; 
pg(stdout,"\n"); 
} 
 
void parameters(f) 
FILE *f; 
{int i; 
printnetsize(f); 
sprintf(outstr," * %1d weights; ",wttotal); pg(f,outstr); 
sprintf(outstr,"data file = %s",datafile); pg(f,outstr); 
if (zeroderiv) pg(f,"*>>>>> 0 deriv <<<<<*\n"); else pg(f,"\n"); 
if (toosmall != 0) 
 { 
  sprintf(outstr,"pw  %4.2f",unscale(toosmall)); pg(f,outstr); 
  sprintf(outstr," * weights in use: %1d\n",wtsinuse); pg(f,outstr); 
 }; 
sprintf(outstr,"sb %f\n", unscale(stdthresh)); pg(f,outstr); 
#ifdef INTEGER 
if (wtlimithit) pg(f,"*>>>>> WEIGHT LIMIT HIT <<<<<*\n"); 
#endif 
listseeds(f); pg(f,"\n"); 
sprintf(outstr,"r %1d %1d ",maxiter,printrate); pg(f,outstr); 
if (f != stdout) pg(f,"\"\n"); else pg(f,"\n"); 
sprintf(outstr,"f b%c c%c e%c i%c",ringbell,copyflag,echo,informat); 
pg(f,outstr); 
if (offby1 == '+') pg(f," O+"); else pg(f," O-"); 
sprintf(outstr," o%c P %d p%c ",outformat,pagesize,probtype); 
pg(f,outstr); 
sprintf(outstr,"R%c ",runningflag); pg(f,outstr); 
sprintf(outstr," s%c ",summary); pg(f,outstr); 
sprintf(outstr,"u%c ",up_to_date_stats); pg(f,outstr); 
sprintf(outstr,"x% f\n",unscale(unknown)); pg(f,outstr); 
pg(f,"f B "); 
for (i=1;i<=MAXFORMAT-1;i++) 
 {sprintf(outstr," %1d",format[i]); pg(f,outstr);}; 
pg(f,"\n"); 
sprintf(outstr,"! %s ",sysstr); pg(f,outstr); 
if (f != stdout) pg(f,"\"\n"); else pg(f,"\n"); 
pg(f,"a "); 
if (nlayers > 2) 
   {sprintf(outstr,"ah %c ",ah); pg(f,outstr);}; 
sprintf(outstr,"ao %c ",ao); pg(f,outstr); 
sprintf(outstr,"d%c ",deriv); pg(f,outstr); 
sprintf(outstr,"u%c\n",update); pg(f,outstr); 
sprintf(outstr,"e %7.5f %7.5f\n",unscale(eta),unscale(eta2));pg(f,outstr); 
sprintf(outstr,"a %7.5f\n",unscale(alpha)); pg(f,outstr); 
 
#ifndef SYMMETRIC 
sprintf(outstr,"d d %8.5f e %8.5f ",unscale(decay),unscale(dbdeta)); 
pg(f,outstr); 
sprintf(outstr,"k %8.5f m %8.5f ",unscale(kappa),unscale(etamax)); 
pg(f,outstr); 
sprintf(outstr,"t %8.5f\n",unscale(theta1)); 
pg(f,outstr); 
sprintf(outstr,"qp dh %8.6f do %8.6f e %8.5f ",qpdecayh,qpdecayo,unscale(qpeta)); 
pg(f,outstr); 
sprintf(outstr,"m %8.5f n %8.5f s%c\n",unscale(mu),unscale(qpnoise),qpslope); 
pg(f,outstr); 
#endif 
 
sprintf(outstr,"* last save at: %d\n",lastsave); pg(f,outstr); 
sprintf(outstr,"rw %s\n",wtfilename); pg(f,outstr); 
 
sprintf(outstr,"t %4.2f\n",unscale(toler)); pg(f,outstr); 
 
printstats(f,TRAIN,1,s); 
if (s[TOL][TEST].npats > 0) printstats(f,TEST,1,s); 
if (f != stdout) 
 { 
  sprintf(outstr,"z %e",minimumsofar); pg(f,outstr); 
 }; 
pg(f,"\n"); 
} 
 
void menus(ch) 
char ch; 
{ 
switch (ch) { 
 
case '?': parameters(stdout); return; 
 
case 'A': 
pg(stdout,"\nAlgorithm Parameters\n\n"); 
pg(stdout,"a a      sets all act. functions to ; {ls}             h aa\n"); 
if (nlayers > 2) 
 { 
  sprintf(outstr,"a ah %c         ",ah); pg(stdout,outstr); 
  pg(stdout,"hidden layer(s) act. function; {ls}                 h aa\n"); 
 }; 
sprintf(outstr,"a ao %c         ",ao); pg(stdout,outstr); 
pg(stdout,"output layer act. function; {ls}                    h aa\n"); 
sprintf(outstr,"a d %c          ",deriv); pg(stdout,outstr); 
pg(stdout,"the output layer derivative term; {cdf}             h ad\n"); 
sprintf(outstr,"a u %c          ",update); pg(stdout,outstr); 
pg(stdout,"the weight update algorithm; {Ccdpq}                h au\n"); 
 
sprintf(outstr,"t %4.3f        ",unscale(toler)); pg(stdout,outstr); 
pg(stdout,"tolerance/unit for successful learning; (0..1)\n"); 
sprintf(outstr,"\nf O %c          ",offby1); pg(stdout,outstr); 
pg(stdout,"allows out-of-date statistics to print; {+-}\n"); 
sprintf(outstr,"f u %c          ",up_to_date_stats); pg(stdout,outstr); 
pg(stdout,"compute up-to-date statistics; {+-}\n"); 
pg(stdout,"\n"); 
return; 
 
case 'C': 
pg(stdout,"\nScreen     Includes Information and Parameters on:\n\n"); 
pg(stdout,"  A        algorithm parameters and tolerance\n"); 
pg(stdout,"  C        this listing of major command groups\n"); 
#ifndef SYMMETRIC 
pg(stdout,"  D        delta-bar-delta parameters\n"); 
#endif 
pg(stdout,"  F        formats: patterns, output, paging, copying screen i/o\n"); 
pg(stdout,"  G        gradient descent (plain backpropagation)\n"); 
pg(stdout,"  M        miscellaneous commands: shell escape, seed values, clear,\n"); 
pg(stdout,"           clear and initialize, quit, save almost everything\n"); 
pg(stdout,"  N        making a network, listing network unit values\n"); 
pg(stdout,"  P        pattern commands: reading patterns, testing patterns,\n"); 
#ifndef SYMMETRIC 
pg(stdout,"  Q        quickprop parameters\n"); 
#endif 
pg(stdout,"  T        a short tutorial\n"); 
pg(stdout,"  W        weight commands: listing, saving, restoring, set bias unit weights\n"); 
pg(stdout,"  ?        a compact listing of everything\n"); 
pg(stdout,"\n"); 
return; 
 
#ifndef SYMMETRIC 
case 'D': 
pg(stdout,"\nThe Delta-Bar-Delta Paramters (d)\n\n"); 
 
sprintf(outstr,"d d %4.2f      ",unscale(decay)); pg(stdout,outstr); 
pg(stdout,"decay rate for each eta; (0..1)\n"); 
sprintf(outstr,"d e %5.3f     ",unscale(dbdeta)); pg(stdout,outstr); 
pg(stdout,"initial eta for each weight; (0..inf)\n"); 
sprintf(outstr,"d k %6.4f    ",unscale(kappa)); pg(stdout,outstr); 
pg(stdout,"kappa, the eta increment; (0..inf)\n"); 
sprintf(outstr,"d m %6.3f    ",unscale(etamax)); pg(stdout,outstr); 
pg(stdout,"maximum value for eta; (0..inf)\n"); 
sprintf(outstr,"d t %3.1f       ",unscale(theta1)); pg(stdout,outstr); 
pg(stdout,"the theta parameter; (0..1)\n"); 
pg(stdout,"\na u d         use this to get the delta-bar-delta update method\n"); 
pg(stdout,"\n"); 
return; 
#endif 
 
case 'F': 
pg(stdout,"\nThe Format Command (f)\n\n"); 
sprintf(outstr,"f b %c         ",ringbell); pg(stdout,outstr); 
pg(stdout,"ring the bell when training is finished; {+-}\n"); 
sprintf(outstr,"f c %c         ",copyflag); pg(stdout,outstr); 
pg(stdout,"make a copy of screen i/o on the file copy; {+-}\n"); 
sprintf(outstr,"f e %c         ",echo); pg(stdout,outstr); 
pg(stdout,"echo input; {+-}\n"); 
sprintf(outstr,"f i %c         ",informat); pg(stdout,outstr); 
pg(stdout,"format for reading input and output patterns; {cr}         h fi\n"); 
sprintf(outstr,"f O %c         ",offby1); pg(stdout,outstr); 
pg(stdout,"give off by 1 statistics for training set; {+-}\n"); 
sprintf(outstr,"f o %c         ",outformat); pg(stdout,outstr); 
pg(stdout,"format for outputing network's unit values; {acer}         h fo\n"); 
sprintf(outstr,"f P %2d        ",pagesize); pg(stdout,outstr); 
pg(stdout,"lines per page; 0 = no paging; [0..inf]\n"); 
sprintf(outstr,"f p %c         ",probtype); pg(stdout,outstr); 
pg(stdout,"problem type; {cg}                                         h fp\n"); 
sprintf(outstr,"f R %c         ",runningflag); pg(stdout,outstr); 
pg(stdout,"print the \"running . . .\" message; {+-}\n"); 
sprintf(outstr,"f s %c         ",summary); pg(stdout,outstr); 
pg(stdout,"summarize learning status while running; {+-}\n"); 
sprintf(outstr,"f u %c         ",up_to_date_stats); pg(stdout,outstr); 
pg(stdout,"get up-to-date status of training patterns; {+-}\n"); 
sprintf(outstr,"f x %5.2f     ",unknown); pg(stdout,outstr); 
pg(stdout,"the value of x in patterns\n"); 
pg(stdout,"f B "); 
{int i; 
for (i=1;i<=MAXFORMAT-1;i++) 
 {sprintf(outstr," %1d",format[i]); pg(stdout,outstr);};}; 
pg(stdout,"\n                            "); 
pg(stdout,"                                             h fB\n"); 
pg(stdout,"\n"); 
return; 
 
case 'G': 
pg(stdout,"\nGradient Descent (Plain Backpropagation)\n\n"); 
sprintf(outstr,"e %8.5f %8.5f  ",unscale(eta),unscale(eta2));pg(stdout,outstr); 
pg(stdout,"eta for weights into the output layer is"); 
sprintf(outstr,"%8.5f\n",unscale(eta)); pg(stdout,outstr); 
pg(stdout,"                     eta for weights into the hidden layer(s) is"); 
sprintf(outstr,"%8.5f\n",unscale(eta2)); pg(stdout,outstr); 
pg(stdout,"e              sets both etas to \n\n"); 
 
sprintf(outstr,"a %4.2f               ",unscale(alpha)); pg(stdout,outstr); 
pg(stdout,"the momentum parameter, alpha, for all layers; [0..1)\n\n"); 
 
pg(stdout,"a u C                use this for the right continuous update method\n"); 
pg(stdout,"a u c                use this for the wrong continuous update method\n"); 
pg(stdout,"a u p                use this for the periodic update method\n"); 
pg(stdout,"\n"); 
return; 
 
case 'M': 
pg(stdout,"\nMiscellaneous Commands\n\n"); 
 
if (sysstr[0] != '\0') 
   {pg(stdout,"!               "); pg(stdout,sysstr); pg(stdout,"\n");}; 
pg(stdout,"!       pass  to the operating system\n\n"); 
 
pg(stdout,"q               q by itself quits the program\n\n"); 
 
pg(stdout,"c               clear the network weights\n"); 
pg(stdout,"ci              same as c except the weights are initialized to\n"); 
sprintf(outstr,"                between -%4.2f ",unscale(initrange)); 
pg(stdout,outstr); 
sprintf(outstr,"and %4.2f\n",unscale(initrange)); pg(stdout,outstr); 
pg(stdout,"ci        same as ci except the weights are initialized to\n"); 
pg(stdout,"                between -  and + \n\n"); 
 
sprintf(outstr,"r               run %d iterations",maxiter); pg(stdout,outstr); 
pg(stdout," and print a summary every\n"); 
sprintf(outstr,"                %d iterations\n",printrate); pg(stdout,outstr); 
pg(stdout,"^R              same as r\n"); 
pg(stdout,"r   run  iterations and print a summary every\n"); 
pg(stdout,"                 iterations\n"); 
 
sprintf(outstr,"s %5d",seed); pg(stdout,outstr); 
sprintf(outstr,"         random number seed: %1d\n",seed); pg(stdout,outstr); 
pg(stdout,"\nse    save everything to \n"); 
pg(stdout,"\n"); 
return; 
 
case 'N': 
pg(stdout,"\nNetwork Information\n\n"); 
printnetsize(stdout); 
pg(stdout,"\n"); 
sprintf(outstr,"                 total weights: %1d\n",wttotal); 
pg(stdout,outstr); 
 
pg(stdout,"l         print the unit values in layer \n\n"); 
return; 
 
case 'P': 
pg(stdout,"\nPattern Related Commands\n\n"); 
pg(stdout,"f p g          the problem type; {gc}                             h fp\n"); 
pg(stdout,"f i r          format to input patterns; {cr}                     h fi\n"); 
pg(stdout,"f o r          format to output network values; {acer}            h fo\n\n"); 
 
pg(stdout,"rt {patterns}  reads the patterns between { and }\n"); 
pg(stdout,"rt   read training patterns from \n"); 
pg(stdout,"rx   read more training patterns from \n"); 
pg(stdout,"tf   test file is \n\n"); 
 
pg(stdout,"p              list all training set pattern values\n"); 
pg(stdout,"pa             same as p\n"); 
pg(stdout,"p    evaluate the training pattern\n"); 
pg(stdout,"p0             summarize training pattern learning\n\n"); 
 
pg(stdout,"t              list all test set pattern values\n"); 
pg(stdout,"ta             same as t\n"); 
pg(stdout,"tr        test recurrent patterns                           h tr\n"); 
pg(stdout,"trp       test recurrent patterns and print results         h trp\n"); 
pg(stdout,"t    evaluate the test pattern\n"); 
pg(stdout,"t0             summarize test pattern learning\n\n"); 
 
pg(stdout,"o         prints the target for training pattern \n\n"); 
 
printstats(stdout,TRAIN,1,s); 
if (s[TOL][TEST].npats > 0) printstats(stdout,TEST,1,s); 
pg(stdout,"\n"); 
return; 
 
case 'Q': 
pg(stdout,"\nThe Quickprop Parameters (qp)\n\n"); 
pg(stdout,"qp d      sets quickprop weight decay to  in all layers\n"); 
sprintf(outstr,"qp dh %8.6f  ",unscale(qpdecayh)); pg(stdout,outstr); 
pg(stdout,"quickprop decay for the hidden layer weights; [0..1)\n"); 
sprintf(outstr,"qp do %8.6f  ",unscale(qpdecayo)); pg(stdout,outstr); 
pg(stdout,"quickprop decay for the output layer weights; [0..1)\n"); 
sprintf(outstr,"qp e %6.4f     ",unscale(qpeta)); pg(stdout,outstr); 
pg(stdout,"quickprop eta; (0..inf)\n"); 
sprintf(outstr,"qp m %4.2f       ",unscale(mu)); pg(stdout,outstr); 
pg(stdout,"quickprop acceleration (mu); (1..inf)\n"); 
sprintf(outstr,"qp n %5.3f      ",unscale(qpnoise)); pg(stdout,outstr); 
pg(stdout,"quickprop noise (ibp only); [0..inf)\n"); 
sprintf(outstr,"qp s %c          ",qpslope); pg(stdout,outstr); 
pg(stdout,"include or exclude extra slope term; {+-}\n"); 
pg(stdout,"\na u q           use this to set the quickprop update method\n"); 
pg(stdout,"\n"); 
return; 
 
case 'T': 
pg(stdout,"\nA Tutorial\n\n"); 
pg(stdout,"The following topics are designed to be read in the order listed.\n\n"); 
pg(stdout,"To get help on a topic type the code on the right at the prompt.\n\n"); 
pg(stdout,"Understanding the Menus                                         h1\n"); 
pg(stdout,"Formatting Data for a Classification Problem                    h2\n"); 
pg(stdout,"Formatting Data for Function Approximation                      h3\n"); 
pg(stdout,"Formatting Data for a Recurrent Problem                         h4\n"); 
pg(stdout,"Making a Network for Classification or Function Approximation   h5\n"); 
pg(stdout,"Making a Recurrent Network                                      h6\n"); 
pg(stdout,"Reading the Data                                                h7\n"); 
pg(stdout,"Setting Algorithms and Parameters                               h8\n"); 
pg(stdout,"Running the Program                                             h9\n"); 
pg(stdout,"Saving Almost Everything                                        h10\n"); 
pg(stdout,"To Quit the Program                                             h11\n\n"); 
return; 
 
case 'W': 
pg(stdout,"\nWeights Related Commands\n\n"); 
pg(stdout,"rw               reads weights from the file "); pg(stdout,wtfilename); 
pg(stdout,"\n"); 
pg(stdout,"sw               saves weights to the file "); pg(stdout,wtfilename); 
pg(stdout,"\n"); 
pg(stdout,"rw     reads weights from \n"); 
pg(stdout,"sw     save weights to \n"); 
sprintf(outstr,"                 last save at: %1d\n\n",lastsave); 
pg(stdout,outstr); 
 
pg(stdout,"w   list weights leading into this unit\n\n"); 
 
if (biasset == 1) 
 { 
  sprintf(outstr,"sb %5.2f         ",unscale(stdthresh)); pg(stdout,outstr); 
  pg(stdout,"bias units set to this value\n\n"); 
 } 
else pg(stdout,"sb         set bias weights to \n\n"); 
 
printnetsize(stdout); 
pg(stdout,"\n"); 
sprintf(outstr,"                 total weights: %1d\n",wttotal); 
pg(stdout,outstr); 
 
#ifdef INTEGER 
if (wtlimithit == 1) 
   pg(stdout,"\n            >>>>> WEIGHT LIMIT HIT <<<<<\n"); 
#endif 
pg(stdout,"\n"); 
return; 
 
default: pg(stdout,"not a screen item\n"); 
return; 
}; /* end switch */ 
} 
 
void help() 
{ 
int ch2; 
pg(stdout,"\n"); 
do ch2 = readch(); while (ch2 == ' ' && ch2 != '\n'); 
        switch(ch2) { 
 
default: menus('C'); return; 
 
case '1': 
ch2 = readch(); 
        switch(ch2) { 
case '0': 
pg(stdout,"\n"); 
pg(stdout,"It is possible to use the program by typing in all the commands at the\n"); 
pg(stdout,"keyboard yet it is more convenient to have the basic set up commands for\n"); 
pg(stdout,"a particular problem in a file, have the program read the file and then\n"); 
pg(stdout,"have it take commands from the keyboard.  So if you have a file named\n"); 
pg(stdout,"xor set up you can start the program with:\n"); 
pg(stdout,"\n"); 
pg(stdout,"bp xor\n"); 
pg(stdout,"\n"); 
pg(stdout,"After working with the problem you may reset many parameters.  To save\n"); 
pg(stdout,"the current set of parameters and weights (but not the patterns which\n"); 
pg(stdout,"are normally in files of their own) use the save everything command,\n"); 
pg(stdout,"`se'.  So to save the current state of the program to a file called,\n"); 
pg(stdout,"say, new, do:\n"); 
pg(stdout,"\n"); 
pg(stdout,"se new\n"); 
pg(stdout,"\n"); 
pg(stdout,"The file new will be virtually identical to the listing you get with\n"); 
pg(stdout,"the `?' command.  Later on you can restart the problem with:\n"); 
pg(stdout,"\n"); 
pg(stdout,"bp new\n"); 
pg(stdout,"\n"); 
return; 
 
case '1': 
pg(stdout,"In DOS and UNIX type `q' at the command line prompt.\n\n"); 
pg(stdout,"In DOS you can hit the escape key to stop a training run.\n\n"); 
pg(stdout,"In DOS and UNIX you can hit ctrl-C to stop anything and get to the\n"); 
pg(stdout,"command prompt.  When used in a DOS window under Windows this may\n"); 
pg(stdout,"produce an error message as well as stopping the program.\n\n"); 
return; 
 
case '\n': 
bufferptr = bufferptr - 1; 
pg(stdout,"Understanding the Menus\n\n"); 
pg(stdout,"First, this program includes a paging algorithm similar to more.  When\n"); 
pg(stdout,"you get the string:\n"); 
pg(stdout,"\n"); 
pg(stdout,"More?\n"); 
pg(stdout,"\n"); 
pg(stdout,"at the bottom of the screen you can get one more page by hitting the\n"); 
pg(stdout,"space bar, one more line by hitting the carriage return, half a page\n"); 
pg(stdout,"with ctrl-D, a c will continue without paging and in most cases typing\n"); 
pg(stdout,"a q will stop the paging.  There is no scrolling backwards.\n\n"); 
pg(stdout,"While the program does not use a mouse or windows it does have menus to\n"); 
pg(stdout,"make it easy to see what the commands are.  One typical menu is the F\n"); 
pg(stdout,"for format menu, so if you type F at the command prompt you get:\n\n"); 
pg(stdout,"The Format Command (f)\n\n"); 
pg(stdout,"f b -         ring the bell when training is finished; {+-}\n"); 
pg(stdout,"f c +         make a copy of screen i/o on the file copy; {+-}\n"); 
pg(stdout,"f e -         echo input; {+-}\n"); 
pg(stdout,"f i r         format for reading input and output patterns; {cr}         h fi\n\n"); 
pg(stdout,"plus there is more that has been deleted but these four lines show enough.\n"); 
pg(stdout,"The first column gives the command and the current value of the parameter.\n"); 
pg(stdout,"In the `f b -' string, the `f' is the general format command that\n"); 
pg(stdout,"includes many sub-commands.  The `b' sub-command controls the ringing\n"); 
pg(stdout,"of the bell when the program finishes learning.  With the `-' it is off.\n"); 
pg(stdout,"The middle portion of the screen gives the function involved with the\n"); 
pg(stdout,"command.  Characters at the end within { and } list the possible options.\n"); 
pg(stdout,"For ringing the bell it is on or off, `+' or `-'.  In the `f i r' the\n"); 
pg(stdout,"explanation for c and r within the { and } can be found by typing `h f i'\n"); 
pg(stdout,"at the normal command prompt.  To change the settings you only have to\n"); 
pg(stdout,"type the command string in the left column but with the new parameter\n"); 
pg(stdout,"setting.\n\n"); 
pg(stdout,"In many cases the command parameters are numbers.  The range of values\n"); 
pg(stdout,"that the parameter can take on are given using [, ], (, and ).  If the\n"); 
pg(stdout,"range listed is: [0..1) the [ next to 0 means that the lowest possible\n"); 
pg(stdout,"value allowed is exactly 0 while the ) indicates that you can get very\n"); 
pg(stdout,"close to 1 but never exactly 1.\n\n"); 
pg(stdout,"In some cases the leftmost column will code a possible command parameter\n"); 
pg(stdout,"using some name within < and >.  For instance there are these two\n"); 
pg(stdout,"examples:\n\n"); 
pg(stdout,"qp d      sets quickprop weight decay to  in all layers\n\n"); 
pg(stdout,"sw     save weights to \n"); 
pg(stdout,"\n"); 
pg(stdout,"In the first case it means that to set the quickprop decay in all layers\n"); 
pg(stdout,"to some value you type `qp d' and some real number as in:\n\n"); 
pg(stdout,"qp d 0.0001\n\n"); 
pg(stdout,"In the second example the command means save the weight to some filename\n"); 
pg(stdout,"so type the name in place of `'.\n\n"); 
return; 
 
default: pg(stdout,"not a help item\n\n"); 
return; 
         };  /* end the inner switch */ 
 
case '2': 
pg(stdout,"The normal way to operate this program is to have the training data\n"); 
pg(stdout,"in one file and if there is test set data it should be in another file.\n\n"); 
pg(stdout,"For a plain classification program, with say four inputs and 3 possible\n"); 
pg(stdout,"classes the data file will look like:\n\n"); 
pg(stdout,"0.4  0.3   0.33 0.21    1  * this is a class 1 pattern\n"); 
pg(stdout,"0.55 0.32 -0.09 0.20    2  * this is a class 2 pattern\n"); 
pg(stdout,"0.11 0.23 -0.97 0.45    3  * this is a class 3 pattern\n\n"); 
pg(stdout,"where the first four numbers are the input and the last number is the\n"); 
pg(stdout,"class number.  If there are a large number of inputs you can use more\n"); 
pg(stdout,"than one line for each pattern but you should start every new pattern\n"); 
pg(stdout,"on a new line.  The asterisk at the end of the line begins a comment.\n\n"); 
pg(stdout,"It is also possible to type the data in as commands but this is\n"); 
pg(stdout,"generally not a good idea unless you have a very small data set\n"); 
pg(stdout,"because you will probably make many mistakes when typing the data\n"); 
pg(stdout,"in.\n\n"); 
return; 
 
case '3': 
pg(stdout,"The normal way to operate this program is to have the training data\n"); 
pg(stdout,"in one file and if there is test set data it should be in another file.\n\n"); 
pg(stdout,"For a function approximation program with say five inputs and 1 output\n"); 
pg(stdout,"the data should look like:\n\n"); 
pg(stdout,"  -1.588   -1.650     0.365     0.188     0.962   -1.543\n"); 
pg(stdout,"  -1.182   -0.926     0.992     0.188     1.140   -1.372\n"); 
pg(stdout,"  -2.650   -1.650     3.501     0.188    -0.566   -1.201\n\n"); 
pg(stdout,"where the first five numbers are the input and the last number is the\n"); 
pg(stdout,"answer.  If there are a large number of inputs you can use more\n"); 
pg(stdout,"than one line for each pattern but you should start every new pattern\n"); 
pg(stdout,"on a new line.\n\n"); 
pg(stdout,"It is also possible to type the data in as commands but this is\n"); 
pg(stdout,"generally not a good idea unless you have a very small data set because\n"); 
pg(stdout,"you will probably make many mistakes when typing the data in.\n\n"); 
return; 
 
case '4': 
pg(stdout,"The normal way to operate this program is to have the training data\n"); 
pg(stdout,"in one file and if there is test set data it should be in another file.\n\n"); 
pg(stdout,"For a recurrent network problem, with say four inputs and 4 possible\n"); 
pg(stdout,"outputs the data file will look like:\n\n"); 
pg(stdout,"1 0 0 0   H   0 0 1 0\n"); 
pg(stdout,"0 0 1 0   H   0 1 0 0\n"); 
pg(stdout,"0 1 0 0   H   0 0 1 0\n"); 
pg(stdout,"0 0 1 0   H   0 0 0 1\n\n"); 
pg(stdout,"where the first four numbers are the input, the H stands for the values\n"); 
pg(stdout,"of the hidden layer units that are copied down to the input and the last\n"); 
pg(stdout,"four numbers are the output.  If there are a large number of inputs you\n"); 
pg(stdout,"can use more than one line for each pattern but you should start every\n"); 
pg(stdout,"new pattern on a new line.\n\n"); 
pg(stdout,"It is also possible to type the data in as commands but this is\n"); 
pg(stdout,"generally not a good idea unless you have a very small data set\n"); 
pg(stdout,"because you will probably make many mistakes when typing the data in.\n\n"); 
return; 
 
case '5': 
pg(stdout,"The command to type in to make a network with four inputs, three\n"); 
pg(stdout,"hidden layer units and two output units is:\n\n"); 
pg(stdout,"m 4 3 2\n\n"); 
pg(stdout,"In many cases adding extra connections from the input units to the\n"); 
pg(stdout,"output units will produce faster training.  If you wanted to use the\n"); 
pg(stdout,"extra connections type in:\n\n"); 
pg(stdout,"m 4 3 2 x\n\n"); 
pg(stdout,"NOTE: there is no way to know ahead of time how many hidden units will\n"); 
pg(stdout,"be needed or if hidden units will be needed at all.\n\n"); 
pg(stdout,"NOTE: when patterns are read in they are attached to the network\n"); 
pg(stdout,"structure so if you make a different size network, such as a 4-5-2\n"); 
pg(stdout,"network after the patterns are read in the patterns will be lost and\n"); 
pg(stdout,"you will have to read them in again.\n\n"); 
return; 
 
case '6': 
pg(stdout,"The command to type in to make a recurrent network with four normal\n"); 
pg(stdout,"input units and three more input units that have values copied from\n"); 
pg(stdout,"the three hidden layer units and with two output units is:\n\n"); 
pg(stdout,"m 4+3 3 2\n\n"); 
pg(stdout,"The 3 in the `4+3' portion must be the same value as the 3 following it.\n\n"); 
return; 
 
case '7': 
pg(stdout,"If you're doing a classification type problem it is important to first\n"); 
pg(stdout,"let the program know that using the `f' (format) command so the last\n"); 
pg(stdout,"number can be interpreted as the class number, use:\n\n"); 
pg(stdout,"f p c   * the problem type is classification\n\n"); 
pg(stdout,"If you're doing a function approximation type of problem, do nothing\n"); 
pg(stdout,"since the default setting (g, for general) will work.\n\n"); 
pg(stdout,"To read in the training set data from some file called, say train is:\n\n"); 
pg(stdout,"rt train   * rt is for read training\n\n\n"); 
pg(stdout,"To read in any test set data from some file called, say, test is:\n\n"); 
pg(stdout,"tf test    * tf is for test file\n\n\n"); 
pg(stdout,"For other ways to read in data see the manual.\n\n"); 
return; 
 
case '8': 
pg(stdout,"There are many algorithms that can be tried and there are many\n"); 
pg(stdout,"parameters for each algorithm that can be varied, some algorithms and\n"); 
pg(stdout,"values produce faster training while others may produce better\n"); 
pg(stdout,"generalization.  So far there is no way to know ahead of time which\n"); 
pg(stdout,"algorithms and values are best.  The fastest training algorithm in this\n"); 
pg(stdout,"program is quickprop.  To get fairly good results set the quickprop eta\n"); 
pg(stdout,"parameter to about 1 / n where n is the number of patterns in the\n"); 
pg(stdout,"training set.  So if n = 100 type in:\n\n"); 
pg(stdout,"qp e 0.01   * sets the quickprop eta to 0.01\n\n"); 
pg(stdout,"and set the algorithm to use to quickprop with the algorithm command:\n\n"); 
pg(stdout,"a uq   * sets the update algorithm to quickprop.\n\n"); 
pg(stdout,"This will probably work well (NO GUARANTEE) with the other default\n"); 
pg(stdout,"parameters in the program.\n\n"); 
 
pg(stdout,"If you need outputs beyond the range of 0 to 1 use the algorithm\n"); 
pg(stdout,"command to make the output layer linear:\n\n"); 
pg(stdout,"a aol   * activation function for the output layer is linear\n\n"); 
return; 
 
case '9': 
pg(stdout,"\n"); 
pg(stdout,"Normally you want to initialize the weights in the network with small random\n"); 
pg(stdout,"values.  This is done with the clear and initialize command, type in:\n"); 
pg(stdout,"\n"); 
pg(stdout,"ci   * ci for clear and initialize\n"); 
pg(stdout,"\n"); 
pg(stdout,"Having done that you can run the training program by typing `r' and a\n"); 
pg(stdout,"carriage return or by typing ctrl-R.  Doing this applies the training\n"); 
pg(stdout,"algorithm for up to 100 passes through the training set data and lists\n"); 
pg(stdout,"the status of the training set and the test set if it exists.  For the\n"); 
pg(stdout,"sonar data included in the sample data the listing will look like:\n"); 
pg(stdout,"\n"); 
pg(stdout,"   10     49.04 %  49.04 % 0.47063      62.50 %  62.50 % 0.38221 \n"); 
pg(stdout,"   20     70.19 %  73.08 % 0.38548      77.88 %  77.88 % 0.38063 \n"); 
pg(stdout,"   30     76.92 %  76.92 % 0.34943      77.88 %  80.77 % 0.33282 \n"); 
pg(stdout,"\n"); 
pg(stdout,"The first column is the iteration number, the second column gives the\n"); 
pg(stdout,"percentage of training set patterns right based on the tolerance the\n"); 
pg(stdout,"third column gives the percentage right based on the maximum value, the\n"); 
pg(stdout,"fourth column gives the abs (not RMS!) error.  The fifth column is the\n"); 
pg(stdout,"percentage of test set patterns right based on the tolerance, the sixth\n"); 
pg(stdout,"column gives the percentage right based on maximum value and the last\n"); 
pg(stdout,"column gives the abs error.\n"); 
pg(stdout,"\n"); 
return; 
 
case 'a': 
do ch2 = readch(); while (ch2 == ' '); 
if (ch2 == 'd') 
 { 
  pg(stdout,"a d c uses the original (correct) derivative.\n\n"); 
  pg(stdout,"a d d uses the differential step derivative in the output layer.\n"); 
  pg(stdout,"a d f uses Fahlman's derivative in the output layer.\n"); 
  pg(stdout,"a d o uses the original (correct) derivative.\n\n"); 
 } 
else if (ch2 == 'a') 
 { 
pg(stdout,"a a  sets every activation function to .\n"); 
pg(stdout,"a ah  sets the hidden layer activation function to .\n"); 
pg(stdout,"a ao  sets the output layer activation function to ,\n"); 
pg(stdout," can be any of the following:\n\n"); 
 
pg(stdout,"                  Function                           Range\n\n"); 
 
pg(stdout,"   l    linear function, x                             (-inf..+inf)\n"); 
pg(stdout,"   s    standard sigmoid, 1 / (1 + exp(-x))               (0..+1)\n"); 
 } 
else if (ch2 == 'u') 
 { 
  pg(stdout,"a u C gives the \"right\" continuous update method.\n"); 
  pg(stdout,"a u c gives the \"wrong\" continuous update method.\n"); 
#ifndef SYMMETRIC 
  pg(stdout,"a u d gives the delta-bar-delta update method.\n"); 
#endif 
  pg(stdout,"a u p gives the periodic update method.\n"); 
#ifndef SYMMETRIC 
  pg(stdout,"a u q gives the quickprop update method.\n"); 
#endif 
 } 
else texterror(); /* end of the 'a' case */ 
break; 
 
case 'f': 
do ch2 = readch(); while (ch2 == ' '); 
if (ch2 == 'B') 
 { 
pg(stdout,"B   ...  ...  puts a carriage return\n"); 
pg(stdout,"          after each  values when the output format is real\n"); 
pg(stdout,"          and inserts a blank after each  value if the\n"); 
pg(stdout,"          format is condensed.\n\n"); 
 } 
else if (ch2 == 'i') 
 { 
  pg(stdout,"i c will read pattern values using compressed format.\n"); 
  pg(stdout,"i r will read pattern values as reals.\n\n"); 
 } 
else if (ch2 == 'o') 
 { 
  pg(stdout,"o a will write node values as analog compressed.\n"); 
  pg(stdout,"o c will write node values as compressed.\n"); 
  pg(stdout,"o e will write node values with e notation.\n"); 
  pg(stdout,"o r will write node values as real.\n\n"); 
 } 
else if (ch2 == 'p') 
 { 
  pg(stdout,"p c will read patterns in the classification format.\n"); 
  pg(stdout,"p g will accept general patterns.\n\n"); 
 } 
else texterror(); 
break; 
 
case 't': 
do ch2 = readch(); while (ch2 == ' '); 
if (ch2 == 'r') 
 { 
  pg(stdout,"tr  in a recurrent network takes each training set pattern\n"); 
  pg(stdout,"        and its  - 1 following patterns and predicts the\n"); 
  pg(stdout,"         + 1st pattern\n"); 
  pg(stdout,"trp  does the same and prints the predicted patterns\n"); 
 } 
else texterror(); 
break; 
     }; /* end switch */ 
pg(stdout,"\n"); 
}