/*
 * 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"

extern float **d_tokenp;
extern long    run;
extern long    sweeps;
extern int     sequential;
extern int     cur_token;
extern int     updatenow;
extern int     ndtokens;
extern int     continuous;
extern int     context;
extern int     nolearn;
extern int     errsig;
extern int     insize;
extern int     advance;
extern float **t_tokenp;
extern long    check;
extern int     array;
extern char    fileroot[128];

/*
 * main loop iteration; fast mode.
 *
 */
run_fast()
{
	extern int *layer_descp;
	extern float **layerp;
	register float *dtp;
	register float *ttp;

	dtp = *d_tokenp;
	ttp = *t_tokenp;
	for (; run < sweeps; run++) {
		/*
		 * randomly choose a token; activate network; adjust
		 * weights according to error
		 */
		if (sequential == 0) {
			cur_token = ransi();
		} else {
			cur_token++;
			updatenow = 0;
			if (cur_token == ndtokens){
				cur_token = 0;
				updatenow = 1;
			}
		}
		/*
		 * for the 1st layer substitute the data; then
		 * activate all the layers
		 */
		if (continuous == 1) {
			*layerp = dtp;
		} else
			*layerp = *(d_tokenp + cur_token);
		/*
		 * if our hidden units are to be used as context
		 * units, save them and concatenate with the real
		 * input.
		 */
		if (context > 0) {
			buildin(context);
		}
		/*
		 * activate the network
		 */
		activate_net();
		/*
		 * pass along which token so we can do correct
		 * teaching, calculate error and back-propogate; if
		 * checkpointing, save weights. If nolearn is set we
		 * will skip the update_net, unless we need to collect
		 * the error signal, in which case we'll pass nolearn
		 * to update_net() and let it caclulate error & return
		 * before changing anything.  (Note, nolearn==0 means
		 * we DO learning!)
		 */
		if ((nolearn == 0) || (errsig == 1)) {
			if (continuous == 1)
				update_net(ttp, nolearn);
			else
				update_net(*(t_tokenp + cur_token), nolearn);
		}
		/*
		 * if continuous mode, need to advance the sliding
		 * window a little
		 */
		if (continuous == 1) {
			if (dtp < *(d_tokenp) + insize - *layer_descp) {
				ttp += advance;
				dtp += advance;
			} else {
				dtp = *d_tokenp;
				ttp = *t_tokenp;
			}
		}
		/*
		 * if checkpointing, save weights
		 */
		if (check && ((run % check) == 0)) {
			if (array == 0)
				saveweights1(fileroot);
			else if (array == 1)
				saveweights2(fileroot);
		}
	}
}
