[comp.sources.misc] v14i087: Fast Backpropagation Part 4 of 4

drt@chinet.chi.il.us (Donald Tveter) (09/16/90)

Posting-number: Volume 14, Issue 87
Submitted-by: Donald Tveter <drt@chinet.chi.il.us>
Archive-name: back-prop/part04

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 4 (of 4)."
# Contents:  int.c real.c misc.c
# Wrapped by drt@chinet on Fri Aug 31 08:18:36 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'int.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'int.c'\"
else
echo shar: Extracting \"'int.c'\" \(14277 characters\)
sed "s/^X//" >'int.c' <<'END_OF_FILE'
X/* *********************************************************** */
X/* file int.c:  Contains the network evaluation and weight     */
X/*              adjustment procedures for the integer versions */
X/*              bp and sbp.                                    */
X/*                                                             */
X/* Copyright (c) 1990 by Donald R. Tveter                      */
X/*                                                             */
X/* The code here has been optimized for use with the Motorola  */
X/* MC 68010 processor and version 3.5 of the UNIX (tm) PC      */
X/* C compiler where UNIX is a trademark of Bell Laboratories.  */
X/* *********************************************************** */
X
X#include "ibp.h"
X#include <stdio.h>
X
Xextern WTTYPE alpha;
Xextern char backprop;
Xextern WTTYPE D;
Xextern WTTYPE decay;
Xextern char deriv;
Xextern WTTYPE eta;
Xextern WTTYPE eta2;
Xextern WTTYPE etamax;
Xextern WTTYPE kappa;
Xextern LAYER *last;
Xextern LAYER *start;
Xextern WTTYPE theta1;
Xextern WTTYPE theta2;
Xextern WTTYPE toler;
Xextern int totaldiff;
Xextern char update;
X
Xvoid forward()             /* computes unit activations */
X{ 
X  register WTNODE *w;
X  register UNIT *u;
X  register UNIT *predu;
X  LAYER *layer;
X  register int sum;
X  register int x;
X  register short fract;
X  register short val;
X  register int intpart;
X
X layer = start->next;
X while (layer != NULL)
X    {
X      u = (UNIT *) layer->units;
X      while (u != NULL)
X         {
X           sum = 0;
X           w = (WTNODE *) u->wtlist;
X           while (w != NULL)
X              {
X                predu = (UNIT *) w->backunit;
X#ifdef SMART
X#   ifdef SYMMETRIC
X                sum = sum + (*(w->weight) * predu->oj) / 1024;
X#   else
X                sum = sum + (w->weight * predu->oj) / 1024;
X#   endif
X#else
X#   ifdef SYMMETRIC
X                x = (*(w->weight) * predu->oj);
X#   else
X                x = w->weight * predu->oj;
X#   endif
X                if (x >= 0) sum = sum + (x >> 10);
X                else sum = sum - ( (-x) >> 10);
X#endif
X                w = w->next;
X              };
X           sum = (D * sum) / 1024;
X           if (sum > 0) x = sum; else x = -sum;
X           intpart = x >> 10;
X           fract = x - (intpart << 10);
X           switch (intpart)
X            {
X  case 0:  val = 512 + ((237 * fract) >> 10);       /* 0 <= x < 1 */
X           break;
X  case 1:  val = 748 + ((153 * fract) >> 10);       /* 1 <= x < 2 */
X           break;
X  case 2:  val = 901 + ((73 * fract) >> 10);        /* 2 <= x < 3 */
X           break;
X  case 3:
X  case 4:  val = 976 + (((x - 3072) * 20) >> 10);   /* 3 <= x < 5 */
X           break;
X  default: val = 1024;                              /* x >= 5 */
X            };
X          if (sum < 0) u->oj = 1024 - val; else u->oj = val;
X          u = u->next;
X         };
X      layer = layer->next;
X    };
X};
X
Xshort backoutput()  /* computes weight changes from the output layer */
X{
X  register short deltaj;
X  register int temp;
X  register short temp2;
X  register short temp3;
X  register short adiff;
X  register UNIT *bunit;
X  register WTNODE *w;
X  register UNIT *u;
X  register PATNODE *t;
X  register short notclose;
X
X notclose = last->unitcount;
X u = (UNIT *) last->units;
X t = (PATNODE *) last->currentpat->pats;
X while (u != NULL)
X   { 
X     temp3 = u->oj;
X     temp2 = t->val - temp3;
X     if (temp2 > 0) adiff = temp2; else adiff = -temp2;
X     if (adiff < toler) notclose = notclose - 1;
X     totaldiff = totaldiff + adiff;
X     if (adiff >= toler || backprop)  /* then compute errors */
X       {
X         if (deriv == 'd') /* diff. step size method */
X            deltaj = temp2;
X         else if (deriv == 'f') /* Fahlman's derivative */
X            {
X              temp = temp2 * (104448 + temp3 * ((short)(1024 - temp3)));
X              if (temp > 0) deltaj = (temp + 524288) >> 20;
X              else deltaj = -((524288 - temp) >> 20);
X            }
X         else /* the derivative in the original formula */
X            {
X              temp = temp2 * (temp3 * ((short)(1024 - temp3)));
X              if (temp > 0) deltaj = (temp + 524288) >> 20;
X              else deltaj = -((524288 - temp) >> 20);
X            }
X         w = (WTNODE *) u->wtlist;
X#ifdef SYMMETRIC
X         while (w->next != NULL)  /* skips threshold unit at end */
X#else
X         while (w != NULL)
X#endif
X            {
X              bunit = (UNIT *) w->backunit;
X#ifdef SYMMETRIC
X              *(w->total) = *(w->total) + deltaj * bunit->oj;
X#else
X              w->total = w->total + deltaj * bunit->oj;
X              if (bunit->layernumber > 1)
X                 bunit->error = bunit->error + deltaj * w->weight;
X#endif
X              w = w->next;
X            }
X       };
X     u = u->next;
X     t = t->next;
X   };
X  return(notclose);
X}
X
X#ifndef SYMMETRIC
X
Xvoid backinner()             /* Computes slopes and passes back */
X{                            /* errors from hidden layers.      */
X   register short deltaj;
X   register int temp;
X   register short temp3;
X   register UNIT *bunit;
X   register WTNODE *w;
X   register UNIT *u;
X   LAYER *layer;
X
X  layer = last->backlayer;
X  while (layer->backlayer != NULL)
X    {
X      u = (UNIT *) layer->units;
X      while (u != NULL)
X        {
X          temp3 = u->oj;
X          if (deriv == 'f') /* Fahlman's derivative */
X             temp = (((short)((temp3*((short)(1024-temp3))+512) >> 10))
X                    + 102) * u->error;
X          else /* either for the original or diff. step size */
X             temp = ((short)((temp3*((short)(1024-temp3))+512) >> 10))
X                    * u->error;
X          if (temp > 0) deltaj = (temp + 524288) >> 20;
X          else deltaj = -((524288 - temp) >> 20);
X          w = (WTNODE *) u->wtlist;
X          while (w != NULL)
X            {
X              bunit = (UNIT *) w->backunit;
X              w->total = w->total + deltaj * bunit->oj;
X              if (bunit->layernumber > 1)
X                 bunit->error = bunit->error + deltaj * w->weight;
X              w = w->next;
X            };
X          u = u->next;
X        };
X      layer = layer->backlayer;
X    };
X}
X
X#endif
X
Xvoid updatej() /* Jacob's delta-bar-delta method for weight updates */
X{
X  register short rkappa;
X  register short temp2;
X  register short dbarm1;
X  register short rdecay;
X  register int temp;
X  register UNIT *u;
X  register WTNODE *w;
X  LAYER *layer;
X
X/* w->olddw is used for delta-bar minus 1 */
X
X rkappa = kappa;
X rdecay = decay;
X layer = last;
X while (layer->backlayer != NULL)
X  {
X   u = (UNIT *) layer->units;
X   while (u != NULL)
X    {
X     w = (WTNODE *) u->wtlist;
X     while (w != NULL)
X      {
X#ifdef SYMMETRIC
X       if (((UNIT *) w->backunit)->unitnumber > u->unitnumber)
X          {
X            if (*(w->total) > 0) temp2 = (*(w->total) + 512) >> 10;
X            else temp2 = -((512 - *(w->total)) >> 10);
X            dbarm1 = *(w->olddw);
X            temp = theta2 * temp2 + theta1 * dbarm1;
X            if (temp > 0) *(w->olddw) = (temp + 512) >> 10;
X            else *(w->olddw) = -((512 - temp) >> 10);
X            if ((temp2 > 0) && (dbarm1 > 0))
X               *(w->eta) = *(w->eta) + rkappa;
X            else if ((temp2 < 0) && (dbarm1 < 0))
X               *(w->eta) = *(w->eta) + rkappa;
X            else if ((temp2 > 0) && (dbarm1 < 0))
X               *(w->eta) = (*(w->eta) * rdecay) >> 10;
X            else if ((temp2 < 0) && (dbarm1 > 0))
X               *(w->eta) = (*(w->eta) * rdecay) >> 10;
X            if (*(w->eta) > etamax) *(w->eta) = etamax;
X            temp = temp2 * *(w->eta);
X            if (temp > 0) temp2 = (temp + 512) >> 10;
X            else temp2 = -((512 - temp) >> 10);
X            *(w->weight) = *(w->weight) + temp2;
X          };
X#else
X       if (w->total > 0) temp2 = (w->total + 512) >> 10;
X       else temp2 = -((512 - w->total) >> 10);
X       dbarm1 = w->olddw;
X       temp = theta2 * temp2 + theta1 * dbarm1;
X       if (temp > 0) w->olddw = (temp + 512) >> 10;
X       else w->olddw = -((512 - temp) >> 10);
X       if (temp2 > 0 && dbarm1 > 0) w->eta = w->eta + rkappa;
X       else if (temp2 < 0 && dbarm1 < 0) w->eta = w->eta + rkappa;
X       else if (temp2 > 0 && dbarm1 < 0)
X          w->eta = (w->eta * rdecay) >> 10;
X       else if (temp2 < 0 && dbarm1 > 0)
X          w->eta = (w->eta * rdecay) >> 10;
X       if (w->eta > etamax) w->eta = etamax;
X       temp = temp2 * w->eta;
X       if (temp > 0) temp2 = (temp + 512) >> 10;
X       else temp2 = -((512 - temp) >> 10);
X       w->weight = w->weight + temp2;
X#endif
X       w = w->next;
X      };
X     u = u->next;
X    };
X   layer = layer->backlayer;
X  };
X}
X
Xvoid updateo()           /* update weights for the original method */
X{                        /* and the differential step size algorithm */
X  register short reta;
X  register short ralpha;
X  register int temp;
X  register UNIT *u;
X  register WTNODE *w;
X  LAYER *layer;
X
X ralpha = alpha;
X reta = eta;
X layer = last;
X while (layer->backlayer != NULL)
X  {
X   if (layer != last && update == 'd') reta = eta2;
X   u = (UNIT *) layer->units;
X   while (u != NULL)
X    {
X     w = (WTNODE *) u->wtlist;
X     while (w != NULL)
X      {
X#ifdef SYMMETRIC
X       if (((UNIT *) w->backunit)->unitnumber > u->unitnumber)
X          {
X            if (*(w->total) > 0)
X               temp = ((*(w->total) + 512) >> 10) * reta
X                      + ralpha * *(w->olddw);
X            else temp = -((512 - *(w->total)) >> 10) * reta
X                        + ralpha * *(w->olddw);
X            if (temp > 0) *(w->olddw) = (temp + 512) >> 10;
X            else *(w->olddw) = -((512 - temp) >> 10);
X            *(w->weight) = *(w->weight) + *(w->olddw);
X          };
X#else
X       if (w->total > 0)
X          temp = ((w->total + 512) >> 10) * reta + ralpha * w->olddw;
X       else
X          temp = -((512 - w->total) >> 10) * reta + ralpha * w->olddw;
X       if (temp > 0) w->olddw = (temp + 512) >> 10;
X       else w->olddw = -((512 - temp) >> 10);
X       w->weight = w->weight + w->olddw;
X#endif
X       w = w->next;
X      };
X     u = u->next;
X    };
X   layer = layer->backlayer;
X  };
X}
X
Xshort cbackoutput()          /* The continuous update version */
X{                            /* of back-propagation */
X  register short deltaj;
X  register int etadeltaj;
X  register int temp;
X  register int temp2;
X  register short temp3;
X  register short adiff;
X  register UNIT *bunit;
X  register WTNODE *w;
X  register UNIT *u;
X  register PATNODE *t;
X  register short ralpha;
X  register short notclose;
X
X ralpha = alpha;
X notclose = last->unitcount;
X u = (UNIT *) last->units;
X t = (PATNODE *) last->currentpat->pats;
X while (u != NULL)
X  { 
X   temp3 = u->oj;
X   temp2 = t->val - temp3;
X   if (temp2 > 0) adiff = temp2; else adiff = -temp2;
X   if (adiff < toler) notclose = notclose - 1;
X   totaldiff = totaldiff + adiff;
X   if (adiff >= toler || backprop)
X    {
X     if (deriv == 'd') /* the differential step size method */
X        deltaj = temp2;
X     else if (deriv == 'f') /* Fahlman's derivative */
X        { /* deltaj = (t->val - u->oj) * [0.1 + u->oj*(1.0 - u->oj)] */
X          temp = temp2 * (104448 + temp3 * ((short)(1024 - temp3)));
X          if(temp > 0) deltaj = (temp + 524288) >> 20;
X          else deltaj = -((524288 - temp) >> 20);
X        }
X     else /* the original derivative */
X        { /* deltaj = (t->val - u->oj) * u->oj * (1.0 - u->oj) */
X          temp = temp2 * (temp3 * ((short)(1024 - temp3)));
X          if(temp > 0) deltaj = (temp + 524288) >> 20;
X          else deltaj = -((524288 - temp) >> 20);
X        };
X     etadeltaj = deltaj * eta;
X     w = (WTNODE *) u->wtlist;
X#ifdef SYMMETRIC
X     while (w->next != NULL)
X#else
X     while (w != NULL)
X#endif
X        { /* get a slope for each weight */
X          bunit = (UNIT *) w->backunit;
X          temp = etadeltaj * bunit->oj;
X          if(temp > 0) temp = (temp + 524288) >> 20;
X          else temp = -((524288 - temp) >> 20);
X#ifdef SYMMETRIC
X          temp2 = ralpha * *(w->olddw);
X#else
X          temp2 = ralpha * w->olddw;
X#endif
X          if (temp2 > 0) temp3 = temp + ((temp2 + 512) >> 10);
X          else temp3 = temp - ((512 - temp2) >> 10);
X#ifdef SYMMETRIC
X          *(w->olddw) = temp3;
X#else
X          w->olddw = temp3;
X#endif
X          /* w->weight = w->weight + w->olddw */
X#ifdef SYMMETRIC
X          temp3 = *(w->weight) + temp3;
X          *(w->weight) = temp3;
X#else
X          temp3 = w->weight + temp3;
X          w->weight = temp3;
X          if (bunit->layernumber > 1)
X             bunit->error = bunit->error + deltaj * temp3;
X#endif
X          w = w->next;
X        }
X      }
X     u = u->next;
X     t = t->next;
X   }
X return(notclose);
X}
X
X#ifndef SYMMETRIC
X
Xvoid cbackinner()           /* Same as cbackoutput, except errors are */
X{                           /* calculated differently */
X   register short deltaj;
X   register int etadeltaj;
X   register int temp;
X   register int temp2;
X   register short temp3;
X   register short reta;
X   register short ralpha;
X   register UNIT *bunit;
X   register WTNODE *w;
X   register UNIT *u;
X   LAYER *layer;
X
X  if (update == 'C') reta = eta2; else reta = eta;
X  ralpha = alpha;
X  layer = last->backlayer;
X  while (layer->backlayer != NULL)
X   {
X    u = (UNIT *) layer->units;
X    while (u != NULL)
X     {
X      temp3 = u->oj;
X      if (deriv == 'f')  /* Fahlman's derivative */
X         temp = (((temp3 * ((short)(1024 - temp3)) + 512) >> 10) + 102)
X                 * u->error;
X      else  /* diff. step size and original derivative */
X         temp = ((temp3 * ((short)(1024 - temp3)) + 512) >> 10)
X                  * u->error;
X      if (temp > 0) deltaj = (temp + 524288) >> 20;
X      else deltaj = -((524288 - temp) >> 20);
X      etadeltaj = reta * deltaj;
X      w = (WTNODE *) u->wtlist;
X      while (w != NULL)
X       {
X        bunit = (UNIT *) w->backunit;
X        temp = etadeltaj * bunit->oj;
X        if (temp > 0) temp = (temp + 524288) >> 20;
X        else temp = -((524288 - temp) >> 20);
X        temp2 = ralpha * w->olddw;
X        if (temp2 > 0) temp3 = temp + ((temp2 + 512) >> 10);
X        else temp3 = temp - ((512 - temp2) >> 10);
X        w->olddw = temp3;
X        temp3 = w->weight + temp3;
X        w->weight = temp3;
X        if (bunit->layernumber > 1)
X           bunit->error = bunit->error + deltaj * temp3;
X        w = w->next;
X       };
X      u = u->next;
X     };
X    layer = layer->backlayer;
X   };
X}
X
X#endif
END_OF_FILE
if test 14277 -ne `wc -c <'int.c'`; then
    echo shar: \"'int.c'\" unpacked with wrong size!
fi
# end of 'int.c'
fi
if test -f 'real.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'real.c'\"
else
echo shar: Extracting \"'real.c'\" \(10454 characters\)
sed "s/^X//" >'real.c' <<'END_OF_FILE'
X/* *********************************************************** */
X/* file real.c:  contains the network evaluation and weight    */
X/* adjustment procedures for the 64-bit floating point program */
X/*                                                             */
X/* Copyright (c) 1990 by Donald R. Tveter                      */
X/*                                                             */
X/* *********************************************************** */
X
X#include "rbp.h"
X#include <stdio.h>
X
Xextern char activation;
Xextern double alpha;
Xextern char backprop;
Xextern double D;
Xextern double decay;
Xextern char deriv;
Xextern double eta;
Xextern double eta2;
Xextern double etamax;
Xextern double kappa;
Xextern LAYER *last;
Xextern LAYER *start;
Xextern double theta1;
Xextern double theta2;
Xextern double toler;
Xextern double totaldiff;
Xextern char update;
X
Xextern double exp(); /* a built-in function */
X
Xvoid forward()       /* computes unit activations */
X{
X  UNIT *u, *predu;
X  LAYER *layer;
X  WTNODE *b;
X  double fract, x, val;
X  double sum;
X  int intpart;
X
X layer = start->next;
X while (layer != NULL)
X   {
X     u = (UNIT *) layer->units;
X     while (u != NULL)
X       {
X         sum = 0.0;
X         b = (WTNODE *) u->wtlist;
X         while (b != NULL)
X           {
X             predu = (UNIT *) b->backunit;
X#ifdef SYMMETRIC
X             sum = sum + *(b->weight) * predu->oj;
X#else
X             sum = sum + b->weight * predu->oj;
X#endif
X             b = b->next;
X           };
X          sum = sum * D;
X          if (activation == 's') u->oj = 1.0 / (1.0 + exp(-sum));
X          else
X             { /* piecewise linear, the fast way */
X              if (sum >= 0.0) x = sum; else x = - sum;
X              intpart = x;
X              fract = x - intpart;
X              switch (intpart)
X                {
X     case 0:  val = 0.5 + 0.231 * fract;          /* 0 <= x < 1 */
X              break;
X     case 1:  val = 0.731059 + 0.149738 * fract;  /* 1 <= x < 2 */
X              break;
X     case 2:  val = 0.880797 + 0.071777 * fract;  /* 2 <= x < 3 */
X              break;
X     case 3:
X     case 4:  val = 0.9525741 + (x - 3.0) * 0.02; /* 3 <= x < 5 */
X              break;
X     default: val = 1.0;                          /* x >= 5 */
X                };
X              if (sum < 0.0) u->oj = 1.0 - val; else u->oj = val;
X             }  /* end of the fast way */
X           u = u->next;
X       };
X    layer = layer->next;
X   };
X}
X
Xshort backoutput()  /* back propagate errors from the output units */
X{                   /* send down errors for any previous layers    */
X double deltaj, diff, adiff;
X register UNIT *u, *bunit;
X register WTNODE *w;
X register PATNODE *t;
X register short notclose;
X
X notclose = last->unitcount;
X u = (UNIT *) last->units;
X t = (PATNODE *) last->currentpat->pats;
X while (u != NULL)
X  {
X   diff = t->val - u->oj;
X   if (diff > 0) adiff = diff; else adiff = -diff;
X   if (adiff < toler) notclose = notclose - 1;
X   totaldiff = totaldiff + adiff;
X   if (adiff >= toler || backprop)
X    {
X     if (deriv == 'd') /* differential step size */
X        deltaj = diff;
X     else if (deriv == 'f') /* Fahlman's derivative */
X        deltaj = diff * (0.1 + u->oj * (1.0 - u->oj));
X     else /* the original derivative */
X        deltaj = diff * u->oj * (1.0 - u->oj);
X     w = (WTNODE *) u->wtlist;
X#ifdef SYMMETRIC
X     while (w->next != NULL)
X#else
X     while (w != NULL)
X#endif
X      {
X        bunit = (UNIT *) w->backunit;
X#ifdef SYMMETRIC
X        *(w->total) = *(w->total) + deltaj * bunit->oj;
X#else
X        w->total = w->total + deltaj * bunit->oj;
X        if (bunit->layernumber > 1)  /* pass back the error */
X           bunit->error = bunit->error + deltaj * w->weight;
X#endif
X        w = w->next;
X      };
X    }
X   u = u->next;
X   t = t->next;
X  }
X return(notclose);
X}
X
X#ifndef SYMMETRIC
X
Xvoid backinner()  /* compute weight changes for hidden layers */
X{                 /* send down errors for any previous layers */
X  LAYER *layer;
X  double deltaj;
X  register UNIT *bunit;
X  register WTNODE *w;
X  register UNIT *u;
X
X  layer = last->backlayer;
X  while (layer->backlayer != NULL)
X     {
X       u = (UNIT *) layer->units;
X       while (u != NULL)
X          {
X            if (deriv == 'f') /* Fahlman's derivative */
X               deltaj = (0.1 + u->oj * (1.0 - u->oj)) * u->error;
X            else /* original and diff. step size derivative */
X               deltaj = (u->oj * (1.0 - u->oj)) * u->error;
X            w = (WTNODE *) u->wtlist;
X            while (w != NULL)
X               {
X                 bunit = (UNIT *) w->backunit;
X                 w->total = w->total + deltaj * bunit->oj;
X                 if (bunit->layernumber > 1)
X                    bunit->error = bunit->error + deltaj * w->weight;
X                 w = w->next;
X               };
X            u = u->next;
X          };
X       layer = layer->backlayer;
X     };
X}
X
X#endif
X
Xvoid updatej() /* Jacob's delta-bar-delta method for changing weights */
X{
X  register short stotal;
X  register short sdbarm1;
X  register UNIT *u;
X  register WTNODE *w;
X  LAYER *layer;
X
X  /* w->olddw is used for delta-bar minus 1 */
X
X layer = last;
X while (layer->backlayer != NULL)
X  {
X   u = (UNIT *) layer->units;
X   while (u != NULL)
X    {
X     w = (WTNODE *) u->wtlist;
X     while (w != NULL)
X      {
X#ifdef SYMMETRIC
X       if (((UNIT *) w->backunit)->unitnumber > u->unitnumber)
X          {
X            if (*(w->total) > 0) stotal = 1;
X               else if (*(w->total) < 0) stotal = -1;
X               else stotal = 0;
X            if (*(w->olddw) > 0) sdbarm1 = 1;
X               else if (*(w->olddw) < 0) sdbarm1 = -1;
X               else sdbarm1 = 0;
X            *(w->olddw) = theta2 * *(w->total) + theta1 * *(w->olddw);
X            if ((stotal > 0) && (sdbarm1 > 0))
X               *(w->eta) = *(w->eta) + kappa;
X            else if ((stotal < 0) && (sdbarm1 < 0))
X               *(w->eta) = *(w->eta) + kappa;
X            else if ((stotal > 0) && (sdbarm1 < 0))
X               *(w->eta) = *(w->eta) * decay;
X            else if ((stotal < 0) && (sdbarm1 > 0))
X               *(w->eta) = *(w->eta) * decay;
X            if (*(w->eta) > etamax) *(w->eta) = etamax;
X            *(w->weight) = *(w->weight) + *(w->total) * *(w->eta);
X          };
X#else
X       if (w->total > 0) stotal = 1;
X          else if (w->total < 0) stotal = -1;
X          else stotal = 0;
X       if (w->olddw > 0) sdbarm1 = 1;
X          else if (w->olddw < 0) sdbarm1 = -1;
X          else sdbarm1 = 0;
X       w->olddw = theta2 * w->total + theta1 * w->olddw;
X       if ((stotal > 0) && (sdbarm1 > 0)) w->eta = w->eta + kappa;
X       else if ((stotal < 0) && (sdbarm1 < 0)) w->eta = w->eta + kappa;
X       else if ((stotal > 0) && (sdbarm1 < 0)) w->eta = w->eta * decay;
X       else if ((stotal < 0) && (sdbarm1 > 0)) w->eta = w->eta * decay;
X       if (w->eta > etamax) w->eta = etamax;
X       w->weight = w->weight + w->total * w->eta;
X#endif
X       w = w->next;
X      };
X     u = u->next;
X    };
X   layer = layer->backlayer;
X  };
X}
X
Xvoid updateo()        /* update weights for the original and the */
X{                     /* differential step size methods */
X  double reta;
X  register UNIT *u;
X  register WTNODE *w;
X  LAYER *layer;
X
X reta = eta;
X layer = last;
X while (layer->backlayer != NULL)
X  {
X   if (layer != last && update == 'd') reta = eta2;
X   u = (UNIT *) layer->units;
X   while (u != NULL)
X    {
X     w = (WTNODE *) u->wtlist;
X     while (w != NULL)
X      {
X#ifdef SYMMETRIC
X       if (((UNIT *) w->backunit)->unitnumber > u->unitnumber)
X          {
X            *(w->olddw) = *(w->total) * reta + alpha * *(w->olddw);
X            *(w->weight) = *(w->weight) + *(w->olddw);
X          };
X#else
X       w->olddw = w->total * reta + alpha * w->olddw;
X       w->weight = w->weight + w->olddw;
X#endif
X       w = w->next;
X      };
X     u = u->next;
X    };
X   layer = layer->backlayer;
X  };
X}
X
Xshort cbackoutput()  /* backoutput for continuous updates */
X{
X double deltaj, etadeltaj, diff, adiff;
X register UNIT *u, *bunit;
X register WTNODE *b;
X register PATNODE *t;
X register short notclose;
X
X notclose = last->unitcount;
X u = (UNIT *) last->units;
X t = (PATNODE *) last->currentpat->pats;
X while (u != NULL)
X  {
X   diff = t->val - u->oj;
X   if (diff > 0) adiff = diff; else adiff = -diff;
X   if (adiff < toler) notclose = notclose - 1;
X   totaldiff = totaldiff + adiff;
X   if (adiff >= toler || backprop)
X    {
X     if (deriv == 'd') /* differential step size derivative */
X        deltaj = diff;
X     else if (deriv == 'f') /* Fahlman's derivative */
X        deltaj = diff * (0.1 + u->oj * (1.0 - u->oj));
X     else /* the original derivative */
X        deltaj = diff * u->oj * (1.0 - u->oj);
X     etadeltaj = deltaj * eta;
X     b = (WTNODE *) u->wtlist;
X#ifdef SYMMETRIC
X     while (b->next != NULL)
X#else
X     while (b != NULL)
X#endif
X      {
X       bunit = (UNIT *) b->backunit;
X#ifdef SYMMETRIC
X       *(b->olddw) = etadeltaj * bunit->oj + alpha * *(b->olddw);
X       *(b->weight) = *(b->weight) + *(b->olddw);
X#else
X       b->olddw = etadeltaj * bunit->oj + alpha * b->olddw;
X       b->weight = b->weight + b->olddw;
X       if (bunit->layernumber > 1)
X          bunit->error = bunit->error + deltaj * b->weight;
X#endif
X       b = b->next;
X      };
X    };
X   u = u->next;
X   t = t->next;
X  }
X return(notclose);
X}
X
X#ifndef SYMMETRIC
X
Xvoid cbackinner()  /* backinner for continuous updates */
X{
X  LAYER *layer;
X  double deltaj, etadeltaj, reta;
X  register UNIT *bunit, *u;
X  register WTNODE *b;
X
X  if (update == 'D') reta = eta2; else reta = eta;
X  layer = last->backlayer;
X  while (layer->backlayer != NULL)
X     {
X       u = (UNIT *) layer->units;
X       while (u != NULL)
X          {
X            if (deriv == 'f') /* Fahlman's derivative */
X               deltaj = (0.1 + u->oj * (1.0 - u->oj)) * u->error;
X            else /* the diff. step size and original derivative */
X               deltaj = (u->oj * (1.0 - u->oj)) * u->error;
X            etadeltaj = reta * deltaj;
X            b = (WTNODE *) u->wtlist;
X            while (b != NULL)
X               {
X                 bunit = (UNIT *) b->backunit;
X                 b->olddw = etadeltaj * bunit->oj + alpha * b->olddw;
X                 b->weight = b->weight + b->olddw;
X                 if (bunit->layernumber > 1)
X                    bunit->error = bunit->error + deltaj * b->weight;
X                 b = b->next;
X               };
X            u = u->next;
X          };
X       layer = layer->backlayer;
X     };
X}
X#endif
END_OF_FILE
if test 10454 -ne `wc -c <'real.c'`; then
    echo shar: \"'real.c'\" unpacked with wrong size!
fi
# end of 'real.c'
fi
if test -f 'misc.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'misc.c'\"
else
echo shar: Extracting \"'misc.c'\" \(11006 characters\)
sed "s/^X//" >'misc.c' <<'END_OF_FILE'
X/* **************************************************** */
X/* file misc.c:  contains pattern manipulation routines */
X/*               and miscellaneous other functions.     */
X/*                                                      */
X/* Copyright (c) 1990 by Donald R. Tveter               */
X/*                                                      */
X/* **************************************************** */
X
X#include <stdio.h>
X#ifdef INTEGER
X#include "ibp.h"
X#else
X#include "rbp.h"
X#endif
X
Xextern short backoutput();
Xextern void backinner();
Xextern short cbackoutput();
Xextern void cbackinner();
Xextern WTTYPE rdr();
Xextern WTTYPE readchar();
Xextern void saveweights();
Xextern WTTYPE scale();
Xextern double unscaleint();
Xextern void updatej();
Xextern void updateo();
X
Xextern char backprop;
Xextern FILE *data;
Xextern char datafilename[50];
Xextern UNIT *hlayer;
Xextern UNIT *ilayer;
Xextern char informat;
Xextern UNIT *jlayer;
Xextern UNIT *klayer;
Xextern LAYER *last;
Xextern int lastprint;
Xextern int npats;
Xextern int prevnpats;
Xextern int readerror;
Xextern int saverate;
Xextern int skiprate;
Xextern LAYER *start;
Xextern char summary;
Xextern WTTYPE toler;
X#ifdef INTEGER
Xextern int totaldiff;
X#else
Xextern double totaldiff;
X#endif
Xextern int totaliter;
Xextern int unlearnedpats;
Xextern char update;
Xextern WTTYPE wtlimit;
Xextern char wtlimithit;
Xextern int wttotal;
X
Xvoid nullpatterns()  /* dispose of any patterns before reading more */
X{
X  PATLIST *pl, *nextpl;
X  PATNODE *pn, *nextpn;
X  if (start->patstart != NULL)
X     {
X       pl = start->patstart;
X       nextpl = pl->next;
X       while (pl != NULL)
X          {
X            pn = pl->pats;
X            nextpn = pn->next;
X            while (pn != NULL)
X               {
X                 free(pn);
X                 pn = nextpn;
X                 nextpn = pn->next;
X               };
X            free(pl);
X            pl = nextpl;
X            nextpl = pl->next;
X          };
X       pl = last->patstart;
X       nextpl = pl->next;
X       while (pl != NULL)
X          {
X            pn = pl->pats;
X            nextpn = pn->next;
X            while (pn != NULL)
X               {
X                 free(pn);
X                 pn = nextpn;
X                 nextpn = pn->next;
X               };
X            free(pl);
X            pl = nextpl;
X            nextpl = pl->next;
X          };
X     };
X  start->patstart = NULL;
X  last->patstart = NULL;
X  npats = 0;
X  prevnpats = 0;
X}
X
Xvoid resetpats()
X{
X start->currentpat = NULL;
X last->currentpat = NULL;
X}
X
Xvoid findendofpats(layer)  /* purpose is to set all layer->currentpat */
XLAYER *layer;              /* fields to end of pattern list so more   */
X                           /* patterns can be added at the end.       */
X{
X PATLIST *pl;
X
X pl = (PATLIST *) layer->patstart;
X while (pl->next != NULL) pl = pl->next;
X layer->currentpat = pl;
X}
X
Xint copyhidden(input,hidden,l)
XUNIT *input, **hidden;
Xint l;
X{
X  if (hidden == NULL)
X     {
X       printf("ran out of hidden units in layer %d\n",l);
X       return(1);
X     }
X  input->oj = (*hidden)->oj;
X  *hidden = (*hidden)->next;
X  return(0);
X}
X
Xvoid nextpat()
X{
X  if (start->currentpat == NULL)
X     {
X       start->currentpat = start->patstart;
X       last->currentpat = last->patstart;
X     }
X  else
X     {
X       start->currentpat = (start->currentpat)->next;
X       last->currentpat = (last->currentpat)->next;
X     };
X}
X
Xvoid setonepat()       /* sets up patterns on input units */
X{
X  register PATNODE *p;
X  register UNIT *u;
X  register LAYER *innerlayers;
X  UNIT *hunit, *iunit, *junit, *kunit;
X  PATLIST *pl;
X  
X  hunit = hlayer;
X  iunit = ilayer;
X  junit = jlayer;
X  kunit = klayer;
X  pl = start->currentpat;
X  p = (PATNODE *) pl->pats;
X  u = (UNIT *) start->units;
X  while (p != NULL)
X     {
X       if (p->val > KCODE) u->oj = p->val;
X       else if (p->val == HCODE)
X               {if (copyhidden(u,&hunit,2) == 1) return;}
X       else if (p->val == ICODE)
X               {if (copyhidden(u,&iunit,3) == 1) return;}
X       else if (p->val == JCODE)
X               {if (copyhidden(u,&junit,4) == 1) return;}
X       else if (copyhidden(u,&kunit,5) == 1) return;
X       u = u->next;
X       p = p->next;
X     };
X
X  innerlayers = start->next;
X  while (innerlayers->next != NULL)
X     {  /* set errors on the inner layer units to 0 */
X       u = (UNIT *) innerlayers->units;
X       while (u != NULL)
X          {
X            u->error = 0;
X            u = u->next;
X          };
X       innerlayers = innerlayers->next;
X     };
X}
X
Xvoid limitwts()
X{
X  register LAYER *layer;
X  register UNIT *u;
X  register WTNODE *w;
X
X  layer = start->next;
X  while (layer != NULL)
X   {
X    u = (UNIT *) layer->units;
X    while (u != NULL)
X     {
X      w = (WTNODE *) u->wtlist;
X      while (w != NULL)
X       {
X#ifdef SYMMETRIC
X        if (*(w->weight) > wtlimit)
X           {
X             *(w->weight) = wtlimit;
X             wtlimithit = 1;
X           }
X        else if (*(w->weight) < -wtlimit)
X           {
X             *(w->weight) = -wtlimit;
X             wtlimithit = 1;
X           };
X#else
X        if (w->weight > wtlimit)
X           {
X             w->weight = wtlimit;
X             wtlimithit = 1;
X           }
X        else if (w->weight < -wtlimit)
X           {
X             w->weight = -wtlimit;
X             wtlimithit = 1;
X           };
X#endif
X        w = w->next;
X       };
X      u = u->next;
X     };
X    layer = layer->next;
X   };
X}
X
X#ifndef SYMMETRIC
X
Xvoid whittle(amount)    /* removes weights whose absolute */
XWTTYPE amount;          /* value is less than amount      */
X{LAYER *layer;
X UNIT *u;
X WTNODE *w, *wprev;
X
X layer = start->next;
X while (layer != NULL)
X   {
X     u = (UNIT *) layer->units;
X     while (u != NULL)
X       {
X         w = (WTNODE *) u->wtlist;
X         wprev = (WTNODE *) NULL;
X         while (w->next != (WTNODE *) NULL)
X           {
X             if ((w->weight) < amount && (w->weight) > -amount)
X               {
X                 if (wprev == NULL) (WTNODE *) u->wtlist = w->next;
X                 else (WTNODE *) wprev->next = w->next;
X                 wttotal = wttotal - 1;
X               }
X             else wprev = w;
X             w = w->next;
X           }
X         u = u->next;
X       }
X     layer = layer->next;
X   }
X}
X
X#endif
X
Xvoid oneset() /* go through the patterns once and update weights */
X{ int i;
X  LAYER *layer;
X  register UNIT *u;
X  register WTNODE *w;
X  short numbernotclose, attempted, passed;
X
Xbegin:
X layer = last;      /* make all b->totals = 0 */
X while (layer->backlayer != NULL)
X    {
X      u = (UNIT *) layer->units;
X      while (u != NULL)
X         {
X           w = (WTNODE *) u->wtlist;
X           while (w != NULL)
X              {
X#ifdef SYMMETRIC
X                *(w->total) = 0;
X#else
X                w->total = 0;
X#endif
X                w = w->next;
X              };
X           u = u->next;
X         };
X      layer = layer->backlayer;
X    };
X attempted = 0;
X passed = 0;
X unlearnedpats = npats;
X resetpats();
X for(i=1;i<=npats;i++)
X    {
X      nextpat();
X      if (last->currentpat->bypass <= 0)
X         {
X           setonepat();
X           forward();
X           attempted = attempted + 1;
X           if (update == 'c' || update == 'C')
X              numbernotclose = cbackoutput();
X           else numbernotclose = backoutput();
X           if (numbernotclose != 0)
X              {
X#ifndef SYMMETRIC
X                if (update == 'c' || update == 'C') cbackinner();
X                else backinner();
X#endif
X              }
X           else /* this one pattern has been learned */
X              {
X                passed = passed + 1;
X                unlearnedpats = unlearnedpats - 1;
X                last->currentpat->bypass = skiprate;
X#ifndef SYMMETRIC
X                if (backprop)
X                   {
X                     if (update == 'c' || update == 'C') cbackinner();
X                     else backinner();
X                   };
X#endif
X              }
X         }
X      else last->currentpat->bypass = last->currentpat->bypass - 1;
X    };
X if (unlearnedpats == 0) return;
X if (attempted == passed)
X    {
X      resetpats();
X      for (i=1;i<=npats;i++)
X         {
X           nextpat();
X           last->currentpat->bypass = 0;
X         };
X      goto begin;
X    };
X if (update == 'j') updatej();
X else if (update == 'o' || update == 'd') updateo();
X if (wtlimit != 0) limitwts();
X}
X
Xvoid kick(size,amount) /* give the network a kick */
XWTTYPE size;
XWTTYPE amount;
X{ LAYER *layer;
X  UNIT *u;
X  WTNODE *w;
X  WTTYPE value;
X  WTTYPE delta;
X  int sign;
X
X  layer = start->next;
X  while (layer != NULL)
X   {
X    u = (UNIT *) layer->units;
X    while (u != NULL)
X     {
X      w = (WTNODE *) u->wtlist;
X      while (w != NULL)
X       {
X#ifdef SYMMETRIC
X         value = *(w->weight);
X#else
X         value = w->weight;
X#endif
X         if (value != 0) sign = 1;
X         else if (rand() > 16383) sign = -1;
X         else sign = 1;
X         delta = (sign * amount * rand()) / 32768;
X         if (value >= size) value = value - delta;
X         else if (value < -size) value = value + delta;
X#ifdef SYMMETRIC
X         if (((UNIT *) w->backunit)->unitnumber != u->unitnumber)
X            *(w->weight) = value;
X#else
X         w->weight = value;
X#endif
X         w = w->next;
X       }
X      u = u->next;
X     }
X    layer = layer->next;
X   } 
X}
X
Xvoid printpats(first,finish,printheader,printerrors,callfromrun)
Xint first,finish,printheader,printerrors,callfromrun;
X{
X  int i;
X  double err;
X
X  if (summary == '+' && callfromrun)
X     {
X       printf("%6d   ",totaliter);
X       printf("%6d learned ",npats-unlearnedpats);
X       printf("%6d unlearned     ",unlearnedpats);
X       err = unscaleint(totaldiff) / (npats * last->unitcount);
X       printf("%7.5lf error/unit\n",err);
X       return;
X     };
X  lastprint = totaliter;
X  if (printheader == 1)
X     printf("%d iterations, file = %s\n",totaliter,datafilename);
X  resetpats();
X  for (i=2;i<=first;i++) nextpat();
X  for (i=first;i<=finish;i++)
X     { 
X       nextpat();
X       setonepat();
X       printf("%3d ",i);
X       forward();
X       printoutunits(last,printerrors);
X     };
X}
X
Xvoid run(n,prpatsrate)
Xint n;              /* the number of iterations to run */
Xint prpatsrate;     /* rate at which to print output patterns */
X
X{ int i;
X  char wtlimitbefore;
X
X  printf("running . . .\n");
X  for (i=1;i<=n;i++)
X    {
X      totaldiff = 0;
X      wtlimitbefore = wtlimithit;
X      oneset();
X      totaliter = totaliter + 1;
X      if (wtlimitbefore == 0 && wtlimithit == 1)
X         printf(">>>>> WEIGHT LIMIT HIT <<<<< at %d\n",totaliter);
X      if (unlearnedpats == 0)
X        {
X          if (update != 'c' && update != 'C') totaliter = totaliter - 1;
X          if ((prpatsrate > 0) && (lastprint != totaliter))
X             printpats(1,npats,1,1,1);
X          printf("patterns learned to within %4.2lf",unscale(toler));
X          printf(" at iteration %d\n",totaliter);
X          return;
X        };
X      if (totaliter % saverate == 0) saveweights();
X      if ((prpatsrate > 0) && ((i % prpatsrate == 0) || (i == n)))
X         printpats(1,npats,1,1,1);
X    };
X} 
END_OF_FILE
echo shar: 1 control character may be missing from \"'misc.c'\"
if test 11006 -ne `wc -c <'misc.c'`; then
    echo shar: \"'misc.c'\" unpacked with wrong size!
fi
# end of 'misc.c'
fi
echo shar: End of archive 4 \(of 4\).
cp /dev/null ark4isdone
MISSING=""
for I in 1 2 3 4 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 4 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0