home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume28 / backprop / part02 / bp.c
Encoding:
C/C++ Source or Header  |  1992-02-23  |  36.9 KB  |  1,528 lines

  1. /* ************************************************** */
  2. /* file bp.c:  contains the main program and network  */
  3. /*             creation routines.                     */
  4. /*                                                    */
  5. /* Copyright (c) 1991 by Donald R. Tveter             */
  6. /*                                                    */
  7. /* ************************************************** */
  8.  
  9. #include <stdio.h>
  10. #include <signal.h>
  11. #include <setjmp.h>
  12.  
  13. #ifdef DOS16
  14. #include <stdlib.h>
  15. #include <time.h>
  16. #endif
  17.  
  18. #ifdef DOS32
  19. #include <stdlib.h>
  20. #include <time.h>
  21. #endif
  22.  
  23. #ifdef UNIX
  24. #include <malloc.h>
  25. #define SIGINT 2
  26. #define CLOCKS_PER_SEC 1000000.0
  27. extern long clock();
  28. #endif
  29.  
  30. #ifdef INTEGER
  31. #include "ibp.h"
  32. #else
  33. #include "rbp.h"
  34. #endif
  35.  
  36. /* an addition for large data sets */
  37.  
  38. INT32 g = 0;
  39.  
  40. /* built-in C functions */
  41.  
  42. extern int rand();
  43. extern void srand();
  44.  
  45. /* functions from io.c */
  46.  
  47. #ifdef INTEGER
  48. extern int scale();
  49. extern REAL unscale();
  50. #endif
  51.  
  52. extern void help(), printweights();
  53. extern void restoreweights(), saveweights(), texterror();
  54. extern WTTYPE rdr();
  55. extern int pg(), printoutunits(), readch(), readint();
  56. extern REAL readchar();
  57. extern char *readstr();
  58.  
  59. /* functions from misc.c */
  60.  
  61. extern void clear(), nullpatterns(), findendofpats(), kick();
  62. extern void setonepat(), setoutputpat(), whittle();
  63. extern int loadpat(), patcheck(), run();
  64.  
  65. /* global variables used in all versions */
  66.  
  67. char activation;      /* activation function, p or s */
  68. WTTYPE alpha;         /* momentum term */
  69. char backprop;        /* flags whether to back propagate error for */
  70.                       /* units close to their targets */
  71. int benchmark;        /* flags benchmarking in progress */
  72. int bufferend;        /* index of last character in input line */
  73. int bufferptr;        /* position of next character in buffer */
  74. char buffer[buffsize];/* holds contents of one input line */
  75. int ch;               /* general purpose character variable */
  76. FILE *copy;           /* file pointer to copy file */
  77. char copyflag;        /* + for copying, - for no copy */
  78. jmp_buf cmdloopstate; /* to save state in case of a SIGINT */
  79. WTTYPE D;             /* sigmoid sharpness */
  80. FILE *data;           /* file for original data */
  81. char *datafilename;   /* copy of the data file name saved here */
  82. WTTYPE dbdeta;        /* the initial eta value for the DBD method */
  83. WTTYPE decay;         /* the decay parameter for the DBD method */
  84. char deriv;           /* flags type of derivative to use */
  85. char echo;            /* controls echoing of characters during input */
  86. char emptystring;     /* for unused string values */
  87. REAL errorperunit;    /* average unsquared error on output layer */
  88. WTTYPE eta;           /* basic learning rate */
  89. WTTYPE eta2;          /* learning rate for lower layers */
  90. WTTYPE etamax;        /* the maximum eta for the DBD method */
  91. int extraconnect;     /* flags the use of connections between */
  92.                       /* non-adjacent layers */
  93. FILE *filestack[4];   /* allows for nested reads from files */
  94. int filestackptr;     /* has the index of the current file */
  95. int format[maxformat];/* each value in format indicates where to put */
  96.                       /* a blank for compressed output mode or a */
  97.                       /* carriage return for real output */
  98. int goal;             /* successes desired when benchmarking */
  99. UNIT *hlayer;         /* pointer to list of units in second layer */
  100. UNIT *ilayer;         /* pointer to list of units in third layer */
  101. char informat;        /* controls format to read numbers */
  102. WTTYPE initialkick;   /* the range weights are initialized to */
  103. char *inputfile;      /* name of file to take extra commands from */
  104. int iter;             /* for counting iterations in one run */
  105. UNIT *jlayer;         /* pointer to list of units in fourth layer */
  106. WTTYPE kappa;         /* the DBD learning parameter */
  107. UNIT *klayer;         /* pointer to list of units in fifth layer */
  108. WTTYPE kicksize;      /* range of random weights when benchmarking */
  109. LAYER *last;          /* has address of the output layer */
  110. int lastprint;        /* last iteration pattern responses printed */
  111. int lastsave;         /* last time weights were saved */
  112. INT32 lineno;         /* counts lines for paging */
  113. int maxiter;          /* maximum iterations when benchmarking */
  114. int maxtries;         /* max networks to try when benchmarking */
  115. short nlayers;        /* number of layers in network */
  116. WTTYPE noise;         /* noise parameter for dbd and qp */
  117. int npats;            /* number of patterns currently in use */
  118. char outformat;       /* controls format to print output */
  119. char outstr[OUTSTRSIZE]; /* the output string */
  120. int pagesize;         /* size of page for pg */
  121. char patform;         /* flags general or classification pattern format */
  122. REAL pct_right;       /* % of training patterns correct */
  123. int prevnpats;        /* previous number of patterns, initially 0 */
  124. int printrate;        /* printrate when benchmarking */
  125. WTTYPE qmark;         /* value for ? in compressed input */
  126. int readerror;        /* flags an error in reading a value */
  127. int readingpattern;   /* flags reading pattern state */
  128. char ringbell;        /* flag to ring bell when finished */
  129. int right;            /* number of training patterns learned */
  130. int saverate;         /* rate at which to save weights */
  131. unsigned seed;        /* seed for generating random weights */
  132. SEEDNODE *seedstart;  /* the list of user defined seeds */
  133. short skiprate;       /* number of times to bypass a learned pattern */
  134. LAYER *start;         /* has address of the input layer */
  135. char summary;         /* flags summary output mode */
  136. int testpat;          /* pattern to skip when benchmarking; else 0 */
  137. char *testfile;       /* file to take test patterns from */
  138. WTTYPE theta1;        /* the DBD parameter */
  139. WTTYPE theta2;        /* 1 - theta1 */
  140. WTTYPE toler;         /* value used in testing for completion */
  141. WTTYPE toosmall;      /* weights smaller than toosmall were removed */
  142. #ifdef INTEGER
  143. INT32 totaldiff;      /* totals errors to find average error per unit */
  144. #else
  145. REAL totaldiff;
  146. #endif
  147. int totaliter;        /* counts total iterations for the program */
  148. char *trainfile;      /* file to take training patterns from */
  149. int unlearned;        /* number unlearned in last learning cycle */
  150. char update;          /* flags type of update rule to use */
  151. char up_to_date_stats;/* + does an extra forward pass after update */
  152. int wrong;            /* number of training patterns unlearned */
  153. char w[8] = "weights";/* the string, weights */
  154. char *wtfile;         /* file to write weights to */
  155. char wtformat;        /* controls format to save and restore weights */
  156. char wtlimithit;      /* flags whether the limit has been hit */
  157. int wttotal;          /* total number of weights in use */
  158.  
  159. /* global variable for the symmetric integer version */
  160.  
  161. #ifdef SYMMETRIC
  162. WTTYPE  stdthresh;    /* the standard threshold weight value */
  163. #endif
  164.  
  165. /* given a layer no. and unit no. locateunit returns the address */
  166. UNIT *locateunit(layerno,unitno)
  167. int layerno, unitno;
  168. {int i;
  169.  UNIT *u;
  170.  LAYER *layer;
  171.  
  172. layer = start;
  173. for(i=1;i<=(layerno-1);i++) layer = layer->next;
  174. u = (UNIT *) layer->units;
  175. while (u != NULL && u->unitnumber != unitno) u = u->next;
  176. if (u == NULL)
  177.   printf("there is no unit %3d in layer %3d\n",unitno,layerno);
  178. return(u);     
  179. }
  180.  
  181. #ifdef SYMMETRIC
  182.  
  183. INT32 wtaddress(i,j,biasunit,type,size) /* Returns the address of a */
  184. int i,j;                                /* weight (1), olddw (2),   */
  185. int biasunit;                           /* eta (3), total (4),      */
  186. int type;                               /* or slope (5)             */
  187. int size;                               /* One is created if it     */
  188.                                         /* doesn't already exist.   */
  189. { int k;
  190.   INT32 addr;
  191.   UNIT *u;
  192.   WTNODE *w;
  193.  
  194. if (biasunit) addr = (INT32) malloc(size);
  195. else if (j >= i) addr = (INT32) malloc(size);
  196. else /* the item already exists, so find its address */
  197.  {
  198.   u = locateunit(2,j);
  199.   w = (WTNODE *) u->wtlist;
  200.   k = 1;
  201.   while (k < i)
  202.    {
  203.     w = w->next;
  204.     k = k + 1;
  205.    };
  206.   if (type == 1) addr = (INT32) w->weight;
  207.   else if (type == 2) addr = (INT32) w->olddw;
  208.   else if (type == 3) addr = (INT32) w->eta;
  209.   else if (type == 4) addr = (INT32) w->total;
  210.   else addr = (INT32) w->slope;
  211.  };
  212. return(addr);
  213. }
  214.  
  215. void setweight(w,i,j,biasunit) /* set initial values in w */
  216. WTNODE *w;
  217. short i, j;
  218. int biasunit;
  219. {WTTYPE *s;
  220.  
  221. s = (WTTYPE *) wtaddress(i,j,biasunit,1,WTSIZE);
  222. *s = 0;
  223. w->weight = s;
  224. s = (WTTYPE *) wtaddress(i,j,biasunit,2,WTSIZE);
  225. *s = 0;
  226. w->olddw = s;
  227. s = (WTTYPE *) wtaddress(i,j,biasunit,3,WTSIZE);
  228. *s = eta;
  229. w->eta = s;
  230. #ifdef INTEGER
  231. w->total = (INT32 *) wtaddress(i,j,biasunit,4,sizeof(INT32));
  232. #else
  233. w->total = (REAL *) wtaddress(i,j,biasunit,4,sizeof(REAL));
  234. #endif
  235. }
  236.  
  237. #else
  238.  
  239. void setweight(w,i,j,biasunit) /* set initial values in w */
  240. WTNODE *w;
  241. short i,j;
  242. int biasunit;
  243. {
  244. w->weight = 0;
  245. w->olddw = 0;
  246. w->slope = 0;
  247. w->eta = dbdeta;
  248. }
  249.  
  250. #endif
  251.  
  252. LAYER *mklayer(prevlayer,n)  /* creates a layer of n units, pointers */
  253. LAYER *prevlayer;            /* and weights back to the units in the */
  254. int n;                       /* previous layer and links this new */
  255.                              /* layer into the list of layers */
  256. {UNIT *front, *p, *q, *bias, *prev, *ptr;
  257.  WTNODE *wfront, *wprev, *w;
  258.  LAYER *lptr;
  259.  int i, j, count;
  260.  
  261. /* make a list of nodes in this layer */
  262.  
  263. count = 1;
  264. front = (UNIT *) malloc(sizeof(UNIT));
  265. front->unitnumber = count;
  266. front->layernumber = nlayers;
  267. prev = front;
  268. for(i=1;i<n;i++)
  269.  {
  270.   count = count + 1;
  271.   ptr = (UNIT *) malloc(sizeof(UNIT));
  272.   prev->next = ptr;
  273.   ptr->unitnumber = count;
  274.   ptr->layernumber = nlayers;
  275.   prev = ptr;
  276.  };
  277. prev->next = NULL;
  278.  
  279. /* make a LAYER node to point to this list of units */
  280.  
  281. lptr = (LAYER *) malloc(sizeof(LAYER));
  282. lptr->unitcount = n;
  283. lptr->patstart = NULL;
  284. lptr->currentpat = NULL;
  285. lptr->backlayer = prevlayer;
  286. lptr->next = NULL;
  287. (UNIT *) lptr->units = front;   /* connect the list of units */
  288.  
  289. /* return if this is the input layer */
  290.  
  291. if (prevlayer == NULL) return(lptr);
  292. prevlayer->next = lptr;
  293.  
  294. /* If we are working on a deeper layer, for every node in this layer, */
  295. /* create a linked list back to units in the previous layer. */
  296.  
  297. i = 1;
  298. q = front;
  299. while (q != NULL) /* do a unit */
  300.  {    
  301.   j = 1;            /* handle first connection */
  302.   p = (UNIT *) prevlayer->units;
  303.   wfront = (WTNODE *) malloc(sizeof(WTNODE));
  304.   wttotal = wttotal + 1;
  305.   (WTNODE *) q->wtlist = wfront;
  306.   wprev = wfront;
  307.   (UNIT *) wfront->backunit = p;
  308.   setweight(wfront,i,j,0);
  309.   p = p->next;
  310.   while (p != NULL) /* handle rest of connections */
  311.    {
  312.     j = j + 1;
  313.     w = (WTNODE *) malloc(sizeof(WTNODE));
  314.     wttotal = wttotal + 1;
  315.     wprev->next = w;
  316.     (UNIT *) w->backunit = p;
  317.     setweight(w,i,j,0);
  318.     wprev = w;
  319.     p = p->next;
  320.    };
  321.   j = j + 1;
  322.   bias = (UNIT *) malloc(sizeof(UNIT));   /* create a bias unit */
  323.   bias->oj = scale(1.0);
  324.   bias->layernumber = nlayers;
  325.   bias->unitnumber = 32767;           /* bias unit is unit 32767 */
  326.   w = (WTNODE *) malloc(sizeof(WTNODE)); /* connect to end of list */
  327.   wttotal = wttotal + 1;
  328.   wprev->next = w;
  329.   (UNIT *) w->backunit = bias;
  330.   setweight(w,n+2,i,1);
  331.   w->next = NULL;
  332.   q = q->next;
  333.   i = i + 1;
  334.  };
  335. return(lptr);
  336. }
  337.  
  338. #ifndef SYMMETRIC
  339.  
  340. void connect(a,b,range)  /* add a connection from unit a to unit b */
  341. UNIT *a, *b;             /* connections go in increasing order */
  342. WTTYPE range;
  343.  
  344. {WTNODE *wnew, *w, *wprev;
  345.  UNIT *wunit;
  346.  int farenough;
  347.  
  348. wnew = (WTNODE *) malloc(sizeof(WTNODE));
  349. wttotal = wttotal + 1;
  350. wnew->eta = dbdeta;
  351. wnew->weight = range * rand() / 32768;
  352. if (rand() > 16383) wnew->weight = -wnew->weight;
  353. wnew->olddw = 0;
  354. wnew->slope = 0;
  355. (UNIT *) wnew->backunit = a;
  356. w = (WTNODE *) b->wtlist;
  357. wprev = NULL;
  358. wunit = (UNIT *) w->backunit;
  359. farenough = 0;                  /* insert the weight in order */
  360. while (w != NULL && !farenough)
  361.  if (wunit->layernumber > a->layernumber) farenough = 1;
  362.  else if (wunit->layernumber == a->layernumber)
  363.   while (w != NULL && !farenough)
  364.    {
  365.     if (wunit->unitnumber < a->unitnumber &&
  366.         wunit->layernumber == a->layernumber)
  367.      {
  368.       wprev = w;
  369.       w = w->next;
  370.       wunit = (UNIT *) w->backunit;
  371.      }
  372.     else farenough = 1;
  373.    }
  374.   else
  375.    {
  376.     wprev = w;
  377.     w = w->next;
  378.     wunit = (UNIT *) w->backunit;
  379.    };
  380. if (wprev == NULL)
  381.  {
  382.   wnew->next = w;
  383.   (WTNODE *) b->wtlist = wnew;
  384.  }
  385. else
  386.  {
  387.   wnew->next = w;
  388.   wprev->next = wnew;
  389.  };
  390. }
  391.  
  392. void addhiddenunit(layerno,range)
  393. int layerno;  /* add hidden unit to end of the layer */
  394. WTTYPE range;
  395. {
  396.  LAYER *lptr, *prevlayer, *nextlayer;
  397.  UNIT *u, *prevu, *p, *bias;
  398.  WTNODE *wnode;
  399.  int i, unitno;
  400.  
  401. lptr = start;
  402. for (i=1;i <= (layerno - 1); i++) lptr = lptr->next;
  403. unitno = lptr->unitcount;
  404. lptr->unitcount = unitno + 1;
  405. prevu = locateunit(layerno,unitno);
  406. if (prevu == NULL) return;
  407. u = (UNIT *) malloc(sizeof(UNIT));
  408. prevu->next = u;
  409. u->next = NULL;
  410. u->unitnumber = unitno + 1;
  411. u->layernumber = layerno;
  412. bias = (UNIT *) malloc(sizeof(UNIT));
  413. bias->oj = scale(1.0);
  414. bias->layernumber = layerno;
  415. bias->unitnumber = 32767;           /* bias unit is unit 32767 */
  416. wnode = (WTNODE *) malloc(sizeof(WTNODE));
  417. wttotal = wttotal + 1;
  418. wnode->weight = range * rand() / 32768;
  419. if (rand() > 16383) wnode->weight = -wnode->weight;
  420. wnode->olddw = 0;
  421. wnode->slope = 0;
  422. wnode->eta = dbdeta;
  423. wnode->next = NULL;
  424. (UNIT *) wnode->backunit = bias;
  425. (WTNODE *) u->wtlist = wnode;
  426. prevlayer = lptr->backlayer;
  427. p = (UNIT *) prevlayer->units;
  428. while (p != NULL)
  429.  {
  430.   connect(p,u,range);
  431.   p = p->next;
  432.  };
  433. nextlayer = lptr->next;
  434. p = (UNIT *) nextlayer->units;
  435. while (p != NULL)
  436.  {
  437.   connect(u,p,range);
  438.   p = p->next;
  439.  };
  440. }      
  441.  
  442. #endif
  443.  
  444. void readpatson(layer,command)
  445. LAYER *layer;
  446. int command;
  447.  
  448. {PATLIST *pl;
  449.  int i, answer, veclength;
  450.  WTTYPE *val;
  451.  
  452. pl = (PATLIST *) malloc(sizeof(PATLIST));
  453. pl->next = NULL;
  454. pl->bypass = 0;      /* number of times to bypass this pattern */
  455. pl->pats = NULL;     /* no patterns read yet */
  456. if (layer->patstart == NULL) (PATLIST *) layer->patstart = pl;
  457. else layer->currentpat->next = pl;
  458. layer->currentpat = pl;
  459.  
  460. if (layer == last && (patform == 'c' || patform == 'C'))
  461.  {
  462.   answer = readint(1,last->unitcount,command);
  463.   if (readerror) return;
  464.   val = (WTTYPE *) malloc(sizeof(WTTYPE));
  465.   *val = answer;
  466.   pl->pats = val;
  467.   return;
  468.  };
  469. veclength = layer->unitcount;
  470. val = (WTTYPE *) malloc(veclength * sizeof(WTTYPE));
  471. pl->pats = val;
  472. for (i=1;i<=veclength;i++)
  473.  {
  474.   if (informat == 'r') *val++ = rdr(GE,(REAL) HCODE,command);
  475.   else *val++ = scale(readchar());
  476.   if (readerror)
  477.    {
  478.     if (readerror == 2 && i == 1) readerror = 2; else readerror = 1;
  479.     return;
  480.    };
  481.  };
  482. return;
  483. }
  484.  
  485. int readpats(number,command)
  486. int number, command;
  487. { int i, j;
  488.   PATLIST *pl;
  489.  
  490. for (i=1;i<=number;i++)
  491.  {
  492.   readpatson(start,command);
  493.   if (readerror == 1) goto failure;
  494.   if (readerror == 2) /* EOF */ break;
  495.   readpatson(last,command);
  496.   if (readerror) goto failure;
  497.  };
  498. if (readerror == 0) return(number);
  499. else if (readerror == 2)
  500.  {
  501.   popfile();
  502.   return(i-1);
  503.  };
  504.  
  505. failure:
  506. printf("error while reading pattern %d\n",i);
  507. popfile();
  508. pl = (PATLIST *) start->patstart;
  509. for (j=1;j<=prevnpats + i - 2;j++) pl = pl->next;
  510. pl->next = NULL;
  511. pl = (PATLIST *) last->patstart;
  512. for (j=1;j<=prevnpats + i - 2;j++) pl = pl->next;
  513. pl->next = NULL;
  514. return(i-1);
  515. }
  516.  
  517. void init()
  518. {int i;
  519.  
  520. activation = 'p';
  521. alpha = scale(0.5);
  522. backprop = 1;
  523. benchmark = 0;
  524. bufferend = 0;
  525. bufferptr = buffsize + 1;
  526. ch = ' ';
  527. copyflag = '-';            /* default is to not make a copy */
  528. D = scale(1.0);
  529. dbdeta = scale(0.5);
  530. decay = scale(0.5);
  531. deriv = 'd';
  532. echo = '-';
  533. eta = scale(0.5);
  534. eta2 = eta;
  535. etamax = scale(30.0);
  536. extraconnect = 0;
  537. format[0] = 0;
  538. for(i=1;i<=maxformat-1;i++) format[i] = format[i-1] + 10;
  539. goal = 10;
  540. informat = 'c';
  541. initialkick = -1;
  542. kappa = scale(0.5);
  543. kicksize = scale(1.0);
  544. lastprint = 0;
  545. lastsave = 0;
  546. maxiter = 1000;
  547. maxtries = 10;
  548. noise = 0;
  549. outformat = 'r';
  550. pagesize = 24;
  551. patform = 'g';
  552. pct_right = 0.0;
  553. prevnpats = 0;
  554. qmark = scale(0.5);
  555. right = 0;
  556. ringbell = '-';
  557. skiprate = 0;
  558. testpat = 0;
  559. saverate = MAXINT;
  560. seedstart = (SEEDNODE *) malloc(sizeof(SEEDNODE));
  561. seedstart->val = 0;
  562. seedstart->next = NULL;
  563. #ifdef SYMMETRIC
  564. stdthresh = -32768;      /* indicates no threshold set */
  565. #endif
  566. summary = '+';
  567. theta1 = scale(0.5);
  568. theta2 = scale(1.0) - theta1;
  569. toler = scale(0.1);
  570. toosmall = -1;           /* indicates no weights whittled away */
  571. totaliter = 0;
  572. update = 'p';
  573. up_to_date_stats = '-';
  574. wrong = 0;
  575. wtfile = &w[0];
  576. wtformat = 'r';
  577. wtlimithit = 0;
  578. wttotal = 0;
  579. }
  580.  
  581. int nonetwork()
  582. {
  583. if (start != NULL) return(0);
  584. pg("there is no network\n");
  585. return(1);
  586. }
  587.  
  588. int nopatterns()
  589. {
  590. if (npats != 0) return(0);
  591. pg("there are no patterns\n");
  592. return(1);
  593. }
  594.  
  595. /* for a SIGINT, restart in cmdloop */
  596. #ifdef UNIX
  597. void restartcmdloop()
  598. #else
  599. void restartcmdloop(int dummy)
  600. #endif
  601. {
  602. while (data != stdin) popfile();
  603. benchmark = 0;
  604. signal(SIGINT,restartcmdloop);
  605. longjmp(cmdloopstate,1);
  606. }
  607.  
  608. void cmdloop()    /* read commands and process them */
  609. {
  610. int finished, layerno, unitno, layer1, layer2, node1, node2;
  611. int i, itemp, itemp2, successes, tries, sumiter, dobenchmark;
  612. INT32 itemp32;
  613. WTTYPE temp, temp2;
  614. REAL averageiter, averagecpu;
  615. LAYER *p;
  616. UNIT *u, *n1, *n2;
  617. char string[81];
  618. WTNODE *w;
  619. SEEDNODE *s, *sprev;
  620. long cputime, prevcputime, totalcpu;
  621.  
  622. setjmp(cmdloopstate); /* restart here from SIGINT */
  623. finished = 0;
  624. do{
  625. #ifdef SYMMETRIC
  626.    if (data == stdin) pg("[?!*AaBbCdefhiklmnOoPpQqRrSsTtWwx]? ");
  627. #else
  628.    if (data == stdin) pg("[?!*AaBbCcdefHhiklmnOoPpQqRrSstWwx]? ");
  629. #endif
  630.  
  631.    while(ch == ' ' || ch == '\n') ch = readch();
  632.    lineno = 0;
  633.    switch (ch) {
  634.  
  635. case EOF:
  636. popfile();
  637. if (data == stdin) pg("taking commands from stdin now\n");
  638. break;
  639.  
  640. case '?':
  641. sprintf(outstr,"\n%d iterations, s %1d  ",totaliter,seed); pg(outstr);
  642. sprintf(outstr,"k 0 %5.3f,  ",unscale(initialkick)); pg(outstr);
  643. sprintf(outstr,"data file = %s\n",datafilename); pg(outstr);
  644. sprintf(outstr,"testing file = %s\n",testfile); pg(outstr);
  645. sprintf(outstr,"training file = %s\n",trainfile); pg(outstr);
  646. sprintf(outstr,"input file = %s\n",inputfile); pg(outstr);
  647. sprintf(outstr,"weight file = %s\n",wtfile); pg(outstr);
  648. sprintf(outstr,"Algorithm: a%c",activation); pg(outstr);
  649. if (backprop) pg(" b+"); else pg(" b-");
  650. sprintf(outstr," D%5.2f d%c g %d ",unscale(D),deriv,g); pg(outstr);
  651. sprintf(outstr,"s%1d t%1d u%c\n",skiprate,testpat,update); pg(outstr);
  652. sprintf(outstr,"e %7.5f %7.5f",unscale(eta),unscale(eta2)); pg(outstr);
  653. sprintf(outstr," --- a %7.5f\n",unscale(alpha)); pg(outstr);
  654. sprintf(outstr,"d d %8.5f e %8.5f ",unscale(decay),unscale(dbdeta));
  655. pg(outstr);
  656. sprintf(outstr," k %8.5f m %8.5f ",unscale(kappa),unscale(etamax));
  657. pg(outstr);
  658. sprintf(outstr," n %8.5f t %8.5f\n",unscale(noise),unscale(theta1));
  659. pg(outstr);
  660. sprintf(outstr,"tolerance = %4.2f\n",unscale(toler)); pg(outstr);
  661. sprintf(outstr,"f b%c c%c e%c i%c",ringbell,copyflag,echo,informat);
  662. pg(outstr);
  663. sprintf(outstr," o%c P %d p%c s%c ",outformat,pagesize,patform,summary);
  664. pg(outstr);
  665. sprintf(outstr,"u%c w%c\n",up_to_date_stats,wtformat); pg(outstr);
  666. pg("format breaks after: ");
  667. for (i=1;i<=10;i++) {sprintf(outstr,"%4d",format[i]); pg(outstr);};
  668. pg("\n                     ");
  669. for (i=11;i<=maxformat-1;i++)
  670.  {sprintf(outstr,"%4d",format[i]); pg(outstr);};
  671. sprintf(outstr,"\nlast time weights were saved: %d\n",lastsave);
  672. pg(outstr);
  673. sprintf(outstr,"saving weights every %d iterations\n",saverate);
  674. pg(outstr);
  675. if (wtlimithit) pg(">>>>> WEIGHT LIMIT HIT <<<<<\n");
  676. pg("network size: ");
  677. p = start;
  678. while (p != NULL)
  679.  {
  680.   sprintf(outstr," %1d",p->unitcount);
  681.   pg(outstr);
  682.   p = p->next;
  683.  };
  684. if (extraconnect) pg(" with extra connections");
  685. sprintf(outstr," (total:  %1d weights)\n",wttotal); pg(outstr);
  686. if (toosmall != -1)
  687.  {
  688.   pg("removed non-bias weights with absolute ");
  689.   sprintf(outstr,"value below  %4.2f\n",unscale(toosmall)); pg(outstr);
  690.  };
  691. #ifdef SYMMETRIC
  692. if (stdthresh != -32768)
  693.  {
  694.   sprintf(outstr,"thresholds frozen at %f\n", unscale(stdthresh));
  695.   pg(outstr);
  696.  };
  697. #endif
  698. sprintf(outstr,"%d patterns   %5.2f%%  right ",npats,pct_right);
  699. pg(outstr);
  700. sprintf(outstr,"(%d right,  %d wrong)  ",right,wrong); pg(outstr);
  701. sprintf(outstr,"%7.5f error/unit\n",errorperunit); pg(outstr);
  702. sprintf(outstr,"? = %f\n",unscale(qmark)); pg(outstr);
  703. sprintf(outstr,"benchmark parameters: g %d ",goal); pg(outstr);
  704. sprintf(outstr,"k %4.2f ",unscale(kicksize)); pg(outstr);
  705. sprintf(outstr,"m %d r %d ",maxtries,maxiter); pg(outstr);
  706. if (printrate != -1) {sprintf(outstr,"%d ",printrate); pg(outstr);};
  707. if (*testfile != emptystring)
  708.  {sprintf(outstr,"t %s\n",testfile); pg(outstr);}
  709. else {sprintf(outstr,"t %d\n",testpat); pg(outstr);};
  710. pg("for help, type h followed by the letter of the command\n\n");
  711. break;
  712.  
  713. case '!':
  714. i = 0;
  715. ch = readch();
  716. while (ch != '\n' && i <= 80)
  717.  {
  718.   string[i] = ch;
  719.   ch = readch();
  720.   i = i + 1;
  721.  };
  722. bufferptr = bufferptr - 1;
  723. string[i] = '\0';
  724. system(string);
  725. break;
  726.  
  727. case '*': break;  /* * on a line is a comment */
  728.  
  729. case 'A':
  730. while (ch != '\n' && ch != '*')
  731.  {
  732.   ch = readch();
  733.   if (ch == 'a')
  734.    {
  735.     do ch = readch(); while (ch == ' ');
  736.     if (ch == 'p' || ch == 'l' || ch == 't') activation = ch;
  737. #ifndef INTEGER
  738.     else if (ch == 's' || ch == 'T') activation = ch;
  739. #endif
  740.     else texterror();
  741.    }
  742.   else if (ch == 'b')
  743.    {
  744.     do ch = readch(); while (ch == ' ');
  745.     if (ch == '+') backprop = 1;
  746.     else if (ch == '-') backprop = 0;
  747.     else texterror();
  748.    }
  749.   else if (ch == 'D')
  750.    {
  751.     temp = rdr(GT,0.0,'A');
  752.     if (!readerror) D = temp;
  753.    }
  754.   else if (ch == 'd')
  755.    {
  756.     do ch = readch(); while (ch == ' ');
  757.     if (ch == 'd' || ch == 'f' || ch == 'o' || ch == 'F') deriv = ch;
  758.     else texterror();
  759.    }
  760.   else if (ch == 'g')
  761.    {
  762.     itemp32 = readint(0,MAXINT,'f');
  763.     if (!readerror) g = itemp32;
  764.    }
  765.   else if (ch == 's')
  766.    {
  767.     itemp = readint(0,32767,'A');
  768.     if (!readerror) skiprate = itemp;
  769.    }
  770.   else if (ch == 't')
  771.    {
  772.     itemp = readint(0,npats,'A');
  773.     if (!readerror) testpat = itemp;
  774.     resetpats();
  775.     for (i=1;i<=npats;i++)
  776.      {
  777.       nextpat();
  778.       if (last->currentpat->bypass < 0) last->currentpat->bypass = 0;
  779.       else if (i == testpat) last->currentpat->bypass = -1;
  780.      };
  781.    }
  782.   else if (ch == 'u')
  783.    {
  784.     do ch = readch(); while (ch == ' ');
  785.     if (ch == 'j') ch = 'd';
  786. #ifdef SYMMETRIC
  787.     if (ch == 'c' || ch == 'p') update = ch;
  788. #else
  789.     if (ch == 'c' || ch == 'p' || ch == 'd') update = ch;
  790. #endif
  791.     else texterror();
  792.    }
  793.   else if (ch == '*' || ch == '\n' || ch == ' ');
  794.   else texterror();
  795.  }
  796. bufferptr = bufferptr - 1;
  797. break;
  798.  
  799. case 'a':
  800. temp = rdr(GE,0.0,'a');
  801. if (!readerror) alpha = temp;
  802. break;
  803.  
  804. case 'B':
  805. dobenchmark = 0;
  806. while (ch != '\n' && ch != '*')
  807.  {
  808.   do ch = readch(); while (ch == ' ');
  809.   if (ch == 'g')
  810.    {
  811.     itemp2 = readint(0,MAXINT,'B');
  812.     if (!readerror) goal = itemp2;
  813.    }
  814.   else if (ch == 'k')
  815.    {
  816.     temp = rdr(GT,0.0,'B');
  817.     if (!readerror) kicksize = temp;
  818.    }
  819.   else if (ch == 'm')
  820.    {
  821.     itemp2 = readint(0,MAXINT,'B');
  822.     if (!readerror) maxtries = itemp2;
  823.    }
  824.   else if (ch == 'r')
  825.    {
  826.     if (nonetwork() || nopatterns()) goto endB;
  827.     maxiter = readint(1,MAXINT,'B');
  828.     if (readerror) goto endB;
  829.     do ch = readch(); while (ch == ' ');
  830.     bufferptr = bufferptr - 1;
  831.     if (ch >= '0' && ch <= '9')
  832.      {
  833.       printrate = readint(1,MAXINT,'B');
  834.       if (readerror) goto endB;
  835.      }
  836.     else printrate = -1;
  837.     dobenchmark = 1;
  838.    }
  839.   else if (ch == 't')
  840.    {
  841.     do ch = readch(); while (ch == ' ');
  842.     if (ch == 'f') testfile = readstr();
  843.     else if (nonetwork() || nopatterns()) goto endB;
  844.     else
  845.      {
  846.       bufferptr = bufferptr - 1;
  847.       itemp = readint(0,npats,'B');
  848.       if (readerror) goto endB;
  849.       testpat = itemp;
  850.       if (testpat == 0) testfile = &emptystring;
  851.      };
  852.    }
  853.   else if (ch == ' ' || ch == '*' || ch == '\n');
  854.   else texterror();
  855.  };
  856. bufferptr = bufferptr - 1;
  857. if (dobenchmark)
  858.  {
  859.   if (testpat)
  860.    {
  861.     sprintf(outstr,"testing pattern %d\n",testpat);
  862.     if (pg(outstr)) goto endB;
  863.    };
  864.   benchmark = 1;
  865.   tries = 0;
  866.   sumiter = 0;
  867.   successes = 0;
  868.   totalcpu = 0;
  869.   s = seedstart->next;
  870.   while (successes < goal && tries < maxtries)
  871.    {
  872.     if (s != NULL)
  873.      {
  874.       seed = s->val;
  875.       srand(seed);
  876.       s = s->next;
  877.      };
  878.     clear();
  879.     kick(scale(0.0),kicksize);
  880.     sprintf(outstr," seed = %6d; ",seed);
  881.     pg(outstr);
  882.     if (testpat)
  883.      {
  884.       resetpats();
  885.       for (i=1;i<=testpat;i++) nextpat();
  886.       last->currentpat->bypass = -1;
  887.      };
  888.     prevcputime = clock();
  889.     if (run(maxiter,printrate)) goto endB;
  890.     cputime = clock();
  891.     tries = tries + 1;;
  892.     if (unlearned == 0 || ((unlearned == 1) && testpat))
  893.      {
  894.       successes = successes + 1;
  895.       sumiter = sumiter + totaliter;
  896.       totalcpu = totalcpu + cputime - prevcputime;
  897.      };
  898.     if (testpat)
  899.      {
  900.       for (i=1;i<(testpat-1);i++) setonepat();
  901.       last->currentpat->bypass = 0;
  902.      }
  903.    };
  904.   sprintf(outstr,"%d failures; %d successes;",tries - successes,successes);
  905.   pg(outstr);
  906.   if (successes > 0)
  907.    {
  908.     averageiter = (REAL) sumiter / (REAL) successes;
  909.     averagecpu = (REAL) totalcpu / (REAL) successes;
  910.     sprintf(outstr," average = %f ",averageiter); pg(outstr);
  911.     sprintf(outstr,"%12.6f sec/network",averagecpu / CLOCKS_PER_SEC);
  912.     pg(outstr);
  913.    };
  914.   pg("\n");
  915.  };
  916.  
  917. endB: benchmark = 0;
  918. break;
  919.  
  920. case 'b':
  921. itemp = 0;
  922. ch = readch();
  923. while (ch != '\n' && ch != '*')
  924.  {
  925.   bufferptr = bufferptr - 1;
  926.   itemp2 = readint(format[itemp],last->unitcount,'b');
  927.   if (readerror) goto endb;
  928.   itemp = itemp + 1;
  929.   if (itemp < maxformat) format[itemp] = itemp2;
  930.   else pg("format too long\n");
  931.   ch = readch();
  932.   while (ch == ' ') ch = readch();
  933.   if (ch >= '0' && ch <= '9') bufferptr = bufferptr - 1;
  934.  };
  935. if (itemp < maxformat-1)
  936.    for (i=itemp+1;i <= maxformat-1; i++) format[i] = format[i-1] + 10;
  937. bufferptr = bufferptr - 1;
  938.  
  939. endb: break;
  940.  
  941. case 'C':
  942. if (nonetwork()) break;
  943. clear();
  944. srand(seed);
  945. break;
  946.  
  947. #ifndef SYMMETRIC
  948. case 'c':
  949. if (nonetwork()) break;
  950. layer1 = readint(1,nlayers,'c');
  951. if (readerror) break;
  952. node1 = readint(1,MAXINT,'c');
  953. if (readerror) break;
  954. layer2 = readint(1,nlayers,'c');
  955. if (readerror) break;
  956. node2 = readint(1,MAXINT,'c');
  957. if (readerror) break;
  958. if (layer1 >= layer2)
  959.  {
  960.   pg("backward connections in c command not implemented\n");
  961.   break;
  962.  };
  963. n1 = locateunit(layer1,node1);
  964. n2 = locateunit(layer2,node2);
  965. if (n1 != NULL && n2 != NULL)
  966.  {
  967.   connect(n1,n2,0);
  968.   extraconnect = 1;
  969.  }
  970. else
  971.  {
  972.   sprintf(outstr,"connection not made: %d %d %d %d\n", layer1, node1, layer2, node2);
  973.   pg(outstr);
  974.  };
  975. break;
  976. #endif
  977.  
  978. case 'd':
  979. case 'j':
  980. while (ch != '\n' && ch != '*')
  981.  {
  982.   ch = readch();
  983.   if (ch == 'd')
  984.    {
  985.     temp = rdr(GT,0.0,'d');
  986.     if (!readerror) decay = temp;
  987.    }
  988.   else if (ch == 'e')
  989.    {
  990.     temp = rdr(GT,0.0,'d');
  991.     if (!readerror && !nonetwork())
  992.      {
  993.       dbdeta = temp;
  994.       p = start->next;
  995.       while (p != NULL)
  996.        {
  997.         u = (UNIT *) p->units;
  998.         while (u != NULL)
  999.          {
  1000.           w = (WTNODE *) u->wtlist;
  1001.           while (w != NULL)
  1002.            {
  1003. #ifdef SYMMETRIC
  1004.             *(w->eta) = dbdeta;
  1005. #else
  1006.             w->eta = dbdeta;
  1007. #endif
  1008.             w = w->next;
  1009.            }
  1010.           u = u->next;
  1011.          }
  1012.         p = p->next;
  1013.        }
  1014.      }
  1015.    }
  1016.   else if (ch == 'k')
  1017.    {
  1018.     temp = rdr(GT,0.0,'d');
  1019.     if (!readerror) kappa = temp;
  1020.    }
  1021.   else if (ch == 'm')
  1022.    {
  1023.     temp = rdr(GT,0.0,'d');
  1024.     if (!readerror) etamax = temp;
  1025.    }
  1026.   else if (ch == 'n')
  1027.    {
  1028.     temp = rdr(GE,0.0,'d');
  1029.     if (!readerror) noise = temp;
  1030.    }
  1031.   else if (ch == 't')
  1032.    {
  1033.     temp = rdr(GE,0.0,'d');
  1034.     if (!readerror)
  1035.      {
  1036.       theta1 = temp;
  1037.       theta2 = scale(1.0) - theta1;
  1038.      };
  1039.    }
  1040.   else if (ch == '*' || ch == '\n' || ch == ' ');
  1041.   else texterror();
  1042.  }
  1043. bufferptr = bufferptr - 1;
  1044. break;
  1045.  
  1046. case 'e':
  1047. temp = rdr(GT,0.0,'e');
  1048. if (!readerror) eta = temp;
  1049. do ch = readch(); while (ch == ' ');
  1050. bufferptr = bufferptr - 1;
  1051. if (ch != '\n' && ch != '*')
  1052.  {
  1053.   temp = rdr(GT,0.0,'r');
  1054.   if (!readerror) eta2 = temp;
  1055.  }
  1056. else eta2 = eta;
  1057. break;
  1058.  
  1059. case 'f':
  1060. while (ch != '\n' && ch != '*')
  1061.  {
  1062.   ch = readch();
  1063.   if (ch == 'b')
  1064.    {
  1065.     do ch = readch(); while (ch == ' ');
  1066.     if (ch == '+' || ch == '-') ringbell = ch; else texterror();
  1067.    }
  1068.   else if (ch == 'c')
  1069.    {
  1070.     do ch = readch(); while (ch == ' ');
  1071.     if (ch == '+')
  1072.      {
  1073.        copyflag = '+';
  1074.        copy = fopen("copy","w");
  1075.        if (copy == NULL)
  1076.         {sprintf(outstr,"cannot open file:  copy\n"); pg(outstr); };
  1077.      }
  1078.     else if (ch == '-')
  1079.      {
  1080.       copyflag = '-';
  1081.       if (copy != NULL)
  1082.        {
  1083.         fflush(copy);
  1084.         fclose(copy);
  1085.        }
  1086.      }
  1087.     else texterror();
  1088.    }
  1089.   else if (ch == 'e')
  1090.    {
  1091.     do ch = readch(); while (ch == ' ');
  1092.     if (ch == '+' || ch == '-') echo = ch;
  1093.    }
  1094.   else if (ch == 'i')
  1095.    {
  1096.     do ch = readch(); while (ch == ' ');
  1097.     if (ch == 'c' || ch == 'r') informat = ch; else texterror();
  1098.    }
  1099.   else if (ch == 'o')
  1100.    {
  1101.     do ch = readch(); while (ch == ' ');
  1102.     if (ch == 'a' || ch == 'c' || ch == 'r') outformat = ch;
  1103.     else texterror();
  1104.    }
  1105.   else if (ch == 'P')
  1106.    {
  1107.     itemp = readint(0,MAXINT,'f');
  1108.     if (!readerror) pagesize = itemp;
  1109.    }
  1110.   else if (ch == 'p')
  1111.    {
  1112.     do ch = readch(); while (ch == ' ');
  1113.     if (ch == 'c' || ch == 'C' || ch == 'g' || ch == 'G') patform = ch;
  1114.     else texterror();
  1115.    }
  1116.   else if (ch == 's')
  1117.    {
  1118.     do ch = readch(); while (ch == ' ');
  1119.     if (ch == '+' || ch == '-') summary = ch; else texterror();
  1120.    }
  1121.   else if (ch == 'u')
  1122.    {
  1123.     do ch = readch(); while (ch == ' ');
  1124.     if (ch == '+' || ch == '-') up_to_date_stats = ch; else texterror();
  1125.    }
  1126.   else if (ch == 'w')
  1127.    {
  1128.     do ch = readch(); while (ch == ' ');
  1129.     if (ch == 'r' || ch == 'R' || ch == 'b' || ch == 'B') wtformat = ch;
  1130.     else texterror();
  1131.    }
  1132.   else if (ch == ' ' || ch == '*' || ch == '\n');
  1133.   else texterror();
  1134.  }
  1135. bufferptr = bufferptr - 1;
  1136. break;
  1137. #ifndef SYMMETRIC
  1138.  
  1139. case 'H':
  1140. if (nonetwork()) break;
  1141. itemp = readint(2,nlayers,'H');
  1142. if (readerror) break;
  1143. temp = rdr(GE,0.0,'H');
  1144. if (!readerror) addhiddenunit(itemp,temp);
  1145. break;
  1146. #endif
  1147.  
  1148. case 'h': help(); break;
  1149.  
  1150. case 'i':
  1151. do ch = readch(); while (ch == ' ');
  1152. if (ch != '\n')
  1153.  {
  1154.   bufferptr = bufferptr - 1;
  1155.   inputfile = readstr();
  1156.  }
  1157. pushfile(inputfile);
  1158. break;
  1159.  
  1160. case 'k':
  1161. if (nonetwork()) break;
  1162. temp = rdr(GE,0.0,'k');
  1163. if (readerror) break;
  1164. temp2 = rdr(GT,0.0,'k');
  1165. if (!readerror)
  1166.  {
  1167.   if (initialkick == -1 && temp == 0) initialkick = temp2;
  1168.   kick(temp,temp2);
  1169.  }
  1170. break;
  1171.  
  1172. case 'l':
  1173. if (nonetwork()) break;
  1174. layerno = readint(1,nlayers,'l'); 
  1175. if (readerror) break;
  1176. p = start;
  1177. for (i=2;i<=layerno;i++) p = p->next;
  1178. printoutunits(1,p,0);
  1179. break;
  1180.  
  1181. case 'm':
  1182. nlayers = 0;
  1183. wttotal = 0;
  1184. ch = readch();
  1185. p = NULL;
  1186. while (ch != '\n' && ch != '*')
  1187.  {
  1188.   itemp = readint(1,MAXINT,'m');
  1189.   if (readerror)
  1190.    {
  1191.     wttotal = 0;
  1192.     goto endm;
  1193.    };
  1194.   nlayers = nlayers + 1;
  1195.   p = mklayer(p,itemp);
  1196.   if (nlayers == 1) start = p;
  1197.   ch = readch();
  1198.   while (ch == ' ') ch = readch();
  1199.   if (ch >= '0' && ch <= '9') bufferptr = bufferptr - 1;
  1200.  };
  1201. last = p;
  1202. p = start;
  1203. p = p->next;
  1204. hlayer = (UNIT *) p->units;
  1205. p = p->next;
  1206. if (p != NULL)
  1207.  {
  1208.   ilayer = (UNIT *) p->units;
  1209.   p = p->next;
  1210.   if (p != NULL)
  1211.    {
  1212.     jlayer = (UNIT *) p->units;
  1213.     p = p->next;
  1214.     if (p != NULL) klayer = (UNIT *) p->units;
  1215.    }
  1216.  };
  1217. bufferptr = bufferptr - 1;
  1218. nullpatterns();
  1219. clear();
  1220. endm: break;
  1221.  
  1222. case 'n':
  1223. if (nonetwork()) break;
  1224. do ch = readch(); while (ch == ' ');
  1225. if (ch == 'f')
  1226.  {
  1227.   trainfile = readstr();
  1228.   itemp = MAXINT;
  1229.   pushfile(trainfile);
  1230.  }
  1231. else
  1232.  {
  1233.   bufferptr = bufferptr - 1;
  1234.   itemp = readint(1,MAXINT,'n');
  1235.   if (readerror) break;
  1236.  };
  1237. nullpatterns();
  1238. readingpattern = 1;
  1239. npats = readpats(itemp,'n');
  1240. if (itemp != MAXINT && npats < itemp)
  1241.  {
  1242.   sprintf(outstr,"\n>>>>> only %d patterns read <<<<<\n\n",npats);
  1243.   pg(outstr);
  1244.  };
  1245. readingpattern = 0;
  1246. wrong = npats;
  1247. break;
  1248.  
  1249. case 'O':
  1250. if (nonetwork() || nopatterns()) break;
  1251. itemp = readint(1,npats,'O');
  1252. if (readerror) break;
  1253. resetpats();
  1254. for (i=1;i<=itemp;i++) nextpat();
  1255. setoutputpat();
  1256. u = (UNIT *) last->units;
  1257. itemp2 = 0; /* unit counter */
  1258. i = 1;      /* format counter */
  1259. while (u != NULL)
  1260.  {
  1261.   if (outformat == 'c')
  1262.      if (unscale(u->tj) == 1) pg("1"); else pg("0");
  1263.   else {sprintf(outstr,"%5.2f",unscale(u->tj)); pg(outstr);};
  1264.   itemp2 = itemp2 + 1;
  1265.   if (format[i] == itemp2)
  1266.    {
  1267.     if (outformat == 'r') pg("\n"); else pg(" ");
  1268.     if (i < maxformat - 1) i = i + 1;
  1269.    };
  1270.   u = u->next;
  1271.  }
  1272. pg("\n");
  1273. break;
  1274.  
  1275. case 'o':
  1276. do ch = readch(); while (ch == ' ' || ch == '\n');
  1277. if (ch == 'r' || ch == 'a' || ch == 'c') outformat = ch;
  1278. else printf("incorrect output format: %c\n",ch);
  1279. break;
  1280.  
  1281. case 'P':
  1282. if (nonetwork() || nopatterns()) break;
  1283. do ch = readch(); while (ch == ' ');
  1284. bufferptr = bufferptr - 1;
  1285. if (ch == '\n' || ch == '*') patcheck(1,npats,1,1,1,1,0);
  1286. else
  1287.  {
  1288.   itemp = readint(0,npats,'P');
  1289.   if (readerror) break;
  1290.   if (itemp == 0) patcheck(1,npats,0,0,1,1,0);
  1291.   else patcheck(itemp,itemp,1,1,0,0,0);
  1292.  };
  1293. break;
  1294.  
  1295. case 'p':
  1296. if (nonetwork()) break;
  1297. loadpat('p');
  1298. printoutunits(1,last,0);
  1299. break;
  1300.  
  1301. case 'Q':
  1302. temp = rdr(GT,(REAL) KCODE,'Q');
  1303. if (!readerror) qmark = temp;
  1304. break;
  1305.  
  1306. case 'q': return;
  1307.  
  1308. case 'R': if (nonetwork()) break; else restoreweights(); break;
  1309.  
  1310. case 'r': /* r for run, rw for restore weights */
  1311. do ch = readch(); while (ch == ' ');
  1312. if (ch == 'w')
  1313.  {
  1314.   do ch = readch(); while (ch == ' ');
  1315.   bufferptr = bufferptr - 1;
  1316.   if (ch == '*' || ch == '\n') /* nothing */ ; else wtfile = readstr();
  1317.   if (nonetwork()) break; else restoreweights();
  1318.  }
  1319. else
  1320.  {
  1321.   if (nonetwork() || nopatterns()) break;
  1322.   bufferptr = bufferptr - 1;
  1323.   itemp = readint(1,MAXINT,'r'); 
  1324.   if (!readerror) iter = itemp; else break;
  1325.   do ch = readch(); while (ch == ' ');
  1326.   bufferptr = bufferptr - 1;
  1327.   if (ch != '\n' && ch != '*')
  1328.    {
  1329.     itemp = readint(1,MAXINT,'r');
  1330.     if (readerror != 1) run(iter,itemp);
  1331.    }
  1332.   else run(iter,-1);
  1333.  };
  1334. break;
  1335.  
  1336. case 'S':
  1337. do ch = readch(); while (ch == ' ');
  1338. bufferptr = bufferptr - 1;
  1339. if (ch == '\n' || ch == '*') itemp = 0;
  1340. else
  1341.  {
  1342.   itemp = readint(0,MAXINT,'S');
  1343.   if (readerror) break; 
  1344.  };
  1345. if (itemp == 0) if (nonetwork()) break; else saveweights();
  1346. else saverate = itemp;
  1347. break;
  1348.  
  1349. case 's':  /* s <int> for seed, sw <filename> for save weights */
  1350. do ch = readch(); while (ch == ' ');
  1351. if (ch == 'w')
  1352.  {
  1353.   do ch = readch(); while (ch == ' ');
  1354.   bufferptr = bufferptr - 1;
  1355.   if (ch == '*' || ch == '\n') /* nothing */ ; else wtfile = readstr();
  1356.   if (nonetwork()) break; else saveweights();
  1357.  }
  1358. else
  1359.  {
  1360.   bufferptr = bufferptr - 1;
  1361.   sprev = seedstart;
  1362.   while (ch != '\n' && ch != '*')
  1363.    {
  1364.     seed = readint(0,MAXINT,'s');
  1365.     if (readerror) goto ends;
  1366.     s = (SEEDNODE *) malloc(sizeof(SEEDNODE));
  1367.     s->val = seed;
  1368.     s->next = NULL;
  1369.     sprev->next = s;
  1370.     sprev = s;
  1371.     do ch = readch(); while(ch == ' ');
  1372.     if (ch >= '0' && ch <= '9') bufferptr = bufferptr - 1;
  1373.    };
  1374. ends: seed = seedstart->next->val;
  1375.   srand(seed);
  1376. }
  1377. bufferptr = bufferptr - 1;
  1378. break;
  1379. #ifdef SYMMETRIC
  1380.  
  1381. case 'T':
  1382. if (nonetwork()) break;
  1383. stdthresh = rdr(GT,-unscale(32767),'T');
  1384. if (readerror) break;
  1385. u = (UNIT *) last->units;
  1386. while (u != NULL)
  1387.  {
  1388.   w = (WTNODE *) u->wtlist;
  1389.   while (w->next != NULL) w = w->next;
  1390.   *(w->weight) = stdthresh;
  1391.   u = u->next;
  1392.  };
  1393. break;
  1394. #endif
  1395.  
  1396. case 't':
  1397. do ch = readch(); while (ch == ' ');
  1398. if (ch == '\n' && (!nonetwork())) testcheck();
  1399. else if (ch == 'f')
  1400.  {
  1401.   do ch = readch(); while (ch == ' ');
  1402.   if (ch == '\n' && (!nonetwork())) testcheck();
  1403.   else
  1404.    {
  1405.     bufferptr = bufferptr - 1;
  1406.     testfile = readstr();
  1407.     if (!nonetwork()) testcheck();
  1408.    };
  1409.  }
  1410. else
  1411.  {
  1412.   bufferptr = bufferptr - 1;
  1413.   temp = rdr(GT,0.0,'t');
  1414.   if (readerror) break;
  1415.   else if (temp < scale(1.0)) toler = temp;
  1416.   else printf("tolerance value out of range\n");
  1417.  };
  1418. break;
  1419. #ifndef SYMMETRIC
  1420.  
  1421. case 'W':
  1422. if (nonetwork()) break;
  1423. temp = rdr(GT,0.0,'W');
  1424. if (!readerror)
  1425.  {
  1426.   toosmall = temp;
  1427.   whittle(temp);
  1428.   printf("total weights now: %1d\n",wttotal);
  1429.  };
  1430. break;
  1431. #endif
  1432.  
  1433. case 'w':
  1434. if (nonetwork()) break;
  1435. layerno = readint(2,nlayers,'w');
  1436. if (readerror) break;
  1437. unitno = readint(1,MAXINT,'w');
  1438. if (readerror) break;
  1439. u = locateunit(layerno,unitno);
  1440. if (u != NULL) printweights(u);
  1441. break;
  1442.  
  1443. case 'x':
  1444. if (nonetwork()) break;
  1445. do ch = readch(); while (ch == ' ');
  1446. if (ch == 'f')
  1447.  {
  1448.   trainfile = readstr();
  1449.   itemp = MAXINT;
  1450.   pushfile(trainfile);
  1451.  }
  1452. else
  1453.  {
  1454.   bufferptr = bufferptr - 1;
  1455.   itemp = readint(1,MAXINT,'n');
  1456.   if (readerror) break;
  1457.  };
  1458. prevnpats = npats;
  1459. findendofpats(start);
  1460. findendofpats(last);
  1461. readingpattern = 1;
  1462. itemp2 = readpats(itemp,'x');
  1463. if (itemp != MAXINT && npats < itemp2)
  1464.    printf("\n>>>>> only %d patterns read <<<<<\n\n",npats);
  1465. readingpattern = 0;
  1466. npats = npats + itemp2;
  1467. wrong = wrong + itemp2;
  1468. break;
  1469.  
  1470. /*
  1471. case 'z': tracer();
  1472.           break;
  1473. */
  1474.  
  1475. default: texterror();
  1476. break;
  1477.       };
  1478.     do ch = readch(); while (ch != '\n');
  1479.   }while (!finished);
  1480. }
  1481.  
  1482. void main(argc,argv)
  1483. int argc;
  1484. char *argv[];
  1485. {
  1486. FILE *tempfile;
  1487. setbuf(stdout,NULL);  /* set unbuffered output */
  1488. printf("Fast Backpropagation Copyright (c) 1990, 1991, 1992 by Donald R. Tveter\n");
  1489. filestackptr = 0;
  1490. filestack[0] = stdin;
  1491. data = stdin;
  1492. emptystring = '\0';
  1493. if (argc == 1)
  1494.  {
  1495.   printf("no data file, stdin assumed\n");
  1496.   datafilename = &emptystring;
  1497.   testfile = &emptystring;
  1498.  }
  1499. else
  1500.  {
  1501.   datafilename = argv[1];
  1502.   pushfile(datafilename);
  1503.   if (argc == 3)
  1504.    {
  1505.     tempfile = fopen(argv[2],"r");
  1506.     if (tempfile == NULL)
  1507.      {
  1508.       printf("there is no file: %s\n",argv[2]);
  1509.       testfile = &emptystring;
  1510.      }
  1511.     else
  1512.      {
  1513.       testfile = argv[2];
  1514.       fclose(tempfile);
  1515.      }
  1516.    }
  1517.   else testfile = &emptystring;
  1518.  };
  1519. init();
  1520. signal(SIGINT,restartcmdloop); /* restart from interrrupt */
  1521. cmdloop();
  1522. if (copy != NULL)
  1523.  {
  1524.   fflush(copy);
  1525.   fclose(copy);
  1526.  }
  1527. }
  1528.