home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume14 / back-prop / part04 / int.c next >
C/C++ Source or Header  |  1990-09-15  |  14KB  |  471 lines

  1. /* *********************************************************** */
  2. /* file int.c:  Contains the network evaluation and weight     */
  3. /*              adjustment procedures for the integer versions */
  4. /*              bp and sbp.                                    */
  5. /*                                                             */
  6. /* Copyright (c) 1990 by Donald R. Tveter                      */
  7. /*                                                             */
  8. /* The code here has been optimized for use with the Motorola  */
  9. /* MC 68010 processor and version 3.5 of the UNIX (tm) PC      */
  10. /* C compiler where UNIX is a trademark of Bell Laboratories.  */
  11. /* *********************************************************** */
  12.  
  13. #include "ibp.h"
  14. #include <stdio.h>
  15.  
  16. extern WTTYPE alpha;
  17. extern char backprop;
  18. extern WTTYPE D;
  19. extern WTTYPE decay;
  20. extern char deriv;
  21. extern WTTYPE eta;
  22. extern WTTYPE eta2;
  23. extern WTTYPE etamax;
  24. extern WTTYPE kappa;
  25. extern LAYER *last;
  26. extern LAYER *start;
  27. extern WTTYPE theta1;
  28. extern WTTYPE theta2;
  29. extern WTTYPE toler;
  30. extern int totaldiff;
  31. extern char update;
  32.  
  33. void forward()             /* computes unit activations */
  34.   register WTNODE *w;
  35.   register UNIT *u;
  36.   register UNIT *predu;
  37.   LAYER *layer;
  38.   register int sum;
  39.   register int x;
  40.   register short fract;
  41.   register short val;
  42.   register int intpart;
  43.  
  44.  layer = start->next;
  45.  while (layer != NULL)
  46.     {
  47.       u = (UNIT *) layer->units;
  48.       while (u != NULL)
  49.          {
  50.            sum = 0;
  51.            w = (WTNODE *) u->wtlist;
  52.            while (w != NULL)
  53.               {
  54.                 predu = (UNIT *) w->backunit;
  55. #ifdef SMART
  56. #   ifdef SYMMETRIC
  57.                 sum = sum + (*(w->weight) * predu->oj) / 1024;
  58. #   else
  59.                 sum = sum + (w->weight * predu->oj) / 1024;
  60. #   endif
  61. #else
  62. #   ifdef SYMMETRIC
  63.                 x = (*(w->weight) * predu->oj);
  64. #   else
  65.                 x = w->weight * predu->oj;
  66. #   endif
  67.                 if (x >= 0) sum = sum + (x >> 10);
  68.                 else sum = sum - ( (-x) >> 10);
  69. #endif
  70.                 w = w->next;
  71.               };
  72.            sum = (D * sum) / 1024;
  73.            if (sum > 0) x = sum; else x = -sum;
  74.            intpart = x >> 10;
  75.            fract = x - (intpart << 10);
  76.            switch (intpart)
  77.             {
  78.   case 0:  val = 512 + ((237 * fract) >> 10);       /* 0 <= x < 1 */
  79.            break;
  80.   case 1:  val = 748 + ((153 * fract) >> 10);       /* 1 <= x < 2 */
  81.            break;
  82.   case 2:  val = 901 + ((73 * fract) >> 10);        /* 2 <= x < 3 */
  83.            break;
  84.   case 3:
  85.   case 4:  val = 976 + (((x - 3072) * 20) >> 10);   /* 3 <= x < 5 */
  86.            break;
  87.   default: val = 1024;                              /* x >= 5 */
  88.             };
  89.           if (sum < 0) u->oj = 1024 - val; else u->oj = val;
  90.           u = u->next;
  91.          };
  92.       layer = layer->next;
  93.     };
  94. };
  95.  
  96. short backoutput()  /* computes weight changes from the output layer */
  97. {
  98.   register short deltaj;
  99.   register int temp;
  100.   register short temp2;
  101.   register short temp3;
  102.   register short adiff;
  103.   register UNIT *bunit;
  104.   register WTNODE *w;
  105.   register UNIT *u;
  106.   register PATNODE *t;
  107.   register short notclose;
  108.  
  109.  notclose = last->unitcount;
  110.  u = (UNIT *) last->units;
  111.  t = (PATNODE *) last->currentpat->pats;
  112.  while (u != NULL)
  113.    { 
  114.      temp3 = u->oj;
  115.      temp2 = t->val - temp3;
  116.      if (temp2 > 0) adiff = temp2; else adiff = -temp2;
  117.      if (adiff < toler) notclose = notclose - 1;
  118.      totaldiff = totaldiff + adiff;
  119.      if (adiff >= toler || backprop)  /* then compute errors */
  120.        {
  121.          if (deriv == 'd') /* diff. step size method */
  122.             deltaj = temp2;
  123.          else if (deriv == 'f') /* Fahlman's derivative */
  124.             {
  125.               temp = temp2 * (104448 + temp3 * ((short)(1024 - temp3)));
  126.               if (temp > 0) deltaj = (temp + 524288) >> 20;
  127.               else deltaj = -((524288 - temp) >> 20);
  128.             }
  129.          else /* the derivative in the original formula */
  130.             {
  131.               temp = temp2 * (temp3 * ((short)(1024 - temp3)));
  132.               if (temp > 0) deltaj = (temp + 524288) >> 20;
  133.               else deltaj = -((524288 - temp) >> 20);
  134.             }
  135.          w = (WTNODE *) u->wtlist;
  136. #ifdef SYMMETRIC
  137.          while (w->next != NULL)  /* skips threshold unit at end */
  138. #else
  139.          while (w != NULL)
  140. #endif
  141.             {
  142.               bunit = (UNIT *) w->backunit;
  143. #ifdef SYMMETRIC
  144.               *(w->total) = *(w->total) + deltaj * bunit->oj;
  145. #else
  146.               w->total = w->total + deltaj * bunit->oj;
  147.               if (bunit->layernumber > 1)
  148.                  bunit->error = bunit->error + deltaj * w->weight;
  149. #endif
  150.               w = w->next;
  151.             }
  152.        };
  153.      u = u->next;
  154.      t = t->next;
  155.    };
  156.   return(notclose);
  157. }
  158.  
  159. #ifndef SYMMETRIC
  160.  
  161. void backinner()             /* Computes slopes and passes back */
  162. {                            /* errors from hidden layers.      */
  163.    register short deltaj;
  164.    register int temp;
  165.    register short temp3;
  166.    register UNIT *bunit;
  167.    register WTNODE *w;
  168.    register UNIT *u;
  169.    LAYER *layer;
  170.  
  171.   layer = last->backlayer;
  172.   while (layer->backlayer != NULL)
  173.     {
  174.       u = (UNIT *) layer->units;
  175.       while (u != NULL)
  176.         {
  177.           temp3 = u->oj;
  178.           if (deriv == 'f') /* Fahlman's derivative */
  179.              temp = (((short)((temp3*((short)(1024-temp3))+512) >> 10))
  180.                     + 102) * u->error;
  181.           else /* either for the original or diff. step size */
  182.              temp = ((short)((temp3*((short)(1024-temp3))+512) >> 10))
  183.                     * u->error;
  184.           if (temp > 0) deltaj = (temp + 524288) >> 20;
  185.           else deltaj = -((524288 - temp) >> 20);
  186.           w = (WTNODE *) u->wtlist;
  187.           while (w != NULL)
  188.             {
  189.               bunit = (UNIT *) w->backunit;
  190.               w->total = w->total + deltaj * bunit->oj;
  191.               if (bunit->layernumber > 1)
  192.                  bunit->error = bunit->error + deltaj * w->weight;
  193.               w = w->next;
  194.             };
  195.           u = u->next;
  196.         };
  197.       layer = layer->backlayer;
  198.     };
  199. }
  200.  
  201. #endif
  202.  
  203. void updatej() /* Jacob's delta-bar-delta method for weight updates */
  204. {
  205.   register short rkappa;
  206.   register short temp2;
  207.   register short dbarm1;
  208.   register short rdecay;
  209.   register int temp;
  210.   register UNIT *u;
  211.   register WTNODE *w;
  212.   LAYER *layer;
  213.  
  214. /* w->olddw is used for delta-bar minus 1 */
  215.  
  216.  rkappa = kappa;
  217.  rdecay = decay;
  218.  layer = last;
  219.  while (layer->backlayer != NULL)
  220.   {
  221.    u = (UNIT *) layer->units;
  222.    while (u != NULL)
  223.     {
  224.      w = (WTNODE *) u->wtlist;
  225.      while (w != NULL)
  226.       {
  227. #ifdef SYMMETRIC
  228.        if (((UNIT *) w->backunit)->unitnumber > u->unitnumber)
  229.           {
  230.             if (*(w->total) > 0) temp2 = (*(w->total) + 512) >> 10;
  231.             else temp2 = -((512 - *(w->total)) >> 10);
  232.             dbarm1 = *(w->olddw);
  233.             temp = theta2 * temp2 + theta1 * dbarm1;
  234.             if (temp > 0) *(w->olddw) = (temp + 512) >> 10;
  235.             else *(w->olddw) = -((512 - temp) >> 10);
  236.             if ((temp2 > 0) && (dbarm1 > 0))
  237.                *(w->eta) = *(w->eta) + rkappa;
  238.             else if ((temp2 < 0) && (dbarm1 < 0))
  239.                *(w->eta) = *(w->eta) + rkappa;
  240.             else if ((temp2 > 0) && (dbarm1 < 0))
  241.                *(w->eta) = (*(w->eta) * rdecay) >> 10;
  242.             else if ((temp2 < 0) && (dbarm1 > 0))
  243.                *(w->eta) = (*(w->eta) * rdecay) >> 10;
  244.             if (*(w->eta) > etamax) *(w->eta) = etamax;
  245.             temp = temp2 * *(w->eta);
  246.             if (temp > 0) temp2 = (temp + 512) >> 10;
  247.             else temp2 = -((512 - temp) >> 10);
  248.             *(w->weight) = *(w->weight) + temp2;
  249.           };
  250. #else
  251.        if (w->total > 0) temp2 = (w->total + 512) >> 10;
  252.        else temp2 = -((512 - w->total) >> 10);
  253.        dbarm1 = w->olddw;
  254.        temp = theta2 * temp2 + theta1 * dbarm1;
  255.        if (temp > 0) w->olddw = (temp + 512) >> 10;
  256.        else w->olddw = -((512 - temp) >> 10);
  257.        if (temp2 > 0 && dbarm1 > 0) w->eta = w->eta + rkappa;
  258.        else if (temp2 < 0 && dbarm1 < 0) w->eta = w->eta + rkappa;
  259.        else if (temp2 > 0 && dbarm1 < 0)
  260.           w->eta = (w->eta * rdecay) >> 10;
  261.        else if (temp2 < 0 && dbarm1 > 0)
  262.           w->eta = (w->eta * rdecay) >> 10;
  263.        if (w->eta > etamax) w->eta = etamax;
  264.        temp = temp2 * w->eta;
  265.        if (temp > 0) temp2 = (temp + 512) >> 10;
  266.        else temp2 = -((512 - temp) >> 10);
  267.        w->weight = w->weight + temp2;
  268. #endif
  269.        w = w->next;
  270.       };
  271.      u = u->next;
  272.     };
  273.    layer = layer->backlayer;
  274.   };
  275. }
  276.  
  277. void updateo()           /* update weights for the original method */
  278. {                        /* and the differential step size algorithm */
  279.   register short reta;
  280.   register short ralpha;
  281.   register int temp;
  282.   register UNIT *u;
  283.   register WTNODE *w;
  284.   LAYER *layer;
  285.  
  286.  ralpha = alpha;
  287.  reta = eta;
  288.  layer = last;
  289.  while (layer->backlayer != NULL)
  290.   {
  291.    if (layer != last && update == 'd') reta = eta2;
  292.    u = (UNIT *) layer->units;
  293.    while (u != NULL)
  294.     {
  295.      w = (WTNODE *) u->wtlist;
  296.      while (w != NULL)
  297.       {
  298. #ifdef SYMMETRIC
  299.        if (((UNIT *) w->backunit)->unitnumber > u->unitnumber)
  300.           {
  301.             if (*(w->total) > 0)
  302.                temp = ((*(w->total) + 512) >> 10) * reta
  303.                       + ralpha * *(w->olddw);
  304.             else temp = -((512 - *(w->total)) >> 10) * reta
  305.                         + ralpha * *(w->olddw);
  306.             if (temp > 0) *(w->olddw) = (temp + 512) >> 10;
  307.             else *(w->olddw) = -((512 - temp) >> 10);
  308.             *(w->weight) = *(w->weight) + *(w->olddw);
  309.           };
  310. #else
  311.        if (w->total > 0)
  312.           temp = ((w->total + 512) >> 10) * reta + ralpha * w->olddw;
  313.        else
  314.           temp = -((512 - w->total) >> 10) * reta + ralpha * w->olddw;
  315.        if (temp > 0) w->olddw = (temp + 512) >> 10;
  316.        else w->olddw = -((512 - temp) >> 10);
  317.        w->weight = w->weight + w->olddw;
  318. #endif
  319.        w = w->next;
  320.       };
  321.      u = u->next;
  322.     };
  323.    layer = layer->backlayer;
  324.   };
  325. }
  326.  
  327. short cbackoutput()          /* The continuous update version */
  328. {                            /* of back-propagation */
  329.   register short deltaj;
  330.   register int etadeltaj;
  331.   register int temp;
  332.   register int temp2;
  333.   register short temp3;
  334.   register short adiff;
  335.   register UNIT *bunit;
  336.   register WTNODE *w;
  337.   register UNIT *u;
  338.   register PATNODE *t;
  339.   register short ralpha;
  340.   register short notclose;
  341.  
  342.  ralpha = alpha;
  343.  notclose = last->unitcount;
  344.  u = (UNIT *) last->units;
  345.  t = (PATNODE *) last->currentpat->pats;
  346.  while (u != NULL)
  347.   { 
  348.    temp3 = u->oj;
  349.    temp2 = t->val - temp3;
  350.    if (temp2 > 0) adiff = temp2; else adiff = -temp2;
  351.    if (adiff < toler) notclose = notclose - 1;
  352.    totaldiff = totaldiff + adiff;
  353.    if (adiff >= toler || backprop)
  354.     {
  355.      if (deriv == 'd') /* the differential step size method */
  356.         deltaj = temp2;
  357.      else if (deriv == 'f') /* Fahlman's derivative */
  358.         { /* deltaj = (t->val - u->oj) * [0.1 + u->oj*(1.0 - u->oj)] */
  359.           temp = temp2 * (104448 + temp3 * ((short)(1024 - temp3)));
  360.           if(temp > 0) deltaj = (temp + 524288) >> 20;
  361.           else deltaj = -((524288 - temp) >> 20);
  362.         }
  363.      else /* the original derivative */
  364.         { /* deltaj = (t->val - u->oj) * u->oj * (1.0 - u->oj) */
  365.           temp = temp2 * (temp3 * ((short)(1024 - temp3)));
  366.           if(temp > 0) deltaj = (temp + 524288) >> 20;
  367.           else deltaj = -((524288 - temp) >> 20);
  368.         };
  369.      etadeltaj = deltaj * eta;
  370.      w = (WTNODE *) u->wtlist;
  371. #ifdef SYMMETRIC
  372.      while (w->next != NULL)
  373. #else
  374.      while (w != NULL)
  375. #endif
  376.         { /* get a slope for each weight */
  377.           bunit = (UNIT *) w->backunit;
  378.           temp = etadeltaj * bunit->oj;
  379.           if(temp > 0) temp = (temp + 524288) >> 20;
  380.           else temp = -((524288 - temp) >> 20);
  381. #ifdef SYMMETRIC
  382.           temp2 = ralpha * *(w->olddw);
  383. #else
  384.           temp2 = ralpha * w->olddw;
  385. #endif
  386.           if (temp2 > 0) temp3 = temp + ((temp2 + 512) >> 10);
  387.           else temp3 = temp - ((512 - temp2) >> 10);
  388. #ifdef SYMMETRIC
  389.           *(w->olddw) = temp3;
  390. #else
  391.           w->olddw = temp3;
  392. #endif
  393.           /* w->weight = w->weight + w->olddw */
  394. #ifdef SYMMETRIC
  395.           temp3 = *(w->weight) + temp3;
  396.           *(w->weight) = temp3;
  397. #else
  398.           temp3 = w->weight + temp3;
  399.           w->weight = temp3;
  400.           if (bunit->layernumber > 1)
  401.              bunit->error = bunit->error + deltaj * temp3;
  402. #endif
  403.           w = w->next;
  404.         }
  405.       }
  406.      u = u->next;
  407.      t = t->next;
  408.    }
  409.  return(notclose);
  410. }
  411.  
  412. #ifndef SYMMETRIC
  413.  
  414. void cbackinner()           /* Same as cbackoutput, except errors are */
  415. {                           /* calculated differently */
  416.    register short deltaj;
  417.    register int etadeltaj;
  418.    register int temp;
  419.    register int temp2;
  420.    register short temp3;
  421.    register short reta;
  422.    register short ralpha;
  423.    register UNIT *bunit;
  424.    register WTNODE *w;
  425.    register UNIT *u;
  426.    LAYER *layer;
  427.  
  428.   if (update == 'C') reta = eta2; else reta = eta;
  429.   ralpha = alpha;
  430.   layer = last->backlayer;
  431.   while (layer->backlayer != NULL)
  432.    {
  433.     u = (UNIT *) layer->units;
  434.     while (u != NULL)
  435.      {
  436.       temp3 = u->oj;
  437.       if (deriv == 'f')  /* Fahlman's derivative */
  438.          temp = (((temp3 * ((short)(1024 - temp3)) + 512) >> 10) + 102)
  439.                  * u->error;
  440.       else  /* diff. step size and original derivative */
  441.          temp = ((temp3 * ((short)(1024 - temp3)) + 512) >> 10)
  442.                   * u->error;
  443.       if (temp > 0) deltaj = (temp + 524288) >> 20;
  444.       else deltaj = -((524288 - temp) >> 20);
  445.       etadeltaj = reta * deltaj;
  446.       w = (WTNODE *) u->wtlist;
  447.       while (w != NULL)
  448.        {
  449.         bunit = (UNIT *) w->backunit;
  450.         temp = etadeltaj * bunit->oj;
  451.         if (temp > 0) temp = (temp + 524288) >> 20;
  452.         else temp = -((524288 - temp) >> 20);
  453.         temp2 = ralpha * w->olddw;
  454.         if (temp2 > 0) temp3 = temp + ((temp2 + 512) >> 10);
  455.         else temp3 = temp - ((512 - temp2) >> 10);
  456.         w->olddw = temp3;
  457.         temp3 = w->weight + temp3;
  458.         w->weight = temp3;
  459.         if (bunit->layernumber > 1)
  460.            bunit->error = bunit->error + deltaj * temp3;
  461.         w = w->next;
  462.        };
  463.       u = u->next;
  464.      };
  465.     layer = layer->backlayer;
  466.    };
  467. }
  468.  
  469. #endif
  470.