
/*
 * 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 "defs.h"
#include <ctype.h>

extern	int nlayers;

saveweights1(fileroot)
	char	*fileroot;
{
	FILE	*fopen();
	FILE	*fp;
	int	i;
	int	j;
	int	k;

	extern	float olderr;
	extern	int *layer_descp;
	extern	float **weightp;
	extern	float **biasp;
	extern	long run;
	float	**wp;
	float	**bp;
	int	*ldp;
	int	*bldp;
	int	*tldp;
	char	filename[128];

#ifdef ibmpc
	sprintf(filename, "%ld.%.3s", run, fileroot);
#else
	sprintf(filename, "%s.%ld.wts", fileroot, run);
#endif
	if ((fp=fopen(filename, "w+")) == NULL) {
		perror(filename);
		exit(1);
	}
	fprintf(fp, "NETWORK CONFIGURED BY RULE\n");
	fprintf(fp, "# weights after %ld (fit = %f) runs\n", run,olderr);
	fprintf(fp, "# WEIGHTS\n");
	for (i=1, bldp=(layer_descp), tldp=(layer_descp+1), wp=weightp; i < nlayers; i++, bldp++, tldp++, wp++) {
		float *w;
		fprintf(fp, "# from layer %d\n", i-1);
		for (j=0, w = *wp; j < *bldp; j++) {
			for (k=0; k < *tldp; k++) {
				fprintf(fp, "%f\n", *(w + j + (k * *bldp)));
			}
		}
	}
	fprintf(fp, "# BIASES\n");
	for (i=0, ldp = layer_descp, bp=biasp; i<nlayers; i++, ldp++, bp++) {
		float *b;
		fprintf(fp, "# from layer %d\n", i);
		for (j=0, b = *bp; j < *ldp; j++) {
			fprintf(fp, "%f\n", *b);
			b++;
		}
	}
	fflush(fp);
	fclose(fp);
}


loadweights1(loadfile)
	char	*loadfile;
{
	extern	int *layer_descp;
	extern	float **weightp;
	extern	float **biasp;
	extern	long run;
	extern	long sweeps;
	FILE	*fopen();
	FILE	*fp;
	register int i;
	register int j;
	register int k;
	float	**wp;
	float	**bp;
	int	*ldp;
	int	*bldp;
	int	*tldp;
	char	rule[10];
	char	junk[100];
	int	nread;

	if ((fp=fopen(loadfile, "r")) == NULL) {
		perror(loadfile);
		exit(1);
	}
	if (fscanf(fp, "NETWORK CONFIGURED BY %s\n", rule) != 1)
		inputerr(loadfile, "wt file header missing");
	if (strcmp(rule, "RULE") != 0) {
		fprintf(stdout, "Saved weights not for rule-configured network\n");
		exit(1);
	}
	/*
	fscanf(fp, "# weights after %ld runs\n", &run);
	*/
	fscanf(fp, "# weights after %ld %[^r]runs\n", &run, junk);
	fscanf(fp, "# WEIGHTS\n");
	sweeps += run;
	/*
	 * new way
	 */
	for (i=1, bldp=(layer_descp), tldp=(layer_descp+1), wp=weightp;
	    i < nlayers; i++, bldp++, tldp++, wp++) {
		float *w;
		if (fscanf(fp, "# from layer %*d\n") == EOF)
			inputerr(loadfile, "premature EOF");
		nread = 0;
		for (j=0, w = *wp; j < *bldp; j++) {
			for (k=0; k < *tldp; k++) {
				nread += fscanf(fp, "%f\n",
					(w + j + (k * *bldp)));
			}
		}
		if (nread != *bldp * *tldp)
			inputerr(loadfile, "weight data");
	}
	if (fscanf(fp, "# BIASES\n") == EOF)
		inputerr(loadfile, "missing biases");
	for (i=0, ldp = layer_descp, bp=biasp; i<nlayers; i++, ldp++, bp++) {
		float *b;
		if (fscanf(fp, "# from layer %*d\n") == EOF)
			inputerr(loadfile, "premature EOF");
		nread = 0;
		for (j=0, b = *bp; j < *ldp; j++) {
			nread += fscanf(fp, "%f\n", b);
			b++;
		}
		if (nread != *ldp)
			inputerr(loadfile, "bias data");
	}
	fclose(fp);
}

#ifdef notdef
int
getfloat(fp, dst)
	register FILE *fp;
	float	*dst;
{
	extern	float atof();
	register int c;
	register char *bp;
	char	buf[32];

	bp = buf;
	while ((c = getc(fp)) != EOF && isspace(c))
		;
	if (feof(fp))
		return 0;
	do {
		if (!isdigit(c) && c != '.' && c != '-') {
			ungetc(c, fp);
			break;
		}
		*bp++ = c;
	} while ((c = getc(fp)) != EOF);
	*bp = 0;
	if (*buf == 0)
		return 0;
	*dst = atof(buf);
	return 1;
}
#endif
