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

#include <stdio.h>
#include <math.h>
#include <sys/types.h>
#include <sys/file.h>
#include <sys/types.h>
#ifdef X
#include "X/box.h"
#endif
#include "defs.h"

update_net(teachp, learnflag)
	float  *teachp;
	int     learnflag;
{
	extern int nlayers;
	extern int array;
	extern int *layer_descp;
	extern float **layerp;
	extern float **weightp;
	extern float **dweightp;
	extern float **iweightp;
	extern float **deltap;
	extern float **biasp;
	extern float **dbiasp;
	extern float **ibiasp;
	extern float delta_z;
	extern int num_hidden;
	extern int context;
	float **lp;
	float **wp;
	float **dwp;
	float **iwp;
	float **dp;
	float **bp;
	float **dbp;
	float **ibp;
	int    *ldp;
	register int i;
	int     nl;

	if (array == 1) {
		delta2(teachp);
#define NOLEARN 1
		if (learnflag == NOLEARN)
			return;
		update_weight2();
	} else if (array == 0) {
		nl = nlayers - 1;
		/*
		 * do layers in reverse; output layer is done differently
		 */
		ldp = layer_descp + nl;
		lp = layerp + nl;
		wp = weightp + (nl - 1);
		dp = deltap + nl;
		delta_out(*lp, *ldp, teachp, *dp);
#define NOLEARN 1
		if (learnflag == NOLEARN)
			return;
		/*
		 * do the rest for nl-1 (==nlayers-2);  we only have
		 * (nlayers-1) connections to change, and we've already done
		 * top set
		 */
		for (i = 0; i < (nl - 1); i++) {
			delta(*ldp, *dp, *wp, *(lp - 1), *(ldp - 1), *(dp - 1));
			lp--;
			ldp--;
			dp--;
			wp--;
		}
		/*
		 * go back and update the weights and biases, given the deltas
		 * we just computed
		 */
		ldp = layer_descp + nl;
		lp = layerp + nl;
		wp = weightp + (nl - 1);
		dwp = dweightp + (nl - 1);
		iwp = iweightp + (nl - 1);
		dp = deltap + nl;
		bp = biasp + nl;
		dbp = dbiasp + nl;
		ibp = ibiasp + nl;
		for (i = 0; i < nl; i++) {
			update_weight(*ldp, *dp, *wp, *dwp, *iwp, *bp, *dbp, *ibp, *(lp - 1), *(ldp - 1));
			ldp--;
			dp--;
			wp--;
			dwp--;
			iwp--;
			bp--;
			dbp--;
			ibp--;
			lp--;
		}
	}
}
