
/*
 * Copyright (1987) Jeff Elman.  University of California, San Diego
 * This software may be redistributed without charge; this notice
 * should be preserved.
 */

/*
 * activate.c
 *
 */

#include <stdio.h>
#include <math.h>
#include <sys/file.h>
#include <sys/types.h>
#include "defs.h"

extern	float *exp_array;
extern	float exp_mult;
extern	long exp_add;
extern	double exp_table();

/*
 * activate1.c
 *
 * allow elements in one layer to activate another.
 */
activate1(b_actp, b_size, t_actp, t_size, t_weightp, t_biasp, noise, linflag)
	float	*b_actp;
	int	b_size;
	float	*t_actp;
	int	t_size;
	register float *t_weightp;
	float	*t_biasp;
	float	noise;
	int	linflag;
{
	extern	long random();
	/*extern	float makenoise();*/
	extern	int debug;
	extern	int nobias;
	extern  int bipolar;
	extern	int numin;
	extern	int numtotal;
	extern	int numout;
	register float *bap;
	register float *endp;
	register float net;
	register int t;
	register float tn;

	/*
	 * Activate Propagation Up Network
	 */
	for (t = 0; t < t_size; t++) {
		if (debug==99) {
			fprintf(stdout, "node %d receives:\n", t);
		}
		net = 0.0;
		endp = b_actp + b_size;
		bap = b_actp;
		while (bap < endp) {
			if (debug==99) {
				fprintf(stdout, "%f*%f\t", *bap,*t_weightp);
			}
			/*
			 * inline expansion of "makenoise"
			 */
			if (noise != 0) {
				tn = noise-(2*noise*(random() / 2147483647.0));
				net += *t_weightp * (*bap + (*bap * tn));
			} else {
				net += *t_weightp * *bap;
			}
			t_weightp++;
		      	bap++;
		    /* 
		     * USE NO NOISE TO SPEED THINGS UP
		     *	net += *t_weightp++ * *bap++;
		     */
		}
		if (debug==99) fprintf(stdout, "NET: %f\n", net);
		/*
		 * if nobias is 0, we do use biases
		 */
		if (nobias==0)
			net += *t_biasp;
		if (linflag == NONLINEAR) {
			if (net < -10.0)
				net = -10.0;
			else if (net > 10.0)
				net = 10.0;
			*t_actp = 1.0 / (1.0 + EXP(-net));
			if (bipolar)
				*t_actp = 2.0 * *t_actp - 1.0;
		}  else if (linflag == LINEAR) {
			*t_actp = net;
		}
		if (debug==99) fprintf(stdout, "new node %d: %f\n", t, *t_actp);
		t_actp++;
		t_biasp++;
	}
}

#ifdef notdef
/*
 * squash.c
 *
 * return activation, given input
 */
float 
squash(m)
	float  m;
{
	float	x;
	float	p;
	p = (float) EXP(-m);
	x = 1.0 / (1.0 + p);
	return (x);
}

/*
 * return a float which randomly varies between +/- n
 */
float
makenoise(n)
	double	n;
{
	extern long random();
	static	double max = 2147483647;

	return (n - (2*n*(random() / max)));
}
#endif
