/* =======================================================
	Neural Network Classes for the NeXT Computer
	Written by: Ralph Zazula
					University of Arizona - Fall 1991
					zazula@pri.com (NeXT Mail)
==========================================================*/
#import "Random.h"
#import "Neuron.h"
#import <stdio.h>

#define L 100		// number of nodes
#define N 5		// number of patterns
#define M 2			// test pattern

void main()
{
	id rand = [[Random alloc] init];
	id nodes = [[List alloc] init];
	
	double T = 2.0;							// initial temperature

	double patterns[N][L], temp, error;
	int	i,j,k;
	
	//
	// create the nodes
	//
	for(i=0; i<L; i++) {
		[nodes addObject:[[Neuron alloc] init]];
		[[nodes lastObject] setType:Sign];
	}
		
	//
	// make the connections
	//
	for(j=0; j<L; j++)
		for(i=0; i<L; i++)
			if(i!=j)
				[[nodes objectAt:j] connect:[nodes objectAt:i]];

	// set seed variables
	[rand setSeeds:5335:7777:32197];
	
	// generate patterns
	printf("generating patterns...\n");
	for(i=0; i<N; i++) 
		for(j=0; j<L; j++)
			patterns[i][j] = [rand percent] > 0.5 ? 1.0 : -1.0;
						
	// set initial temperature
	printf("setting initial temperature to: %f\n",T);
	for(i=0; i<L; i++)
		[[nodes objectAt:i] setTemp:T];

	// set weights
	printf("setting weights...\n");
	for(j=0; j<L; j++)
		for(k=0; k<L; k++) {
			temp=0.0;
			if (j!=k) {
				for(i=0; i<N; i++)
					temp += patterns[i][j]*patterns[i][k];
				[[nodes objectAt:j] setWeightFor:[nodes objectAt:k] to:temp];
			}
		}
		
	// apply trial input (one of the patterns with noise added)
	printf("applying input...\n");
	for(i=0; i<L; i++)
		[[nodes objectAt:i]
			setOutput:( [rand percent] > 0.6 ? -patterns[M][i] : patterns[M][i])];
		
	// step and report error
	for(i=0; i<1000; i++) {
		error = 0.0;
		for(j=0; j<L; j++)
			[[nodes objectAt:[rand randMax:(L-1)]] step];
		for(k=0; k<L; k++)
			error += ([[nodes objectAt:k] lastOutput] - patterns[M][k])*
				([[nodes objectAt:k] lastOutput] - patterns[M][k])/4;
		printf("[%u] error: %lf  temp: %lf\n",i,error,T);
		// decay the temperature
		if(i > 50)
			T = 0.99*T;
		for(j=0; j<L; j++)
			[[nodes objectAt:j] setTemp:T];
	}
		
		
	
}
