home *** CD-ROM | disk | FTP | other *** search
- /* *********************************************************** */
- /* file int.c: Contains the network evaluation and weight */
- /* adjustment procedures for the integer versions */
- /* bp and sbp. */
- /* */
- /* Copyright (c) 1991 by Donald R. Tveter */
- /* */
- /* The code here has been optimized for use with the Motorola */
- /* MC 68010 processor and version 3.5 of the UNIX (tm) PC */
- /* C compiler where UNIX is a trademark of Bell Laboratories. */
- /* *********************************************************** */
-
- #include "ibp.h"
- #include <stdio.h>
-
- extern char activation, backprop, deriv, wtlimithit;
- extern WTTYPE alpha, D, decay, eta, eta2, etamax, kappa, noise;
- extern WTTYPE theta1, theta2, toler;
- extern LAYER *last, *start;
- extern INT32 totaldiff;
-
- void forward() /* computes unit activations */
- {
- register INT32 sum, x, intpart;
- register WTNODE *w;
- register UNIT *u, *predu;
- LAYER *layer;
- register short fract, val;
-
- layer = start->next;
- while (layer != NULL)
- {
- u = (UNIT *) layer->units;
- while (u != NULL)
- {
- sum = 0;
- w = (WTNODE *) u->wtlist;
- while (w != NULL)
- {
- predu = (UNIT *) w->backunit;
- #ifdef SMART
- # ifdef SYMMETRIC
- sum = sum + (INT32) *(w->weight) * predu->oj / 1024;
- # else
- sum = sum + (INT32) w->weight * predu->oj / 1024;
- # endif
- #else
- # ifdef SYMMETRIC
- x = (INT32) *(w->weight) * predu->oj;
- # else
- x = (INT32) w->weight * predu->oj;
- # endif
- if (x >= 0) sum = sum + (x >> 10); else sum = sum - ( (-x) >> 10);
- #endif
- w = w->next;
- };
- sum = (INT32) D * sum / 1024;
- if (activation == 'p' || activation == 't')
- {
- if (sum > 0) x = sum; else x = -sum;
- intpart = x >> 10;
- fract = x & 01777;
- switch (intpart) {
- case 0: val = 512 + (((INT32) 237 * fract) >> 10); /* 0 <= x < 1 */
- break;
- case 1: val = 748 + (((INT32) 153 * fract) >> 10); /* 1 <= x < 2 */
- break;
- case 2: val = 901 + (((INT32) 73 * fract) >> 10); /* 2 <= x < 3 */
- break;
- case 3:
- case 4: val = 976 + (((INT32) (x - 3072) * 20) >> 10); /* 3 <= x < 5 */
- break;
- default: val = 1024; /* x >= 5 */ };
- if (sum < 0) u->oj = 1024 - val; else u->oj = val;
- if (activation == 't') u->oj = (u->oj - 512) * 2;
- }
- else if (activation == 'l') u->oj = sum;
- u = u->next;
- };
- layer = layer->next;
- };
- }
-
- short backoutput() /* computes weight changes from the output layer */
- {
- register short deltaj, temp2, temp3;
- register INT32 temp;
- register UNIT *bunit, *u;
- register WTNODE *w;
- register short adiff, notclose;
-
- notclose = last->unitcount;
- u = (UNIT *) last->units;
- while (u != NULL)
- {
- temp3 = u->oj;
- temp2 = u->tj - temp3;
- if (temp2 > 0) adiff = temp2; else adiff = -temp2;
- if (adiff < toler) notclose = notclose - 1;
- totaldiff = totaldiff + adiff;
- if (adiff >= toler || backprop) /* then compute errors */
- {
- if (deriv == 'd') /* diff. step size method */
- deltaj = temp2;
- else if (deriv == 'f' || deriv == 'F') /* Fahlman's derivative */
- {
- if (activation == 't') temp3 = temp3 / 2 + 512;
- temp = (INT32) temp2 * ((INT32) 104448 + (INT32) temp3 * ((short)(1024 - temp3)));
- if (temp > 0) deltaj = (INT32) (temp + 524288) >> 20;
- else deltaj = -((INT32) (524288 - temp) >> 20);
- }
- else /* the derivative in the original formula */
- {
- if (activation == 't') temp3 = temp3 / 2 + 512;
- temp = (INT32) temp2 * ((INT32) temp3 * ((short)(1024 - temp3)));
- if (temp > 0) deltaj = (INT32) (temp + 524288) >> 20;
- else deltaj = -((INT32) (524288 - temp) >> 20);
- }
- w = (WTNODE *) u->wtlist;
- #ifdef SYMMETRIC
- while (w->next != NULL) /* skips threshold unit at end */
- #else
- while (w != NULL)
- #endif
- {
- bunit = (UNIT *) w->backunit;
- #ifdef SYMMETRIC
- *(w->total) = *(w->total) + (INT32) deltaj * bunit->oj;
- #else
- w->total = w->total + (INT32) deltaj * bunit->oj;
- if (bunit->layernumber > 1)
- bunit->error = bunit->error + (INT32) deltaj * w->weight;
- #endif
- w = w->next;
- }
- };
- u = u->next;
- };
- return(notclose);
- }
-
- #ifndef SYMMETRIC
-
- void backinner() /* Computes slopes and passes back */
- { /* errors from hidden layers. */
- register short deltaj, temp3;
- register INT32 temp;
- register UNIT *bunit, *u;
- register WTNODE *w;
- LAYER *layer;
-
- layer = last->backlayer;
- while (layer->backlayer != NULL)
- {
- u = (UNIT *) layer->units;
- while (u != NULL)
- {
- if (activation == 't') temp3 = u->oj / 2 + 512; else temp3 = u->oj;
- if (deriv == 'f') /* Fahlman's derivative */
- temp = (INT32) (((short)(((INT32) temp3*((short)(1024-temp3))+512) >> 10))
- + 102) * u->error;
- else /* either for the original or diff. step size */
- temp = (INT32) ((short)(((INT32) temp3*((short)(1024-temp3))+512) >> 10))
- * u->error;
- if (temp > 0) deltaj = (INT32) (temp + 524288) >> 20;
- else deltaj = -((INT32) (524288 - temp) >> 20);
- w = (WTNODE *) u->wtlist;
- while (w != NULL)
- {
- bunit = (UNIT *) w->backunit;
- w->total = w->total + (INT32) deltaj * bunit->oj;
- if (bunit->layernumber > 1)
- bunit->error = bunit->error + (INT32) deltaj * w->weight;
- w = w->next;
- };
- u = u->next;
- };
- layer = layer->backlayer;
- };
- }
-
- #endif
-
- #ifdef SYMMETRIC
- void dbd_update() {pg("symmetric dbd update no longer supported\n");}
- #else
- void dbd_update() /* the delta-bar-delta method for weight updates */
- {
- register short rkappa, temp2, dbarm1, rdecay;
- register INT32 temp;
- register UNIT *u;
- register WTNODE *w;
- LAYER *layer;
-
- /* w->olddw is used for delta-bar minus 1 */
-
- rkappa = kappa;
- rdecay = decay;
- layer = last;
- while (layer->backlayer != NULL)
- {
- u = (UNIT *) layer->units;
- while (u != NULL)
- {
- w = (WTNODE *) u->wtlist;
- while (w != NULL)
- {
- if (w->total > 0) temp2 = (INT32) (w->total + 512) >> 10;
- else temp2 = -((INT32) (512 - w->total) >> 10);
- dbarm1 = w->olddw;
- temp = (INT32) theta2 * temp2 + (INT32) theta1 * dbarm1;
- if (temp > 0) w->olddw = (INT32) (temp + 512) >> 10;
- else w->olddw = -((INT32) (512 - temp) >> 10);
- if (temp2 > 0 && dbarm1 > 0) w->eta = w->eta + rkappa;
- else if (temp2 < 0 && dbarm1 < 0) w->eta = w->eta + rkappa;
- else if (temp2 > 0 && dbarm1 < 0)w->eta = ((INT32) w->eta * rdecay) >> 10;
- else if (temp2 < 0 && dbarm1 > 0)w->eta = ((INT32) w->eta * rdecay) >> 10;
- if (w->eta > etamax) w->eta = etamax;
- temp = (INT32) temp2 * w->eta;
- if (temp > 0) temp2 = (INT32) (temp + 512) >> 10;
- else if (temp < 0) temp2 = -((INT32) (512 - temp) >> 10);
-
- else if (w->slope == 0)
- {if (w->total < 0) temp2 = noise; else temp2 = -noise;}
- w->slope = temp2;
-
- temp = (INT32) w->weight + temp2;
- if (temp > MAXSHORT)
- {
- wtlimithit = 1;
- w->weight = MAXSHORT;
- }
- else if (temp < MINSHORT)
- {
- wtlimithit = 1;
- w->weight = MINSHORT;
- }
- else w->weight = temp;
- w = w->next;
- };
- u = u->next;
- };
- layer = layer->backlayer;
- };
- }
- #endif
-
- void periodic_update() /* update weights for the original method */
- { /* and the differential step size algorithm */
- register short reta, ralpha;
- register INT32 temp;
- register short temp2;
- register UNIT *u;
- register WTNODE *w;
- LAYER *layer;
-
- ralpha = alpha;
- layer = last;
- while (layer->backlayer != NULL)
- {
- if (layer == last) reta = eta; else reta = eta2;
- u = (UNIT *) layer->units;
- while (u != NULL)
- {
- w = (WTNODE *) u->wtlist;
- while (w != NULL)
- {
- #ifdef SYMMETRIC
- if (((UNIT *) w->backunit)->unitnumber > u->unitnumber)
- {
- if (*(w->total) > 0) temp = (INT32) ((INT32)(*(w->total) + 512) >> 10) * reta
- + (INT32) ralpha * *(w->olddw);
- else temp = (INT32) -(((INT32) 512 - *(w->total)) >> 10) * reta
- + (INT32) ralpha * *(w->olddw);
- if (temp > 0) temp2 = (INT32) (temp + 512) >> 10;
- else temp2 = -(((INT32) 512 - temp) >> 10);
- *(w->olddw) = temp2;
- temp = (INT32) *(w->weight) + temp2;
- if (temp > MAXSHORT)
- {
- wtlimithit = 1;
- *(w->weight) = MAXSHORT;
- }
- else if (temp < MINSHORT)
- {
- wtlimithit = 1;
- *(w->weight) = MINSHORT;
- }
- else *(w->weight) = temp;
- };
- #else
- if (w->total > 0)
- temp = (INT32) (((INT32) w->total + 512) >> 10) * reta + (INT32) ralpha * w->olddw;
- else
- temp = (INT32) -(((INT32) 512 - w->total) >> 10) * reta + (INT32) ralpha * w->olddw;
- if (temp > 0) temp2 = (INT32) (temp + 512) >> 10;
- else temp2 = -(((INT32) 512 - temp) >> 10);
- w->olddw = temp2;
- temp = (INT32) w->weight + temp2;
- if (temp > MAXSHORT)
- {
- wtlimithit = 1;
- w->weight = MAXSHORT;
- }
- else if (temp < MINSHORT)
- {
- wtlimithit = 1;
- w->weight = MINSHORT;
- }
- else w->weight = temp;
- #endif
- w = w->next;
- };
- u = u->next;
- };
- layer = layer->backlayer;
- };
- }
-
-
- void qp_update() {pg("quickprop not yet finished\n");}
- void supersab() {pg("supersab not yet finished\n");}
-
- short cbackoutput() /* The continuous update version */
- { /* of back-propagation */
- register short deltaj;
- register INT32 etadeltaj, temp, temp2;
- register short temp3, adiff;
- register UNIT *bunit;
- register WTNODE *w;
- register UNIT *u;
- register short ralpha, reta, notclose;
-
- ralpha = alpha;
- reta = eta;
- notclose = last->unitcount;
- u = (UNIT *) last->units;
- while (u != NULL)
- {
- temp3 = u->oj;
- temp2 = u->tj - temp3;
- if (temp2 > 0) adiff = temp2; else adiff = -temp2;
- if (adiff < toler) notclose = notclose - 1;
- totaldiff = totaldiff + adiff;
- if (adiff >= toler || backprop)
- {
- if (deriv == 'd') /* the differential step size method */
- deltaj = temp2;
- else if (deriv == 'f' || deriv == 'F') /* Fahlman's derivative */
- { /* deltaj = (u->tj - u->oj) * [0.1 + u->oj*(1.0 - u->oj)] */
- if (activation == 't') temp3 = temp3 / 2 + 512;
- temp = (INT32) temp2 * ((INT32) 104448 + (INT32) temp3 * ((short)(1024 - temp3)));
- if(temp > 0) deltaj = (INT32) (temp + 524288) >> 20;
- else deltaj = -(((INT32) 524288 - temp) >> 20);
- }
- else /* the original derivative */
- { /* deltaj = (u->tj - u->oj) * u->oj * (1.0 - u->oj) */
- if (activation == 't') temp3 = temp3 / 2 + 512;
- temp = (INT32) temp2 * ((INT32) temp3 * ((short)(1024 - temp3)));
- if(temp > 0) deltaj = ((INT32) temp + 524288) >> 20;
- else deltaj = -(((INT32) 524288 - temp) >> 20);
- };
- etadeltaj = (INT32) deltaj * reta;
- w = (WTNODE *) u->wtlist;
- #ifdef SYMMETRIC
- while (w->next != NULL)
- #else
- while (w != NULL)
- #endif
- { /* get a slope for each weight */
- bunit = (UNIT *) w->backunit;
- temp = (INT32) etadeltaj * bunit->oj;
- if(temp > 0) temp = (INT32) (temp + 524288) >> 20;
- else temp = -(((INT32) 524288 - temp) >> 20);
- #ifdef SYMMETRIC
- temp2 = (INT32) ralpha * *(w->olddw);
- #else
- temp2 = (INT32) ralpha * w->olddw;
- #endif
- if (temp2 > 0) temp3 = temp + (((INT32) temp2 + 512) >> 10);
- else temp3 = temp - (((INT32) 512 - temp2) >> 10);
- #ifdef SYMMETRIC
- *(w->olddw) = temp3;
- #else
- w->olddw = temp3;
- #endif
- /* w->weight = w->weight + w->olddw */
- #ifdef SYMMETRIC
- temp = (INT32) *(w->weight) + temp3;
- if (temp > MAXSHORT)
- {
- wtlimithit = 1;
- *(w->weight) = MAXSHORT;
- }
- else if (temp < MINSHORT)
- {
- wtlimithit = 1;
- *(w->weight) = MINSHORT;
- }
- else *(w->weight) = temp;
- #else
- temp = (INT32) w->weight + temp3;
- if (temp > MAXSHORT)
- {
- wtlimithit = 1;
- temp3 = MAXSHORT;
- }
- else if (temp < MINSHORT)
- {
- wtlimithit = 1;
- temp3 = MINSHORT;
- }
- else temp3 = temp;
- w->weight = temp3;
- if (bunit->layernumber > 1)
- bunit->error = bunit->error + (INT32) deltaj * temp3;
- #endif
- w = w->next;
- }
- }
- u = u->next;
- }
- return(notclose);
- }
-
- #ifndef SYMMETRIC
-
- void cbackinner()
- {
- register short deltaj;
- register INT32 etadeltaj, temp, temp2;
- register short temp3, reta, ralpha;
- register UNIT *bunit;
- register WTNODE *w;
- register UNIT *u;
- LAYER *layer;
-
- reta = eta2;
- ralpha = alpha;
- layer = last->backlayer;
- while (layer->backlayer != NULL)
- {
- u = (UNIT *) layer->units;
- while (u != NULL)
- {
- if (activation == 't') temp3 = u->oj / 2 + 512;
- else temp3 = u->oj;
- if (deriv == 'f') /* Fahlman's derivative */
- temp = (INT32) ((((INT32) temp3 * ((short)(1024 - temp3)) + 512) >> 10) + 102)
- * u->error;
- else /* diff. step size and original derivative */
- temp = (((INT32) temp3 * ((short)(1024 - temp3)) + 512) >> 10)
- * u->error;
- if (temp > 0) deltaj = (INT32) (temp + 524288) >> 20;
- else deltaj = -(((INT32) 524288 - temp) >> 20);
- etadeltaj = (INT32) reta * deltaj;
- w = (WTNODE *) u->wtlist;
- while (w != NULL)
- {
- bunit = (UNIT *) w->backunit;
- temp = (INT32) etadeltaj * bunit->oj;
- if (temp > 0) temp = (INT32) (temp + 524288) >> 20;
- else temp = -(((INT32) 524288 - temp) >> 20);
- temp2 = (INT32) ralpha * w->olddw;
- if (temp2 > 0) temp3 = temp + ((INT32) (temp2 + 512) >> 10);
- else temp3 = temp - (((INT32) 512 - temp2) >> 10);
- w->olddw = temp3;
- temp = (INT32) w->weight + temp3;
- if (temp > MAXSHORT)
- {
- wtlimithit = 1;
- temp3 = MAXSHORT;
- }
- else if (temp < MINSHORT)
- {
- wtlimithit = 1;
- temp3 = MINSHORT;
- }
- else temp3 = temp;
- w->weight = temp3;
- if (bunit->layernumber > 1)
- bunit->error = bunit->error + (INT32) deltaj * temp3;
- w = w->next;
- };
- u = u->next;
- };
- layer = layer->backlayer;
- };
- }
- #endif
-