[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference abbott::neural-networks

Title:The New Neural Networks Conference
Moderator:LGP30::FLEISCHER
Created:Fri May 25 1990
Last Modified:Sun May 04 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:82
Total number of notes:276

82.0. "Source code for Windows 95 Application, Neural networks for image recognition" by SUBSYS::POIRIER () Sun May 04 1997 18:36

This program only runs on Windows95 do to some of the keyboard interrupts
I am monitoring.  To compile I used Microsoft Visual C++ v 4.1.
You need to include the video for Windows libraries in order to compile.
These are available from the MSDN site.
The header file follows this..
If anybody wants just the executable, E-Mail me at [email protected]
Questions or comments, I will gladly answer..

-Jamey




   /* 1/28/97 JP Neural Net
   Feedforward multilayer representation of a Neural Network which
   uses supervised learning through back propagation.
   Uses three layers, input - hidden - output.
   The activation of a node is computed by:
   1.  For each incoming connection compute activion*weight.
   2.  Sum up all the values of step 1 to get total input.
   3.  Perform sigmoid function 1/1+exp(-x) on total input.
   Training is done by repeatedly running a training set, taking the
   resulting error function of the output nodes and adjusting the weights
   backward through the net to get as close to the desired output as
   possible. */

#include "ICU.H"

//Global variables
NET Net; //The network 
double ITERATIONS; //Count number of epochs needed to train net.
/* FLAGWIN is a global window which when opened must be acknowledged
(closed) by the user before it will allow you to continue. */
HWND FLAGWIN;
char INPUTSTRING[10]; //Temp String to store user keyboard input as needed.
/* INIT flag which is set to true once a network has been set up
in memory and initialized. */
BOOLEAN NET_INIT=FALSE; 
long NUM_INPUT; //Size of Input layer, how many nodes
long NUM_OUTPUT; 
long NUM_HIDDEN;
long INPUT_SET; //Number of training sets..
double ACCEPTABLE_ERROR=0.00009; 
float **DESIRED_OUTPUT; //[SET][DESIRED_NETWORK_ACTIVATION]

BOOLEAN AllocSpace()
/* Allocates space within the heap for the neural net and
associated weights.  By using pointers can allow the
user to change the size of the network dynamically. 
Returns true if network is set up correctly. 
!!! WARNING: I am not checking all these calls to malloc !!! */
{
	long i;
	int set;

	Net.input=(Unit **)malloc(sizeof(Unit *)*INPUT_SET);		
	Net.hidden=(Unit *)malloc(sizeof(Unit)*NUM_HIDDEN);
	Net.output=(Unit *)malloc(sizeof(Unit)*NUM_OUTPUT);
	Net.error=(double *)malloc(sizeof(double)*INPUT_SET);
	Net.i2h=(double **)malloc(sizeof(double *)*NUM_INPUT);
	Net.h2o=(double **)malloc(sizeof(double *)*NUM_HIDDEN);
	DESIRED_OUTPUT=(float **)malloc(sizeof(float *)*INPUT_SET);

	for (i=0; i<INPUT_SET; i++)
	{
		Net.input[i]=(Unit *)malloc(sizeof(Unit)*NUM_INPUT);
		DESIRED_OUTPUT[i]=(float *)malloc(sizeof(float)*NUM_OUTPUT);
	}
	for (i=0; i<NUM_INPUT; i++)
	{
		Net.i2h[i]=(double *)malloc(sizeof(double)*NUM_HIDDEN);
		if (Net.i2h[i]==NULL)
		{
			MessageBox(NULL,"Insufficient Memory","Allocate
Memory",MB_ICONSTOP);
			FreeSpace();
			PostQuitMessage(0); //Exit Program			
		}
	}
	for (i=0; i<NUM_HIDDEN; i++)
	{
		Net.h2o[i]=(double *)malloc(sizeof(double)*NUM_OUTPUT);
		if (Net.h2o[i]==NULL)
		{
			MessageBox(NULL,"Insufficient Memory","Allocate
Memory",MB_ICONSTOP);
			FreeSpace();
			PostQuitMessage(0); //Exit Program
		}
	}
	//Clear Input layer and set all desired outputs to zero initially.
	for (set=0; set<INPUT_SET; set++)
	{
		for (i=0; i<NUM_INPUT; i++)
			Net.input[set][i].activation=(float)0;
		for (i=0; i<NUM_OUTPUT; i++)
			DESIRED_OUTPUT[set][i]=(float)0;
	}
	//Clear Hidden Layer
	for (i=0; i<NUM_HIDDEN; i++)
		Net.hidden[i].activation=0;
	//Finally, Clear Output Layer
	for (i=0; i<NUM_OUTPUT; i++)
		Net.output[i].activation=0;
	return TRUE;
} //End of Alloc Space

void FreeSpace()
/* Frees up heap memory being used for the network.  Note
that if it ran out of memory while trying to allocate space
then the first NULL parameter we hit should be as far as we need
to go since every other memory request after that point is also
NULL. */
{
	long i;

	if (Net.hidden==NULL)
		return;
	else
		free(Net.hidden);
	if (Net.output==NULL)
		return;
	else
		free(Net.output);
	if (Net.error==NULL)
		return;
	else
		free(Net.error);

	for (i=0; i<INPUT_SET; i++)
	{
		if (Net.input[i]==NULL)
			return;
		else
			free(Net.input[i]);
		if (DESIRED_OUTPUT[i]==NULL)
			return;
		else
			free(DESIRED_OUTPUT[i]);
	}
	if (Net.input==NULL)
		return;
	else
		free(Net.input);
	if (DESIRED_OUTPUT==NULL)
		return;
	else
		free(DESIRED_OUTPUT);

	for (i=0; i<NUM_INPUT; i++)
		if (Net.i2h[i]==NULL)
			return;
		else
			free(Net.i2h[i]);
	if (Net.i2h==NULL)
		return;
	else
		free(Net.i2h);

	for (i=0; i<NUM_HIDDEN; i++)
		if (Net.h2o[i]==NULL)
			return;
		else
			free(Net.h2o[i]);
	if (Net.h2o==NULL)
		return;
	else
		free(Net.h2o);
	//Reset env params
	NET_INIT=FALSE;
	NUM_INPUT=0;
	NUM_HIDDEN=0;
	NUM_OUTPUT=0;
	ACCEPTABLE_ERROR=0;
	INPUT_SET=0;
} //End of FreeSpace

void SavNet(HWND hwnd)
/* This function will save a network's connection weights
in a file.  These can be loaded later and you don't have
to re-train the network. */
{
	FILE *file;
	char filename[80]="";
	OPENFILENAME ofn; // common dialog box structure
	int i,j;

	if (!NET_INIT)
	{
		MessageBox(hwnd,"Network Not Initialized!","Save Network",
			MB_ICONHAND);
		return;
	}

	//First get filename		
	// Initialize OPENFILENAME
	ofn.lStructSize = sizeof(OPENFILENAME);
	ofn.hInstance=NULL;
	ofn.hwndOwner = hwnd;
	ofn.lpstrFile = filename;
	ofn.nMaxFile = sizeof(filename);
	ofn.lpstrFilter = "All\0*.*\0Neural Network\0*.NET\0";
	ofn.lpstrCustomFilter=NULL;
	ofn.nFilterIndex = 2;
	ofn.lpstrFileTitle = NULL;
	ofn.nMaxFileTitle = 0;
	
	ofn.lpstrInitialDir = NULL;
	ofn.lpstrTitle="Save Neural Network";
	ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
		

	// Display the Open dialog box. 
	if (GetSaveFileName(&ofn)!=TRUE)
	{
		MessageBox(hwnd,"Invalid Filename.","Save Network",MB_ICONWARNING);
		return;
	}

	//Open file with write privs
	if ((file=fopen(filename,"w"))==NULL)
	{
		MessageBox(hwnd,"Error: Unable to open file for write!","Save
Network",MB_ICONWARNING);
		return;
	}

	//Write Environment to file
	fprintf(file,"%d\n",NUM_INPUT);
	fprintf(file,"%d\n",NUM_HIDDEN);
	fprintf(file,"%d\n",NUM_OUTPUT);
	fprintf(file,"%d\n",INPUT_SET);
	fprintf(file,"%f\n",ACCEPTABLE_ERROR);
	fprintf(file,"\n\n"); //Two Seperator lines in file
	//Write weights to file..
	for (i=0; i<NUM_INPUT; i++)
		for (j=0; j<NUM_HIDDEN; j++)
			fprintf(file,"%f\n",Net.i2h[i][j]);
	fprintf(file,"\n\n"); //Two seperator lines in file..
	for (i=0; i<NUM_HIDDEN; i++)
		for (j=0; j<NUM_OUTPUT; j++)
			fprintf(file,"%f\n",Net.h2o[i][j]);
	if (fclose(file))
	{
		MessageBox(hwnd,"Unable to close file!","Save
Network",MB_ICONWARNING);
		return;
	}
	MessageBox(hwnd,"Network successfully saved.","Save Network",MB_OK);
	return;
} //End of SavNet

void ViewParams(HWND parent)
/* Allows the user to view the current environment
parameter settings. */
{
	HWND child;
	HDC hdc;
	char temp[100],tempb[50];
	char number[20];

	//Check to make certain network has been initialized
	if (!NET_INIT)
	{
		MessageBox(parent,"Network has not been initialized!",
			"View Environment Parameters",MB_ICONSTOP);
		return;
	}
		
	child=CreateWindow(
			"ChildClass", //name of Window Class
			"Current Environment Parameters", //You supply the title
			WS_DLGFRAME, //window_style dialog box
			CW_USEDEFAULT, //X coordinate - let Windows decide
			CW_USEDEFAULT, //Y coordinate - let Windows decide
			300, //Width
			200, //Height 
			parent, //Handle to Parent window
			NULL, //No menu
			NULL, //handle of this instance of the program
			NULL, //No additional arguments
			);
	//display the window
	ShowWindow(child,1);
	//display env params
	hdc=GetDC(child);
	//INPUT NODES
	strcpy(temp,"NUM_INPUT nodes: ");
	ltoa(NUM_INPUT,number,10); strcat(temp,number);
	TextOut(hdc,1,1,temp,strlen(temp));
	//HIDDEN NODES
	strcpy(temp,"NUM_HIDDEN nodes: ");
	ltoa(NUM_HIDDEN,number,10); strcat(temp,number);
	TextOut(hdc,1,20,temp,strlen(temp));
	//OUTPUT NODES
	strcpy(temp,"NUM_OUTPUT nodes: ");
	ltoa(NUM_OUTPUT,number,10); strcat(temp,number);
	TextOut(hdc,1,40,temp,strlen(temp));
	//INPUT SET
	strcpy(temp,"Number of input sets: ");
	ltoa(INPUT_SET,number,10); strcat(temp,number);
	TextOut(hdc,1,60,temp,strlen(temp));
	//ACCEPTABLE ERROR
	ConvertFloat(tempb,ACCEPTABLE_ERROR,8);
	strcpy(temp,"Acceptable Error: "); strcat(temp,tempb);
	TextOut(hdc,1,80,temp,strlen(temp));
	ReleaseDC(hdc,child);	
}
				
void LoadNet(HWND hwnd)
/* Loads a network from a previously saved file.  All we
are concerned with here are the weights i2h and h2o. */
{
	FILE *file;
	char filename[80]="";
	OPENFILENAME ofn; // common dialog box structure
	char line[100];
	int i,j;

	//First get filename		
	// Initialize OPENFILENAME
	ofn.lStructSize = sizeof(OPENFILENAME);
	ofn.hInstance=NULL;
	ofn.hwndOwner = hwnd;
	ofn.lpstrFile = filename;
	ofn.nMaxFile = sizeof(filename);
	ofn.lpstrFilter = "All\0*.*\0Neural Network\0*.NET\0";
	ofn.lpstrCustomFilter=NULL;
	ofn.nFilterIndex = 2;
	ofn.lpstrFileTitle = NULL;
	ofn.nMaxFileTitle = 0;
	
	ofn.lpstrInitialDir = NULL;
	ofn.lpstrTitle="Open Neural Network";
	ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
		

	// Display the Open dialog box. 
	if (GetOpenFileName(&ofn)!=TRUE)
	{
		MessageBox(hwnd,"Invalid Filename.","Load Neural Net",MB_ICONWARNING);
		return;
	}

	//Open file with read privs
	if ((file=fopen(filename,"r"))==NULL)
	{
		MessageBox(hwnd,"Unable to open for read.","Load Neural
Net",MB_ICONWARNING);
		return;
	}

	//If Network has been initialized clear it..
	if (NET_INIT)
		FreeSpace();

	//Get Environment data from file
	fgets(line,100,file); NUM_INPUT=atol(line);
	fgets(line,100,file); NUM_HIDDEN=atol(line);
	fgets(line,100,file); NUM_OUTPUT=atol(line);
	fgets(line,100,file); INPUT_SET=atol(line);
	fgets(line,100,file); ACCEPTABLE_ERROR=atof(line);

	NET_INIT=AllocSpace();
	if (!NET_INIT)
	{
		MessageBox(hwnd,"Network parameters incorrectly defined in input
file!",
			"Load Network",MB_ICONSTOP);
		fclose(file);
		return;
	}

	//Skip two lines
	fgets(line,100,file); 
	fgets(line,100,file); 
	//Load input to hidden..
	for (i=0; i<NUM_INPUT; i++)
		for (j=0; j<NUM_HIDDEN; j++)
		{
			if(feof(file))
			{
				MessageBox(hwnd,"Not enough input data for input to
hidden weights!","Load Neural Net",MB_ICONWARNING);
				return;
			}	
			fgets(line,100,file);
			Net.i2h[i][j]=atof(line);
		}
	//Expect two blank lines between data sets..
	fgets(line,100,file); 
	fgets(line,100,file);
	//Ok now load hidden to output..
	for (i=0; i<NUM_HIDDEN; i++)
		for (j=0; j<NUM_OUTPUT; j++)
		{
			if(feof(file))
			{
				MessageBox(hwnd,"Not enough input data for hidden to
output weights!","Load Neural Net",MB_ICONWARNING);
				fclose(file);
				return;
			}	
			fgets(line,100,file);
			Net.h2o[i][j]=atof(line);
		}
	fclose(file);
	strcpy(line,"Loaded "); strcat(line,filename);
	strcat(line," Successfully.");
	MessageBox(hwnd,line,"Load Neural Net",MB_OK);
	return;
} //End of LoadNet

void LoadDSRD(HWND hwnd)
/* Loads desired activations for the output nodes from a file.
This is easier than setting them all manually when you have a lot
of input sets. */
{
	FILE *file;
	int count,set;
	char filename[80];
	char line[100];
	OPENFILENAME ofn; // common dialog box structure

	if (!NET_INIT)
	{
		MessageBox(hwnd,"Network Not Initialized!","Load Desired Activations",
			MB_ICONHAND);
		return;
	}

	//First get filename		
	// Initialize OPENFILENAME
	ofn.lStructSize = sizeof(OPENFILENAME);
	ofn.hInstance=NULL;
	ofn.hwndOwner = hwnd;
	ofn.lpstrFile = filename;
	ofn.nMaxFile = sizeof(filename);
	ofn.lpstrFilter = "All\0*.*\0Desired Data\0*.DAT\0";
	ofn.lpstrCustomFilter=NULL;
	ofn.nFilterIndex = 2;
	ofn.lpstrFileTitle = NULL;
	ofn.nMaxFileTitle = 0;
	
	ofn.lpstrInitialDir = NULL;
	ofn.lpstrTitle="Open Desired Activation File";
	ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
		

	// Display the Open dialog box. 
	if (GetOpenFileName(&ofn)!=TRUE)
	{
		MessageBox(hwnd,"Invalid Filename.","Load Desired
Activations",MB_ICONWARNING);
		return;
	}

	/* Starts filling at input set 0 and continues until
	it has no more data. */

	//Open the file, read only
	if ((file=fopen(filename,"r"))==NULL)
	{
		MessageBox(hwnd,"Unable to open file for read!","Load Desired
Activations",MB_ICONHAND);
		return;
	}

	set=0;
	do
	{		
		for (count=0; count<NUM_OUTPUT; count++)
		{
			if(feof(file))
			{
				MessageBox(hwnd,"End of Data Reached","Load Desired
Activations",MB_OK);
				fclose(file);
				return;
			}
			strcpy(line,"0.000000");
			fgets(line,100,file);
			DESIRED_OUTPUT[set][count]=(float)atof(line);
		}
		set++;
	} while (set<INPUT_SET);

	fclose(file);
	strcpy(line,"Data loaded from: ");
	strcat(line,filename);
	MessageBox(hwnd,line,"Load Desired Activations",MB_OK);
	return;
} //End of LoadDSRD

void NetInit(HWND hwnd)
/* Clears all the activation states of the units
and assigns random values from 0-1 for the connection
weights. */
{
	int i,j;
	MSG msg;
	double NegPos; 

	/* If network has already been initialized then
	free up memory before re-initializing.  Size may change.. */
	if (NET_INIT)
		FreeSpace();

	//Get Number of Input Nodes
	ZeroMemory(INPUTSTRING,strlen(INPUTSTRING)); //Reset Input String
	UserInput("Number of Input Nodes: ",300,100,hwnd);
	while (FLAGWIN!=NULL) 
	{
		GetMessage(&msg,NULL,0,0);
		TranslateMessage(&msg);
		DispatchMessage(&msg); //return control to Windows
	} 
	NUM_INPUT=atol(INPUTSTRING);
	if (NUM_INPUT<1 | NUM_INPUT>19200)
	{
		MessageBox(hwnd,"Invalid number of input units!","Initialize
Network",MB_ICONHAND);
		NET_INIT=FALSE;
		return;
	}
	//Get Number of Hidden Nodes
	ZeroMemory(INPUTSTRING,strlen(INPUTSTRING)); //Reset Input String
	UserInput("Number of Hidden Nodes: ",300,100,hwnd);
	while (FLAGWIN!=NULL) 
	{
		GetMessage(&msg,NULL,0,0);
		TranslateMessage(&msg);
		DispatchMessage(&msg); //return control to Windows
	} 
	NUM_HIDDEN=atol(INPUTSTRING);
	if (NUM_HIDDEN<1)
	{
		MessageBox(hwnd,"Invalid number of hidden units!","Initialize
Network",MB_ICONHAND);
		NET_INIT=FALSE;
		return;
	}
	//Get Number of Output Nodes
	ZeroMemory(INPUTSTRING,strlen(INPUTSTRING)); //Reset Input String
	UserInput("Number of Output Nodes: ",300,100,hwnd);
	while (FLAGWIN!=NULL) 
	{
		GetMessage(&msg,NULL,0,0);
		TranslateMessage(&msg);
		DispatchMessage(&msg); //return control to Windows
	} 
	NUM_OUTPUT=atol(INPUTSTRING);
	if (NUM_OUTPUT<1)
	{
		MessageBox(hwnd,"Invalid number of output units!","Initialize
Network",MB_ICONHAND);
		NET_INIT=FALSE;
		return;
	}
	//Get Number of Input sets
	ZeroMemory(INPUTSTRING,strlen(INPUTSTRING)); //Reset Input String
	UserInput("Number of Input Sets: ",300,100,hwnd);
	while (FLAGWIN!=NULL) 
	{
		GetMessage(&msg,NULL,0,0);
		TranslateMessage(&msg);
		DispatchMessage(&msg); //return control to Windows
	} 
	INPUT_SET=atol(INPUTSTRING);
	if (INPUT_SET<1)
	{
		MessageBox(hwnd,"Invalid number of input sets!","Initialize
Network",MB_ICONHAND);
		NET_INIT=FALSE;
		return;
	}
	//Get Acceptable error level
	ZeroMemory(INPUTSTRING,strlen(INPUTSTRING)); //Reset Input String
	UserInput("Acceptable Error Level: ",300,100,hwnd);
	while (FLAGWIN!=NULL) 
	{
		GetMessage(&msg,NULL,0,0);
		TranslateMessage(&msg);
		DispatchMessage(&msg); //return control to Windows
	} 
	ACCEPTABLE_ERROR=atof(INPUTSTRING);
	if (INPUT_SET<0)
	{
		MessageBox(hwnd,"Invalid error level!","Initialize
Network",MB_ICONHAND);
		NET_INIT=FALSE;
		return;
	}

	//Allocate space for network
	if (!(NET_INIT=AllocSpace()))
	{
		MessageBox(hwnd,"Unable to allocate space for network!","Initialize
Network",
			MB_ICONHAND);
		return;
	}

	srand( (unsigned)time( NULL ) ); //Seed off timer

	//Assign Random weights for input to hidden connections
	for (i=0; i<NUM_INPUT; i++)		
		for (j=0; j<NUM_HIDDEN; j++)
		{
			NegPos=RANDOM;
			if (NegPos<0.5)
				Net.i2h[i][j]=RANDOM*-1;  //random 0 to -1
			else
				Net.i2h[i][j]=RANDOM; //random 0 to 1
		}
			
	//Clear Hidden Layer
	for (i=0; i<NUM_HIDDEN; i++)
	{
		Net.hidden[i].activation=0;
		//Assign Random weights for hidden to output connections	
		for (j=0; j<NUM_OUTPUT; j++)
		{
			NegPos=RANDOM;
			if (NegPos<0.5)
				Net.h2o[i][j]=RANDOM*-1; 			
			else
				Net.h2o[i][j]=RANDOM;
		}
	}
	return;
} //end NetInit


void ViewInputActivations(HWND parent)
{
	HWND win;
	if (!NET_INIT)
	{
		MessageBox(parent,"Network not initialized!","View Input Activations",
			MB_ICONSTOP);
		return;
	}
	win=CreateWindow("InputClass","Input Layer Activations",WS_VSCROLL, 
		CW_USEDEFAULT,CW_USEDEFAULT,400,200,parent,NULL,NULL,NULL);
	ShowWindow(win,1);
}

void ViewHiddenActivations(HWND parent)
{
	HWND win;
	if (!NET_INIT)
	{
		MessageBox(parent,"Network not initialized!","View Hidden
Activations",
			MB_ICONSTOP);
		return;
	}
	win=CreateWindow("HiddenClass","Hidden Layer Activations",WS_VSCROLL, 
		CW_USEDEFAULT,CW_USEDEFAULT,400,200,parent,NULL,NULL,NULL);
	ShowWindow(win,1);
}

void ViewOutputActivations(HWND parent)
{
	HWND win;
	if (!NET_INIT)
	{
		MessageBox(parent,"Network not initialized!","View Output
Activations",
			MB_ICONSTOP);
		return;
	}
	win=CreateWindow("OutputClass","Output Layer Activations",WS_VSCROLL, 
		CW_USEDEFAULT,CW_USEDEFAULT,400,200,parent,NULL,NULL,NULL);
	ShowWindow(win,1);
}

void ViewI2H(HWND parent)
{
	HWND win;
	if (!NET_INIT)
	{
		MessageBox(parent,"Network not initialized!","View Input to Hidden
Weights",
			MB_ICONSTOP);
		return;
	}
	win=CreateWindow("I2HClass","Input to Hidden Weights",WS_VSCROLL, 
		CW_USEDEFAULT,CW_USEDEFAULT,400,200,parent,NULL,NULL,NULL);
	ShowWindow(win,1);
}

void ViewH2O(HWND parent)
{
	HWND win;
	if (!NET_INIT)
	{
		MessageBox(parent,"Network not initialized!","View Hidden to Output
Weights",
			MB_ICONSTOP);
		return;
	}
	win=CreateWindow("H2OClass","Hidden to Output Weights",WS_VSCROLL, 
		CW_USEDEFAULT,CW_USEDEFAULT,400,200,parent,NULL,NULL,NULL);
	ShowWindow(win,1);
}

void ViewDesiredOutput(HWND parent)
{
	HWND win;
	if (!NET_INIT)
	{
		MessageBox(parent,"Network not initialized!","View Desired Output
Activations",
			MB_ICONSTOP);
		return;
	}
	win=CreateWindow("DesiredClass","Desired Output Activations",WS_VSCROLL, 
		CW_USEDEFAULT,CW_USEDEFAULT,500,200,parent,NULL,NULL,NULL);
	ShowWindow(win,1);
}

void GetInput(HWND hwnd)
/* This will read incoming DATA from a file into
the input nodes.  The first line in the input file should be
the input set you want to load data into. */
{
	FILE *file;
	int count,set;
	int DataType;
	char filename[80];
	char line[100];
	OPENFILENAME ofn; // common dialog box structure

	if (!NET_INIT)
	{
		MessageBox(hwnd,"Network Not Initialized!","Load Input File",
			MB_ICONHAND);
		return;
	}

	//First get filename		
	// Initialize OPENFILENAME
	ofn.lStructSize = sizeof(OPENFILENAME);
	ofn.hInstance=NULL;
	ofn.hwndOwner = hwnd;
	ofn.lpstrFile = filename;
	ofn.nMaxFile = sizeof(filename);
	ofn.lpstrFilter = "All\0*.*\0Network Data\0*.DAT\0";
	ofn.lpstrCustomFilter=NULL;
	ofn.nFilterIndex = 2;
	ofn.lpstrFileTitle = NULL;
	ofn.nMaxFileTitle = 0;
	
	ofn.lpstrInitialDir = NULL;
	ofn.lpstrTitle="Open Network Data File";
	ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
		

	// Display the Open dialog box. 
	if (GetOpenFileName(&ofn)!=TRUE)
	{
		MessageBox(hwnd,"Invalid Filename.","Load Data File",MB_ICONWARNING);
		return;
	}

	//Open the file, read only
	if ((file=fopen(filename,"r"))==NULL)
	{
		MessageBox(hwnd,"Unable to open file for read!","Load Data
File",MB_ICONHAND);
		return;
	}

	//Do you want to load this as serial or optimized? 1=optimized 0=serial
	DataType=MessageBox(hwnd,"Load optimized?","Load Data File",MB_YESNO);

	/* The first line in the file should contain the input set you
	want to begin loading the data into.  From that point it will
	continue to load data until it hits the end of file. */
	fgets(line,100,file);
	set=atoi(line);
	if (set<0 | set>INPUT_SET)
	{
		MessageBox(hwnd,"Error: First line in file should contain number of
the input set to start loading into."
			,"Load Data File",MB_ICONWARNING);
		fclose(file);
		return;
	}

	if (DataType!=IDYES) //then load Serial
	do
	{		
		for (count=0; count<NUM_INPUT; count++)
		{
			if(feof(file))
			{
				MessageBox(hwnd,"End of Data Reached","Load Data
File",MB_OK);
				fclose(file);
				return;
			}
			strcpy(line,"0.000000");
			fgets(line,100,file);
			Net.input[set][count].activation=atof(line);
		}
		set++;
	} while (set<INPUT_SET);
	else //optimized
	{
		do
		{		
				if(feof(file))
				{
					MessageBox(hwnd,"End of Data Reached","Load
Data File",MB_OK);
					fclose(file);
					return;
				}
				ZeroMemory(&line[0],strlen(line));
				fgets(line,50,file);
				for (count=0; count<NUM_INPUT; count++)
				
Net.input[set][count].activation=line[count]-'0';
				for (count=0; count<NUM_OUTPUT; count++)
				{
					if (line[count+NUM_INPUT+1]=='0')
					
DESIRED_OUTPUT[set][count]=(float)0.00;
					else
					
DESIRED_OUTPUT[set][count]=(float)1.00;
				}

			set++;
		} while (set<INPUT_SET);
	} //End of else

	fclose(file);
	strcpy(line,"Data loaded from: ");
	strcat(line,filename);
	MessageBox(hwnd,line,"Load Data File",MB_OK);
	return;
} //End of GetInput

void Epoch(HWND hwnd)
/* Computes output of network and adjusts using error function
until net is trained. */
{
	int SetCount; //Counter to keep track of what input set we are on.
	int total;  //Total number of input sets which flag accetable error rates.
	unsigned long keyval;
	int i;
	long *Flags=(long *)malloc(sizeof(long)*INPUT_SET);
	/* If a particular input pattern has an acceptable output
	error with these weights I will set this input patterns flag
	to true. This allows me to know when all the input patterns
	are trained. */

	if (!NET_INIT)
	{
		MessageBox(hwnd,"Network Not Initialized!","Train Network",
			MB_ICONHAND);
		return;
	}

	MessageBox(hwnd,"Beginning Network Training!","Train Network",MB_OK);
	ITERATIONS=0;
	do
	{
		for (SetCount=0; SetCount<INPUT_SET; SetCount++)
		{
			//Monitor keyboard interrupt for keypress 'break'
			keyval=_inp(0x60);
			if (keyval==70) //on press of CTRL-BREAK abort training.
			{
				/* This is nice since you can stop the network at
				any time and look to see how close it is, and restart
				it training from where it left off. */
				SetForegroundWindow(hwnd);
				if (MessageBox(hwnd,"Abort Training???","Train
Network",
						MB_YESNO)==IDYES)
					return;
			}
			Compute(SetCount);
			if (Good(SetCount))
			{ 
				/* This particular input pattern is within the
acceptable
				error rate. */
				Flags[SetCount]=1;
				total=0;
				for (i=0; i<INPUT_SET; i++)
					if (Flags[i]==1) total+=1;
				if (total==INPUT_SET)
				{
					SetForegroundWindow(hwnd);
					MessageBox(hwnd,"Network successfully
Trained!","Train Network",MB_OK);
					free(Flags);
					return; //Network trained
				}
			}
			else
			{
				BackProp(SetCount); //Adjust weights
				ITERATIONS++;
				Flags[SetCount]=0;
			}
		} //End of for SetCount
	} while (1);
} //End of Epoch

int Good(int SetCount)
/* Computes overall network error, returns
1 if pattern is trained, else 0 */
{
	int i;
	/* Compute overall network error:
	(sum(square(actual output of node i-desired output of node i)))/NUM_OUTPUT */
	Net.error[SetCount]=0;
	for (i=0; i<NUM_OUTPUT; i++)
	
Net.error[SetCount]=Net.error[SetCount]+(square((Net.output[i].activation-DESIRED_OUT
PUT[SetCount][i])));
	Net.error[SetCount]=Net.error[SetCount]/NUM_OUTPUT; //Divide by the total
number of output units.
	if (Net.error[SetCount]<=ACCEPTABLE_ERROR)
		return 1;
	else
		return 0;
}

void BackProp(int SetCount)
/* Computes error value of output activation and adjusts
weights backward through the net. */
{
	int i,j;
	double *EAo=(double *)malloc(sizeof(double)*NUM_OUTPUT); //Output node
activation error
	double *EAh=(double *)malloc(sizeof(double)*NUM_HIDDEN); //Hidden node
activation error
	/* Compute EA for output nodes (difference between actual
	and desired activation output) */
	for (i=0; i<NUM_OUTPUT; i++)
		EAo[i]=Net.output[i].activation-DESIRED_OUTPUT[SetCount][i];
	//Compute EA for hidden nodes
	for (i=0; i<NUM_HIDDEN; i++)
	{
		EAh[i]=0;
		for (j=0; j<NUM_OUTPUT; j++)
		
EAh[i]+=(Net.h2o[i][j]*(Net.output[j].activation)*(1-Net.output[j].activation)*EAo[j]
);
	}
	//Adjust weights accordingly
	for (i=0; i<NUM_HIDDEN; i++)
		for (j=0; j<NUM_OUTPUT; j++)		 
		
Net.h2o[i][j]+=((-1)*Net.hidden[i].activation*Net.output[j].activation*(1-Net.output[
j].activation)*EAo[j]);
	for (i=0; i<NUM_INPUT; i++)
		for (j=0; j<NUM_HIDDEN; j++)
		
Net.i2h[i][j]+=((-1)*Net.input[SetCount][i].activation*Net.hidden[j].activation*(1-Ne
t.hidden[j].activation)*EAh[j]);
	free(EAo);
	free(EAh);
} //Yes! End of backprop.

void Compute(int SetCount)
/* Pushes input values through the net and gives output activiation */
{
	int i,h,o;
	//Sum up Input to Hidden inputs
	for (h=0; h<NUM_HIDDEN; h++)
	{
		Net.hidden[h].input=0; //Reset total input
		for (i=0; i<NUM_INPUT; i++)
		
Net.hidden[h].input+=(Net.input[SetCount][i].activation*Net.i2h[i][h]);
	}
	//Peform Sigmoid on total inputs of hidden layer
	for (h=0; h<NUM_HIDDEN; h++)
		Net.hidden[h].activation=SIGMOID(Net.hidden[h].input);
	//Sum up Hidden to Output inputs
	for (o=0; o<NUM_OUTPUT;  o++)
	{
		Net.output[o].input=0; //Reset total input
		for (h=0; h<NUM_HIDDEN; h++)
			Net.output[o].input+=(Net.hidden[h].activation*Net.h2o[h][o]);
	}
	//Perform Sigmoid on total inputs of output layer
	for (o=0; o<NUM_OUTPUT; o++)
		Net.output[o].activation=SIGMOID(Net.output[o].input);
	return;
} //End of Compute

void SetDOutput(HWND hwnd)
/* Allows the user to manually set the desired
output for a particular input pattern. */
{
	MSG msg;
	int i,set;
	char line[100];

	if (!NET_INIT)
	{
		MessageBox(hwnd,"Network Not Initialized","Set Desired Output
Activation",
			MB_ICONHAND);
		return;
	}

	//What input set to run..
	INPUTSTRING[0]=0; set=-1; //Reset Input string and image set
	UserInput("Enter INPUT SET",300,100,hwnd);
	while (FLAGWIN!=NULL) 
	{
		GetMessage(&msg,NULL,0,0);
		TranslateMessage(&msg);
		DispatchMessage(&msg); //return control to Windows
	}
	set=atoi(INPUTSTRING);
	if (strlen(INPUTSTRING)<1)
			set=-1;
	if (set<0 | set>INPUT_SET-1)
	{
		MessageBox(hwnd,"Invalid Input Set","Set Desired Output",MB_ICONHAND);
		return;
	}

	for (i=0; i<NUM_OUTPUT; i++)
	{
		do 
		{ 
			INPUTSTRING[0]=0; //Reset Input string
			itoa(i, line, 10);
			strcat(line," nodes output");
			UserInput(line,300,100,hwnd);
			while (FLAGWIN!=NULL) 
			{
				GetMessage(&msg,NULL,0,0);
				TranslateMessage(&msg);
				DispatchMessage(&msg); //return control to Windows
			}
			DESIRED_OUTPUT[set][i]=(float)atof(INPUTSTRING);
		} while (DESIRED_OUTPUT[set][i]<0 | DESIRED_OUTPUT[set][i]>1);
	}
	MessageBox(hwnd,"Desired Output set.","Set Desired Output",MB_OK);
	return;
}


int PASCAL WinMain(HANDLE hThisInst, HANDLE hPrevInst,
				   LPSTR lpszArgs, int nWinMode)
{
	HWND hwnd;
	MSG msg;
	WNDCLASS wcl,kid,input,hidden,output,i2h,h2o,desired;

	/* If this is the first instance of the program, then I need
	to register several window classes for different window types. */

	if (!hPrevInst) //Like school in the summertime, no CLASS
	{
		//Register a Main Window Class
			wcl.hInstance=hThisInst; //handle to this instance
			wcl.lpszClassName="MyWin"; //Window Class name
			wcl.lpfnWndProc=WindowFunc; //Window function
			wcl.style=CS_DBLCLKS;  //Support double click of mouse
			wcl.hIcon=LoadIcon(NULL,IDI_APPLICATION); //Icon style
			wcl.hCursor=LoadCursor(NULL,IDC_ARROW); //Cursor style
			wcl.lpszMenuName=NULL; //no Menu
			wcl.cbClsExtra=0; //no extra
			wcl.cbWndExtra=0; //Information needed
			wcl.hbrBackground=GetStockObject(WHITE_BRUSH);

		//Register Generic Child Class
			kid.hInstance=hThisInst; //handle to this instance
			kid.lpszClassName="ChildClass"; //Window Class name
			kid.lpfnWndProc=ChildFunc; //Window function
			kid.style=CS_NOCLOSE; //Disable close option. 
			kid.hIcon=LoadIcon(NULL,IDI_APPLICATION); //Icon style
			kid.hCursor=LoadCursor(NULL,IDC_ARROW); //Cursor style
			kid.lpszMenuName=NULL; //no Menu
			kid.cbClsExtra=0; //no extra
			kid.cbWndExtra=0; //Information needed
			kid.hbrBackground=GetStockObject(WHITE_BRUSH);

		//Register DisplayInputClass (supports scroll bars)	
			input.hInstance=hThisInst; //handle to this instance
			input.lpszClassName="InputClass"; //Window Class name
			input.lpfnWndProc=DisplayInputNodes; //Window function
			input.style=CS_NOCLOSE; //Disable close option. 
			input.hIcon=LoadIcon(NULL,IDI_APPLICATION); //Icon style
			input.hCursor=LoadCursor(NULL,IDC_ARROW); //Cursor style
			input.lpszMenuName=NULL; //no Menu
			input.cbClsExtra=0; //no extra
			input.cbWndExtra=0; //Information needed
			input.hbrBackground=GetStockObject(WHITE_BRUSH);

		//Register DisplayHiddenClass
			hidden.hInstance=hThisInst; //handle to this instance
			hidden.lpszClassName="HiddenClass"; //Window Class name
			hidden.lpfnWndProc=DisplayHiddenNodes; //Window function
			hidden.style=CS_NOCLOSE; //Disable close option. 
			hidden.hIcon=LoadIcon(NULL,IDI_APPLICATION); //Icon style
			hidden.hCursor=LoadCursor(NULL,IDC_ARROW); //Cursor style
			hidden.lpszMenuName=NULL; //no Menu
			hidden.cbClsExtra=0; //no extra
			hidden.cbWndExtra=0; //Information needed
			hidden.hbrBackground=GetStockObject(WHITE_BRUSH);

		//Register DisplayOutputClass
			output.hInstance=hThisInst; //handle to this instance
			output.lpszClassName="OutputClass"; //Window Class name
			output.lpfnWndProc=DisplayOutputNodes; //Window function
			output.style=CS_NOCLOSE; //Disable close option. 
			output.hIcon=LoadIcon(NULL,IDI_APPLICATION); //Icon style
			output.hCursor=LoadCursor(NULL,IDC_ARROW); //Cursor style
			output.lpszMenuName=NULL; //no Menu
			output.cbClsExtra=0; //no extra
			output.cbWndExtra=0; //Information needed
			output.hbrBackground=GetStockObject(WHITE_BRUSH);

		//Register DisplayI2HClass
			i2h.hInstance=hThisInst; //handle to this instance
			i2h.lpszClassName="i2hClass"; //Window Class name
			i2h.lpfnWndProc=DisplayI2H; //Window function
			i2h.style=CS_NOCLOSE; //Disable close option. 
			i2h.hIcon=LoadIcon(NULL,IDI_APPLICATION); //Icon style
			i2h.hCursor=LoadCursor(NULL,IDC_ARROW); //Cursor style
			i2h.lpszMenuName=NULL; //no Menu
			i2h.cbClsExtra=0; //no extra
			i2h.cbWndExtra=0; //Information needed
			i2h.hbrBackground=GetStockObject(WHITE_BRUSH);

		//Register DisplayH2OClass
			h2o.hInstance=hThisInst; //handle to this instance
			h2o.lpszClassName="h2oClass"; //Window Class name
			h2o.lpfnWndProc=DisplayH2O; //Window function
			h2o.style=CS_NOCLOSE; //Disable close option. 
			h2o.hIcon=LoadIcon(NULL,IDI_APPLICATION); //Icon style
			h2o.hCursor=LoadCursor(NULL,IDC_ARROW); //Cursor style
			h2o.lpszMenuName=NULL; //no Menu
			h2o.cbClsExtra=0; //no extra
			h2o.cbWndExtra=0; //Information needed
			h2o.hbrBackground=GetStockObject(WHITE_BRUSH);

		//Register DisplayDesiredClass
			desired.hInstance=hThisInst; //handle to this instance
			desired.lpszClassName="DesiredClass"; //Window Class name
			desired.lpfnWndProc=DisplayDesired; //Window function
			desired.style=CS_NOCLOSE; //Disable close option. 
			desired.hIcon=LoadIcon(NULL,IDI_APPLICATION); //Icon style
			desired.hCursor=LoadCursor(NULL,IDC_ARROW); //Cursor style
			desired.lpszMenuName=NULL; //no Menu
			desired.cbClsExtra=0; //no extra
			desired.cbWndExtra=0; //Information needed
			desired.hbrBackground=GetStockObject(WHITE_BRUSH);

		
		if (!RegisterClass(&wcl)) return 0;				
		if (!RegisterClass(&kid)) return 0;				
		if (!RegisterClass(&input)) return 0;
		if (!RegisterClass(&hidden)) return 0;		
		if (!RegisterClass(&output)) return 0;		
		if (!RegisterClass(&i2h)) return 0;		
		if (!RegisterClass(&h2o)) return 0;				
		if (!RegisterClass(&desired)) return 0;
	}

	/* Now that a window class has been registered, a Window can
	be created. */

	hwnd=CreateWindow(
		"MyWin", //name of Window Class
		"Neural Net - J.P. 97", //Title
		WS_OVERLAPPEDWINDOW, //window_style normal
		CW_USEDEFAULT, //X coordinate - let Windows decide
		CW_USEDEFAULT, //Y coordinate - let Windows decide
		350, //Width 
		350, //Height
		NULL, //Parent window, there isn't one
		NULL, //No menu
		hThisInst, //handle of this instance of the program
		NULL, //No additional arguments
		);	
	
	//Now display the window
	ShowWindow(hwnd,nWinMode);
	//Display main Menu
	Menu(hwnd);
	
	//Create message loop
	while (GetMessage(&msg,NULL,0,0))
	{
		TranslateMessage(&msg); //allow use of keyboard
		DispatchMessage(&msg); //return control to Windows
	}
	return msg.wParam;
}

/* This function is called by Windows and is passed messages from the
message queue. */
LONG FAR PASCAL WindowFunc(HWND hwnd, unsigned int message,
								   unsigned int
wParam, LONG lParam)
{
	int xcount,ycount;

	switch (message)
	{
	case WM_CHAR: //Process keystroke
		Beep(1,1);
		break;

	case WM_LBUTTONDBLCLK: //Process left mouse button
		if (FLAGWIN)
		//Cannot perform operation
			Beep(1,20);
		else
		{
	
			xcount=(int)LOWORD(lParam); //horizontal position of cursor 
			ycount=(int)HIWORD(lParam); //vertical position of cursor 
			ProcessSelection(xcount,ycount,hwnd);
		}
		break;

	case WM_PAINT: //Redraw the screen
			Menu(hwnd);
		break;
	
	case WM_DESTROY: //terminate program
		PostQuitMessage(0);
		break;

	}

	/* let Windows process any messages not specified in the
	preceding switch statement.  */
	return DefWindowProc(hwnd,message,wParam,lParam);
}  

void clrscr(HWND hwnd)
/* Clears the screen */
{
	HDC hdc;
	int i;
	hdc=GetDC(hwnd);
	//Clear the screen
	for (i=0; i<400; i++)
		TextOut(hdc,1,i,
		"                                                      ",54);
	ReleaseDC(hwnd,hdc);
}

void Menu(HWND hwnd)
/* This function draws the main menu on the screen. */
{
	HDC hdc;
	char Temp[50],Temp2[10];

	hdc=GetDC(hwnd);
	//Main Menu
		TextOut(hdc,1,1    ,"Main Menu           ",20);
		TextOut(hdc,20,20  ,"Initialize Network  ",20);
		TextOut(hdc,20,40  ,"Load Input File     ",20);
		TextOut(hdc,20,60  ,"Train Network       ",20);
		TextOut(hdc,20,80  ,"Save Network        ",20);
		TextOut(hdc,20,100 ,"Load Network        ",20);
		TextOut(hdc,20,120 ,"Camera Viewpoint    ",20);
		TextOut(hdc,20,140 ,"Run Image           ",20);
		TextOut(hdc,20,160 ,"Set Desired Output  ",20);
		TextOut(hdc,20,180 ,"View ENV Params     ",20);
		TextOut(hdc,20,200 ,"Quit                ",20);
		TextOut(hdc,200,20 ,"View Dsrd Outputs   ",20);
		TextOut(hdc,200,40 ,"Input Activations   ",20);
		TextOut(hdc,200,60 ,"Hidden Activations  ",20);
		TextOut(hdc,200,80 ,"Output Activations  ",20);
		TextOut(hdc,200,100,"I2H Weights         ",20);
		TextOut(hdc,200,120,"H2O Weights         ",20);
		TextOut(hdc,200,140,"Recognize Image     ",20);
		TextOut(hdc,200,160,"Load DSRD from file ",20);
		TextOut(hdc,200,180,"Run All input sets  ",20);
		//Display Time to Train
		strcpy(Temp,"Training Revolutions: ");
		strcpy(Temp2,"0.00000");
		ltoa((long)ITERATIONS,Temp2,10);
		strcat(Temp,Temp2);
		TextOut(hdc,100,300,Temp,strlen(Temp));
	ReleaseDC(hwnd,hdc);
} //End of Menu

void ProcessSelection(int xcount, int ycount, HWND hwnd)
/* This checks for a user selection from the main menu and
responds accordingly. */
{
	HDC hdc;
	MSG msg;
	int i,set;

	hdc=GetDC(hwnd);

	//Clear the line where status remarks are being printed.
	for (i=0; i<200; i++)
		TextOut(hdc,i,280," ",1);

	if (xcount>20 & xcount<150)	//Left menu items
	{
		if (ycount>20 & ycount<40) //Initialize Network
		{
			TextOut(hdc,1,280,"Initializing Network...",23);
			NetInit(hwnd);
			TextOut(hdc,1,280,"Network Initialized.     ",24);
			ReleaseDC(hwnd,hdc);
			return;
		}
		if (ycount>40 & ycount<60) //Load Input File
		{
			TextOut(hdc,1,280,"Load Input File",15);
			GetInput(hwnd);
			ReleaseDC(hwnd,hdc);
			return;
		}
		if (ycount>60 & ycount<80) //Train Network
		{
			TextOut(hdc,1,280,"Training in Progress!!",22);
			Epoch(hwnd); 
			TextOut(hdc,1,280,"Training Complete      ",23);
			ReleaseDC(hwnd,hdc);
			return;
		}
		if (ycount>80 & ycount<100) //Save Network
		{
			TextOut(hdc,1,280,"Save  Network",13);
			SavNet(hwnd);
			ReleaseDC(hwnd,hdc);
			return;
		}
		if (ycount>100 & ycount<120) //Load Network
		{
			TextOut(hdc,1,280,"Load Network",12);
			LoadNet(hwnd);
			ReleaseDC(hwnd,hdc);
			return;
		}
		if (ycount>120 & ycount<140)  //Get single Camera Image
		{
			WhatISee(hwnd);
			ReleaseDC(hwnd,hdc);
			return;
		}
		if (ycount>140 & ycount<160) //Run Image
		{
			TextOut(hdc,1,280,"Run Image",9);
			//Check if Network is initialized
			if (!NET_INIT)
			{
				MessageBox(hwnd,"Network Not Initialized!","Run
Image",
					MB_ICONHAND);
				return;
			}
			//What input set to run..
			INPUTSTRING[0]=0; set=-1; //Reset Input string and image set
			UserInput("Enter Input Set to run",300,100,hwnd);
			while (FLAGWIN!=NULL) 
			{
				GetMessage(&msg,NULL,0,0);
				TranslateMessage(&msg);
				DispatchMessage(&msg); //return control to Windows
			}
			set=atoi(INPUTSTRING);
			if (strlen(INPUTSTRING)<1)
				set=-1;
			if (set<0 | set>INPUT_SET-1)
			{
				MessageBox(hwnd,"Invalid Input Set","Run
Image",MB_ICONHAND);
				ReleaseDC(hwnd,hdc);
				return;
			}
			Compute(set);
			MessageBox(hwnd,"Image run, View Output Activations to see
results.","Run Image Set",MB_OK);
			ReleaseDC(hwnd,hdc);
			return;
		} //end of Run Image
		if (ycount>160 & ycount<180) //Set Desired Output
		{
			TextOut(hdc,1,280,"Set Desired Output",18);
			SetDOutput(hwnd);
			ReleaseDC(hwnd,hdc);
			return;
		}
		if (ycount>180 & ycount<200) //View Env Params
		{
			TextOut(hdc,1,280,"View Environment Parameters",27);
			ViewParams(hwnd);
			ReleaseDC(hwnd,hdc);
			return;
		}
		if (ycount>200 & ycount<220) //Quit
		{
			if (MessageBox(hwnd,"You wish to
quit?","Quit",MB_YESNO)==IDYES)
			{
				if (NET_INIT)
					FreeSpace(); //Free up environment!
				PostQuitMessage(0); //Exit Program
			}
		}
	} //end of if (xcount>20 & xcount<150)	

	if (xcount<350 & xcount>150) //Right Menu Items
	{
		if (ycount>20 & ycount<40)  //View Desired Output
		{
			TextOut(hdc,1,280,"View Desired Output",19);
			ViewDesiredOutput(hwnd);
			ReleaseDC(hwnd,hdc);
			return;
		}
		if (ycount>40 & ycount<60) //View Input Activations
		{
			TextOut(hdc,1,280,"View Input Activations",22);
			ViewInputActivations(hwnd);
			ReleaseDC(hwnd,hdc);
			return;
		}
		if (ycount>60 & ycount<80) //View Hidden Activations
		{
			TextOut(hdc,1,280,"View Hidden Activations",23);
			ViewHiddenActivations(hwnd);
			ReleaseDC(hwnd,hdc);
			return;
		}
		if (ycount>80 & ycount<100) //View Output Activations
		{
			TextOut(hdc,1,280,"View Output Activations",23);
			ViewOutputActivations(hwnd);
			ReleaseDC(hwnd,hdc);
			return;
		}
		if (ycount>100 & ycount<120) //View I2H Weights
		{
			TextOut(hdc,1,280,"View Input to Hidden",20);
			ViewI2H(hwnd);
			ReleaseDC(hwnd,hdc);
			return;
		}
		if (ycount>120 & ycount<140) //View H2O Weights
		{
			TextOut(hdc,1,280,"View Hidden to Output",21);
			ViewH2O(hwnd);
			ReleaseDC(hwnd,hdc);
			return;
		}
		if (ycount>140 & ycount<160) //Recognize Image
		{
			Capture(hwnd);
			ReleaseDC(hwnd,hdc);
			return;
		}
		if (ycount>160 & ycount<180) //Load desired output from file
		{
			TextOut(hdc,1,280,"Load Desired Output File",24);
			LoadDSRD(hwnd);
			ReleaseDC(hwnd,hdc);
			return;
		}
		if (ycount>180 & ycount<200) //Run All input Sets
		{
			TextOut(hdc,1,280,"Run all input Sets",18);
			RunAllSets(hwnd);
			ReleaseDC(hwnd,hdc);
			return;
		}
	} // end of if (xcount<350 & xcount>150)
	ReleaseDC(hwnd,hdc);
} //End of ProcessSelection

void DisplayText(char title[50],char output[100],HWND parent,int priority)
/* This function will create a dialog box which will
display the output to the user.  If priority is set to 1 then the
dialog must be CLOSED before the user can continue. */
{
	HWND child;
	HDC hdc;

	switch (priority)
	{
		
		case 1:
			FLAGWIN=CreateWindow(
				"ChildClass", //name of Window Class
				title, //You supply the title
				WS_DLGFRAME, //window_style dialog box
				CW_USEDEFAULT, //X coordinate - let Windows decide
				CW_USEDEFAULT, //Y coordinate - let Windows decide
				300, //Width
				100, //Height 
				parent, //Handle to Parent window
				NULL, //No menu
				NULL, //handle of this instance of the program
				NULL, //No additional arguments
				);
			//display the window
			ShowWindow(FLAGWIN,1);
			//display the message
			hdc=GetDC(FLAGWIN);
			SetTextColor(hdc,0x0000FF); //Red
			TextOut(hdc,1,1,output,strlen(output));
			ReleaseDC(hdc,child);	
			break;
		default:
			child=CreateWindow(
				"ChildClass", //name of Window Class
				title, //You supply the title
				WS_DLGFRAME, //window_style dialog box
				CW_USEDEFAULT, //X coordinate - let Windows decide
				CW_USEDEFAULT, //Y coordinate - let Windows decide
				300, //Width
				100, //Height 
				parent, //Handle to Parent window
				NULL, //No menu
				NULL, //handle of this instance of the program
				NULL, //No additional arguments
				);
			//display the window
			ShowWindow(child,1);
			//display the message
			hdc=GetDC(child);
			SetTextColor(hdc,0x0);
			TextOut(hdc,1,1,output,strlen(output));
			ReleaseDC(hdc,child);	
			break;
	}	
} //End of DisplayText

void UserInput(char *title,int width, int height,HWND parent)
{
	HDC hdc;

	FLAGWIN=CreateWindow(
				"ChildClass", //name of Window Class
				title, //You supply the title
				WS_DLGFRAME, //edit style dialog box
				CW_USEDEFAULT, //X coordinate - let Windows decide
				CW_USEDEFAULT, //Y coordinate - let Windows decide
				width, //Width
				height, //Height 
				parent, //Handle to Parent window
				NULL, //No menu
				NULL, //handle of this instance of the program
				NULL, //No additional arguments
				);
			//display the window
			ShowWindow(FLAGWIN,1);
			//display the message
			hdc=GetDC(FLAGWIN);
			TextOut(hdc,1,1," ",1);
			ReleaseDC(hdc,FLAGWIN);
}


LONG FAR PASCAL ChildFunc(HWND child, unsigned int message,
								   unsigned int
wParam, LONG lParam)
/* This function handles incoming messages from the child window
class. */
{
	HDC hdc;
	switch (message)
	{

		case WM_LBUTTONDOWN:
				//User presses mouse get rid of window
				if (FLAGWIN==child)
					FLAGWIN=NULL;
				DestroyWindow(child);
			break;
		case WM_CHAR:
			switch(wParam)
			{
				case 13: //return
					if (FLAGWIN==child)
						FLAGWIN=NULL;
					DestroyWindow(child);
					break;
				default:
					hdc=GetDC(child);
					strcat(INPUTSTRING,(char *)&wParam);
				
TextOut(hdc,1,1,INPUTSTRING,strlen(INPUTSTRING));
					ReleaseDC(hdc,child);
					break;
			} //End switch wParam
			break;
	} 
	/* let Windows process any messages not specified in the
	preceding switch statement.  */
	return DefWindowProc(child,message,wParam,lParam);
} //End of ChildFunc


LONG FAR PASCAL DisplayInputNodes(HWND scroll, unsigned int message,
						unsigned int wParam, LONG lParam)
/* Handles incoming messages for the scrolling window displaying 
Input nodes and their activations. */
{
	HDC hdc;  
	PAINTSTRUCT ps; 
	TEXTMETRIC tm; 
	SCROLLINFO si; 
 
	/* These variables are required to display text. */ 
 
	static int xClient;     /* width of client area                  */ 
	static int yClient;     /* height of client area                 */ 
	static int xClientMax;  /* maximum width of client area          */ 
 
	static int xChar;       /* horizontal scrolling unit             */ 
	static int yChar;       /* vertical scrolling unit               */ 
	static int xUpper;      /* average width of uppercase letters    */ 
 
	static int xPos;        /* current horizontal scrolling position */ 
	static int yPos;        /* current vertical scrolling position   */ 
 
	static int xMax;        /* maximum horiz. scrolling position     */ 
	static int yMax;        /* maximum vert. scrolling position      */ 
 
	int yInc;               /* vertical scrolling increment          */ 
 
	long i;                  /* loop counter                          */ 
	int x, y;               /* horiz. and vert. printing coords      */ 
 
	long FirstLine;          /* first line in the invalidated area    */ 
	long LastLine;           /* last line in the invalidated area     */ 

	char tempa[100],tempb[20]; /* Used to parse output lines */
	div_t div_result;		/* Division result structure */
	long SetCount;          /* Keep track of what input set */
	long NodeCount;			/* Keep track of what node in the input set */

/* This is the number of maximum number of lines that need
	to be displayed.  */	
long LINES=NUM_INPUT*INPUT_SET;
 
	switch (message) 
	{ 

		case WM_LBUTTONDOWN:
				//User presses mouse get rid of window
				DestroyWindow(scroll);
			break;
			
		 case WM_CREATE :
			 
 		   	
			/* Get the handle of the client area's device context. */ 
 
			hdc = GetDC (scroll); 
 
	        /* Extract font dimensions from the text metrics. */ 
 
			GetTextMetrics (hdc, &tm); 
			xChar = tm.tmAveCharWidth; 
			xUpper = (tm.tmPitchAndFamily & 1 ? 3 : 2) * xChar/2; 
			yChar = tm.tmHeight + tm.tmExternalLeading; 
			
			/* Free the device context. */  
			ReleaseDC (scroll, hdc);  
	       /* 
		    * Set an arbitrary maximum width for client area. 
			* (xClientMax is the sum of the widths of 48 average 
			* lowercase letters and 12 uppercase letters.) 
			*/  
	        xClientMax = 48 * xChar + 12 * xUpper; 
		    return 0; 
 
    case WM_SIZE: 
 
        /* Retrieve the dimensions of the client area. */ 
 
        yClient = HIWORD (lParam); 
        xClient = LOWORD (lParam); 
 
        /* 
         * Determine the maximum vertical scrolling position. 
         * The two is added for extra space below the lines 
         * of text. 
         */ 
 
        yMax = max (0, LINES + 2 - yClient/yChar); 
 
        /* 
         * Make sure the current vertical scrolling position 
         * does not exceed the maximum. 
         */ 
 
        yPos = min (yPos, yMax); 
 
        /* 
         * Adjust the vertical scrolling range and scroll box 
         * position to reflect the new yMax and yPos values. 
         */ 
 
        si.cbSize = sizeof(si); 
        si.fMask  = SIF_RANGE | SIF_PAGE | SIF_POS; 
        si.nMin   = 0; 
        si.nMax   = yMax; 
        si.nPage  = yClient / yChar; 
        si.nPos   = yPos; 
        SetScrollInfo(scroll, SB_VERT, &si, TRUE); 
 
        /* 
         * Determine the maximum horizontal scrolling position. 
         * The two is added for extra space to the right of the 
         * lines of text. 
         */ 
 
        xMax = max (0, 2 + (xClientMax - xClient)/xChar); 
 
        /* 
         * Make sure the current horizontal scrolling position 
         * does not exceed the maximum. 
         */ 
 
        xPos = min (xPos, xMax); 
 
        /* 
         * Adjust the horizontal scrolling range and scroll box 
         * position to reflect the new xMax and xPos values. 
         */ 
 
        si.cbSize = sizeof(si); 
        si.fMask  = SIF_RANGE | SIF_PAGE | SIF_POS; 
        si.nMin   = 0; 
        si.nMax   = xMax; 
        si.nPage  = xClient / xChar; 
        si.nPos   = xPos; 
        SetScrollInfo(scroll, SB_HORZ, &si, TRUE); 
 
        return 0; 
 
    case WM_PAINT: 
 
        /* Prepare the window for painting. */ 
 
        hdc = BeginPaint(scroll, &ps); 
 
        /* 
         * Use the current vertical scrolling position and 
         * coordinates of the invalid rectangle to determine 
         * the range of new lines that should be drawn in the 
         * client area. 
         */ 
 
        FirstLine = max (0, yPos + ps.rcPaint.top/yChar - 1); 
        LastLine = min (LINES, yPos + ps.rcPaint.bottom/yChar); 
 
        /* Display these lines. */ 		
		for (i = FirstLine;i < LastLine;i++) 
		{ 
			div_result = div( i, NUM_INPUT);
			SetCount=div_result.quot;
			NodeCount=div_result.rem;
			x = xChar * (1 - xPos); 
		    y = yChar * (1 - yPos + i);
			strcpy(tempa,"Input Set: "); ltoa(div_result.quot,tempb,10);
strcat(tempa,tempb);
			strcat(tempa," Node: "); ltoa(NodeCount,tempb,10);
strcat(tempa,tempb);
			strcat(tempa," Activation: "); 
		
ConvertFloat(tempb,Net.input[SetCount][NodeCount].activation,8);
			strcat(tempa,tempb);
			//Clear line
			TextOut(hdc,x,y,"                                            
        ",52);
			TextOut(hdc,x+50,y,"                                         
           ",52);
			TextOut(hdc, x, y, tempa, strlen(tempa)); 
		}  
 
        /* Indicate that painting is finished. */ 
 
        EndPaint(scroll, &ps);
        break;  
 
    case WM_VSCROLL: 

            switch(LOWORD (wParam)) { 
 
            /* User clicked the shaft above the scroll box. */ 
 
            case SB_PAGEUP: 
                 yInc = min(-1, -yClient / yChar); 
                 break; 
 
            /* User clicked the shaft below the scroll box. */ 
 
            case SB_PAGEDOWN: 
                 yInc = max(1, yClient / yChar); 
                 break; 
 
            /* User clicked the top arrow. */ 
 
            case SB_LINEUP: 
                 yInc = -1; 
                 break; 
 
            /* User clicked the bottom arrow. */ 
 
            case SB_LINEDOWN: 
                 yInc = 1; 
                 break; 
 
            /* User dragged the scroll box. */ 
 
            case SB_THUMBTRACK: 
                 yInc = HIWORD(wParam) - yPos; 
                 break; 
 
            default: 
                 yInc = 0; 
 
        } 
 
        /* 
         * If applying the vertical scrolling increment does not 
         * take the scrolling position out of the scrolling range, 
         * increment the scrolling position, adjust the position 
         * of the scroll box, and update the window. UpdateWindow 
         * sends the WM_PAINT message. 
         */ 
 
        if (yInc = max(-yPos, min(yInc, yMax - yPos))) { 
            yPos += yInc; 
            ScrollWindowEx(scroll, 0, -yChar * yInc, 
                (CONST RECT *) NULL, (CONST RECT *) NULL, 
                (HRGN) NULL, (LPRECT) NULL, SW_INVALIDATE); 
            si.cbSize = sizeof(si); 
            si.fMask  = SIF_POS; 
            si.nPos   = yPos; 
            SetScrollInfo(scroll, SB_VERT, &si, TRUE); 
            UpdateWindow (scroll); 
        } 
		
	} //End of switch(message)

	//Let Windows handle it..
	return DefWindowProc(scroll,message,wParam,lParam);
} //End of DisplayInputNodes


LONG FAR PASCAL DisplayHiddenNodes(HWND scroll, unsigned int message,
						unsigned int wParam, LONG lParam)
/* Handles incoming messages for the scrolling window displaying 
Hidden nodes and their activations. */
{
	HDC hdc;  
	PAINTSTRUCT ps; 
	TEXTMETRIC tm; 
	SCROLLINFO si; 
 
	/* These variables are required to display text. */ 
 
	static int xClient;     /* width of client area                  */ 
	static int yClient;     /* height of client area                 */ 
	static int xClientMax;  /* maximum width of client area          */ 
 
	static int xChar;       /* horizontal scrolling unit             */ 
	static int yChar;       /* vertical scrolling unit               */ 
	static int xUpper;      /* average width of uppercase letters    */ 
 
	static int xPos;        /* current horizontal scrolling position */ 
	static int yPos;        /* current vertical scrolling position   */ 
 
	static int xMax;        /* maximum horiz. scrolling position     */ 
	static int yMax;        /* maximum vert. scrolling position      */ 
 
	int yInc;               /* vertical scrolling increment          */ 
 
	long i;                  /* loop counter                          */ 
	int x, y;               /* horiz. and vert. printing coords      */ 
 
	long FirstLine;          /* first line in the invalidated area    */ 
	long LastLine;           /* last line in the invalidated area     */ 

	char tempa[100],tempb[20]; /* Used to parse output lines */

/* This is the number of maximum number of lines that need
	to be displayed.  */	
long LINES=NUM_HIDDEN;
 
	switch (message) 
	{ 

		case WM_LBUTTONDOWN:
				//User presses mouse get rid of window
				DestroyWindow(scroll);
			break;
			
		 case WM_CREATE :
			 
 		   	
			/* Get the handle of the client area's device context. */ 
 
			hdc = GetDC (scroll); 
 
	        /* Extract font dimensions from the text metrics. */ 
 
			GetTextMetrics (hdc, &tm); 
			xChar = tm.tmAveCharWidth; 
			xUpper = (tm.tmPitchAndFamily & 1 ? 3 : 2) * xChar/2; 
			yChar = tm.tmHeight + tm.tmExternalLeading; 
			
			/* Free the device context. */  
			ReleaseDC (scroll, hdc);  
	       /* 
		    * Set an arbitrary maximum width for client area. 
			* (xClientMax is the sum of the widths of 48 average 
			* lowercase letters and 12 uppercase letters.) 
			*/  
	        xClientMax = 48 * xChar + 12 * xUpper; 
		    return 0; 
 
    case WM_SIZE: 
 
        /* Retrieve the dimensions of the client area. */ 
 
        yClient = HIWORD (lParam); 
        xClient = LOWORD (lParam); 
 
        /* 
         * Determine the maximum vertical scrolling position. 
         * The two is added for extra space below the lines 
         * of text. 
         */ 
 
        yMax = max (0, LINES + 2 - yClient/yChar); 
 
        /* 
         * Make sure the current vertical scrolling position 
         * does not exceed the maximum. 
         */ 
 
        yPos = min (yPos, yMax); 
 
        /* 
         * Adjust the vertical scrolling range and scroll box 
         * position to reflect the new yMax and yPos values. 
         */ 
 
        si.cbSize = sizeof(si); 
        si.fMask  = SIF_RANGE | SIF_PAGE | SIF_POS; 
        si.nMin   = 0; 
        si.nMax   = yMax; 
        si.nPage  = yClient / yChar; 
        si.nPos   = yPos; 
        SetScrollInfo(scroll, SB_VERT, &si, TRUE); 
 
        /* 
         * Determine the maximum horizontal scrolling position. 
         * The two is added for extra space to the right of the 
         * lines of text. 
         */ 
 
        xMax = max (0, 2 + (xClientMax - xClient)/xChar); 
 
        /* 
         * Make sure the current horizontal scrolling position 
         * does not exceed the maximum. 
         */ 
 
        xPos = min (xPos, xMax); 
 
        /* 
         * Adjust the horizontal scrolling range and scroll box 
         * position to reflect the new xMax and xPos values. 
         */ 
 
        si.cbSize = sizeof(si); 
        si.fMask  = SIF_RANGE | SIF_PAGE | SIF_POS; 
        si.nMin   = 0; 
        si.nMax   = xMax; 
        si.nPage  = xClient / xChar; 
        si.nPos   = xPos; 
        SetScrollInfo(scroll, SB_HORZ, &si, TRUE); 
 
        return 0; 
 
    case WM_PAINT: 
 
        /* Prepare the window for painting. */ 
 
        hdc = BeginPaint(scroll, &ps); 
 
        /* 
         * Use the current vertical scrolling position and 
         * coordinates of the invalid rectangle to determine 
         * the range of new lines that should be drawn in the 
         * client area. 
         */ 
 
        FirstLine = max (0, yPos + ps.rcPaint.top/yChar - 1); 
        LastLine = min (LINES, yPos + ps.rcPaint.bottom/yChar); 
 
        /* Display these lines. */ 		
		for (i = FirstLine;i < LastLine;i++) 
		{ 
			x = xChar * (1 - xPos); 
		    y = yChar * (1 - yPos + i);
			strcpy(tempa,"Hidden Node: "); ltoa(i,tempb,10);
strcat(tempa,tempb);
			strcat(tempa," Activation: "); 
			ConvertFloat(tempb,Net.hidden[i].activation,8);
			strcat(tempa,tempb);
			//Clear line
			TextOut(hdc,x,y,"                                            
        ",52);
			TextOut(hdc,x+50,y,"                                         
           ",52);
			TextOut(hdc, x, y, tempa, strlen(tempa)); 
		}  
 
        /* Indicate that painting is finished. */ 
 
        EndPaint(scroll, &ps);
        break;  
 
    case WM_VSCROLL: 

            switch(LOWORD (wParam)) { 
 
            /* User clicked the shaft above the scroll box. */ 
 
            case SB_PAGEUP: 
                 yInc = min(-1, -yClient / yChar); 
                 break; 
 
            /* User clicked the shaft below the scroll box. */ 
 
            case SB_PAGEDOWN: 
                 yInc = max(1, yClient / yChar); 
                 break; 
 
            /* User clicked the top arrow. */ 
 
            case SB_LINEUP: 
                 yInc = -1; 
                 break; 
 
            /* User clicked the bottom arrow. */ 
 
            case SB_LINEDOWN: 
                 yInc = 1; 
                 break; 
 
            /* User dragged the scroll box. */ 
 
            case SB_THUMBTRACK: 
                 yInc = HIWORD(wParam) - yPos; 
                 break; 
 
            default: 
                 yInc = 0; 
 
        } 
 
        /* 
         * If applying the vertical scrolling increment does not 
         * take the scrolling position out of the scrolling range, 
         * increment the scrolling position, adjust the position 
         * of the scroll box, and update the window. UpdateWindow 
         * sends the WM_PAINT message. 
         */ 
 
        if (yInc = max(-yPos, min(yInc, yMax - yPos))) { 
            yPos += yInc; 
            ScrollWindowEx(scroll, 0, -yChar * yInc, 
                (CONST RECT *) NULL, (CONST RECT *) NULL, 
                (HRGN) NULL, (LPRECT) NULL, SW_INVALIDATE); 
            si.cbSize = sizeof(si); 
            si.fMask  = SIF_POS; 
            si.nPos   = yPos; 
            SetScrollInfo(scroll, SB_VERT, &si, TRUE); 
            UpdateWindow (scroll); 
        } 
		
	} //End of switch(message)

	//Let Windows handle it..
	return DefWindowProc(scroll,message,wParam,lParam);
} //End of DisplayHiddenNodes

LONG FAR PASCAL DisplayOutputNodes(HWND scroll, unsigned int message,
						unsigned int wParam, LONG lParam)
/* Handles incoming messages for the scrolling window displaying 
Output nodes and their activations. */
{
	HDC hdc;  
	PAINTSTRUCT ps; 
	TEXTMETRIC tm; 
	SCROLLINFO si; 
 
	/* These variables are required to display text. */ 
 
	static int xClient;     /* width of client area                  */ 
	static int yClient;     /* height of client area                 */ 
	static int xClientMax;  /* maximum width of client area          */ 
 
	static int xChar;       /* horizontal scrolling unit             */ 
	static int yChar;       /* vertical scrolling unit               */ 
	static int xUpper;      /* average width of uppercase letters    */ 
 
	static int xPos;        /* current horizontal scrolling position */ 
	static int yPos;        /* current vertical scrolling position   */ 
 
	static int xMax;        /* maximum horiz. scrolling position     */ 
	static int yMax;        /* maximum vert. scrolling position      */ 
 
	int yInc;               /* vertical scrolling increment          */ 
 
	long i;                  /* loop counter                          */ 
	int x, y;               /* horiz. and vert. printing coords      */ 
 
	long FirstLine;          /* first line in the invalidated area    */ 
	long LastLine;           /* last line in the invalidated area     */ 

	char tempa[100],tempb[20]; /* Used to parse output lines */

/* This is the number of maximum number of lines that need
	to be displayed.  */	
long LINES=NUM_OUTPUT;
 
	switch (message) 
	{ 

		case WM_LBUTTONDOWN:
				//User presses mouse get rid of window
				DestroyWindow(scroll);
			break;
			
		 case WM_CREATE :
			 
 		   	
			/* Get the handle of the client area's device context. */ 
 
			hdc = GetDC (scroll); 
 
	        /* Extract font dimensions from the text metrics. */ 
 
			GetTextMetrics (hdc, &tm); 
			xChar = tm.tmAveCharWidth; 
			xUpper = (tm.tmPitchAndFamily & 1 ? 3 : 2) * xChar/2; 
			yChar = tm.tmHeight + tm.tmExternalLeading; 
			
			/* Free the device context. */  
			ReleaseDC (scroll, hdc);  
	       /* 
		    * Set an arbitrary maximum width for client area. 
			* (xClientMax is the sum of the widths of 48 average 
			* lowercase letters and 12 uppercase letters.) 
			*/  
	        xClientMax = 48 * xChar + 12 * xUpper; 
		    return 0; 
 
    case WM_SIZE: 
 
        /* Retrieve the dimensions of the client area. */ 
 
        yClient = HIWORD (lParam); 
        xClient = LOWORD (lParam); 
 
        /* 
         * Determine the maximum vertical scrolling position. 
         * The two is added for extra space below the lines 
         * of text. 
         */ 
 
        yMax = max (0, LINES + 2 - yClient/yChar); 
 
        /* 
         * Make sure the current vertical scrolling position 
         * does not exceed the maximum. 
         */ 
 
        yPos = min (yPos, yMax); 
 
        /* 
         * Adjust the vertical scrolling range and scroll box 
         * position to reflect the new yMax and yPos values. 
         */ 
 
        si.cbSize = sizeof(si); 
        si.fMask  = SIF_RANGE | SIF_PAGE | SIF_POS; 
        si.nMin   = 0; 
        si.nMax   = yMax; 
        si.nPage  = yClient / yChar; 
        si.nPos   = yPos; 
        SetScrollInfo(scroll, SB_VERT, &si, TRUE); 
 
        /* 
         * Determine the maximum horizontal scrolling position. 
         * The two is added for extra space to the right of the 
         * lines of text. 
         */ 
 
        xMax = max (0, 2 + (xClientMax - xClient)/xChar); 
 
        /* 
         * Make sure the current horizontal scrolling position 
         * does not exceed the maximum. 
         */ 
 
        xPos = min (xPos, xMax); 
 
        /* 
         * Adjust the horizontal scrolling range and scroll box 
         * position to reflect the new xMax and xPos values. 
         */ 
 
        si.cbSize = sizeof(si); 
        si.fMask  = SIF_RANGE | SIF_PAGE | SIF_POS; 
        si.nMin   = 0; 
        si.nMax   = xMax; 
        si.nPage  = xClient / xChar; 
        si.nPos   = xPos; 
        SetScrollInfo(scroll, SB_HORZ, &si, TRUE); 
 
        return 0; 
 
    case WM_PAINT: 
 
        /* Prepare the window for painting. */ 
 
        hdc = BeginPaint(scroll, &ps); 
 
        /* 
         * Use the current vertical scrolling position and 
         * coordinates of the invalid rectangle to determine 
         * the range of new lines that should be drawn in the 
         * client area. 
         */ 
 
        FirstLine = max (0, yPos + ps.rcPaint.top/yChar - 1); 
        LastLine = min (LINES, yPos + ps.rcPaint.bottom/yChar); 
 
        /* Display these lines. */ 		
		for (i = FirstLine;i < LastLine;i++) 
		{ 
			x = xChar * (1 - xPos); 
		    y = yChar * (1 - yPos + i);
			strcpy(tempa,"Output Node : "); ltoa(i,tempb,10);
strcat(tempa,tempb);			
			strcat(tempa," Activation: "); 
			ConvertFloat(tempb,Net.output[i].activation,8);
			strcat(tempa,tempb);
			//Clear line
			TextOut(hdc,x,y,"                                            
        ",52);
			TextOut(hdc,x+50,y,"                                         
           ",52);
			TextOut(hdc, x, y, tempa, strlen(tempa)); 
		}  
 
        /* Indicate that painting is finished. */ 
 
        EndPaint(scroll, &ps);
        break;  
 
    case WM_VSCROLL: 

            switch(LOWORD (wParam)) { 
 
            /* User clicked the shaft above the scroll box. */ 
 
            case SB_PAGEUP: 
                 yInc = min(-1, -yClient / yChar); 
                 break; 
 
            /* User clicked the shaft below the scroll box. */ 
 
            case SB_PAGEDOWN: 
                 yInc = max(1, yClient / yChar); 
                 break; 
 
            /* User clicked the top arrow. */ 
 
            case SB_LINEUP: 
                 yInc = -1; 
                 break; 
 
            /* User clicked the bottom arrow. */ 
 
            case SB_LINEDOWN: 
                 yInc = 1; 
                 break; 
 
            /* User dragged the scroll box. */ 
 
            case SB_THUMBTRACK: 
                 yInc = HIWORD(wParam) - yPos; 
                 break; 
 
            default: 
                 yInc = 0; 
 
        } 
 
        /* 
         * If applying the vertical scrolling increment does not 
         * take the scrolling position out of the scrolling range, 
         * increment the scrolling position, adjust the position 
         * of the scroll box, and update the window. UpdateWindow 
         * sends the WM_PAINT message. 
         */ 
 
        if (yInc = max(-yPos, min(yInc, yMax - yPos))) { 
            yPos += yInc; 
            ScrollWindowEx(scroll, 0, -yChar * yInc, 
                (CONST RECT *) NULL, (CONST RECT *) NULL, 
                (HRGN) NULL, (LPRECT) NULL, SW_INVALIDATE); 
            si.cbSize = sizeof(si); 
            si.fMask  = SIF_POS; 
            si.nPos   = yPos; 
            SetScrollInfo(scroll, SB_VERT, &si, TRUE); 
            UpdateWindow (scroll); 
        } 
		
	} //End of switch(message)

	//Let Windows handle it..
	return DefWindowProc(scroll,message,wParam,lParam);
} //End of DisplayOutputNodes


LONG FAR PASCAL DisplayI2H(HWND scroll, unsigned int message,
						unsigned int wParam, LONG lParam)
/* Handles incoming messages for the scrolling window displaying 
Input to Hidden Weights. */
{
	HDC hdc;  
	PAINTSTRUCT ps; 
	TEXTMETRIC tm; 
	SCROLLINFO si; 
 
	/* These variables are required to display text. */ 
 
	static int xClient;     /* width of client area                  */ 
	static int yClient;     /* height of client area                 */ 
	static int xClientMax;  /* maximum width of client area          */ 
 
	static int xChar;       /* horizontal scrolling unit             */ 
	static int yChar;       /* vertical scrolling unit               */ 
	static int xUpper;      /* average width of uppercase letters    */ 
 
	static int xPos;        /* current horizontal scrolling position */ 
	static int yPos;        /* current vertical scrolling position   */ 
 
	static int xMax;        /* maximum horiz. scrolling position     */ 
	static int yMax;        /* maximum vert. scrolling position      */ 
 
	int yInc;               /* vertical scrolling increment          */ 
 
	long i;                  /* loop counter                          */ 
	int x, y;               /* horiz. and vert. printing coords      */ 
 
	long FirstLine;          /* first line in the invalidated area    */ 
	long LastLine;           /* last line in the invalidated area     */ 

	char tempa[100],tempb[20]; /* Used to parse output lines */
	div_t div_result;		/* Division result structure */
	long InputCount;
	long HiddenCount;



/* This is the number of maximum number of lines that need
	to be displayed.  */	
long LINES=NUM_INPUT*NUM_HIDDEN;
 
	switch (message) 
	{ 

		case WM_LBUTTONDOWN:
				//User presses mouse get rid of window
				DestroyWindow(scroll);
			break;
			
		 case WM_CREATE :
			 
 		   	
			/* Get the handle of the client area's device context. */ 
 
			hdc = GetDC (scroll); 
 
	        /* Extract font dimensions from the text metrics. */ 
 
			GetTextMetrics (hdc, &tm); 
			xChar = tm.tmAveCharWidth; 
			xUpper = (tm.tmPitchAndFamily & 1 ? 3 : 2) * xChar/2; 
			yChar = tm.tmHeight + tm.tmExternalLeading; 
			
			/* Free the device context. */  
			ReleaseDC (scroll, hdc);  
	       /* 
		    * Set an arbitrary maximum width for client area. 
			* (xClientMax is the sum of the widths of 48 average 
			* lowercase letters and 12 uppercase letters.) 
			*/  
	        xClientMax = 48 * xChar + 12 * xUpper; 
		    return 0; 
 
    case WM_SIZE: 
 
        /* Retrieve the dimensions of the client area. */ 
 
        yClient = HIWORD (lParam); 
        xClient = LOWORD (lParam); 
 
        /* 
         * Determine the maximum vertical scrolling position. 
         * The two is added for extra space below the lines 
         * of text. 
         */ 
 
        yMax = max (0, LINES + 2 - yClient/yChar); 
 
        /* 
         * Make sure the current vertical scrolling position 
         * does not exceed the maximum. 
         */ 
 
        yPos = min (yPos, yMax); 
 
        /* 
         * Adjust the vertical scrolling range and scroll box 
         * position to reflect the new yMax and yPos values. 
         */ 
 
        si.cbSize = sizeof(si); 
        si.fMask  = SIF_RANGE | SIF_PAGE | SIF_POS; 
        si.nMin   = 0; 
        si.nMax   = yMax; 
        si.nPage  = yClient / yChar; 
        si.nPos   = yPos; 
        SetScrollInfo(scroll, SB_VERT, &si, TRUE); 
 
        /* 
         * Determine the maximum horizontal scrolling position. 
         * The two is added for extra space to the right of the 
         * lines of text. 
         */ 
 
        xMax = max (0, 2 + (xClientMax - xClient)/xChar); 
 
        /* 
         * Make sure the current horizontal scrolling position 
         * does not exceed the maximum. 
         */ 
 
        xPos = min (xPos, xMax); 
 
        /* 
         * Adjust the horizontal scrolling range and scroll box 
         * position to reflect the new xMax and xPos values. 
         */ 
 
        si.cbSize = sizeof(si); 
        si.fMask  = SIF_RANGE | SIF_PAGE | SIF_POS; 
        si.nMin   = 0; 
        si.nMax   = xMax; 
        si.nPage  = xClient / xChar; 
        si.nPos   = xPos; 
        SetScrollInfo(scroll, SB_HORZ, &si, TRUE); 
 
        return 0; 
 
    case WM_PAINT: 
 
        /* Prepare the window for painting. */ 
 
        hdc = BeginPaint(scroll, &ps); 
 
        /* 
         * Use the current vertical scrolling position and 
         * coordinates of the invalid rectangle to determine 
         * the range of new lines that should be drawn in the 
         * client area. 
         */ 
 
        FirstLine = max (0, yPos + ps.rcPaint.top/yChar - 1); 
        LastLine = min (LINES, yPos + ps.rcPaint.bottom/yChar); 
 
        /* Display these lines. */ 		
		for (i = FirstLine;i < LastLine;i++) 
		{ 
			div_result = div( i, NUM_HIDDEN);
			InputCount=div_result.quot;
			HiddenCount=div_result.rem;
			x = xChar * (1 - xPos); 
		    y = yChar * (1 - yPos + i);
			strcpy(tempa,"Input Node: "); ltoa(InputCount,tempb,10);
strcat(tempa,tempb);
			strcat(tempa," Hidden Node: "); ltoa(HiddenCount,tempb,10);
strcat(tempa,tempb);
			strcat(tempa," Weight: "); 
			ConvertFloat(tempb,Net.i2h[InputCount][HiddenCount],8);
			strcat(tempa,tempb);
			//Clear line
			TextOut(hdc,x,y,"                                            
        ",52);
			TextOut(hdc,x+50,y,"                                         
           ",52);
			TextOut(hdc, x, y, tempa, strlen(tempa)); 
		}  
 
        /* Indicate that painting is finished. */ 
 
        EndPaint(scroll, &ps);
        break;  
 
    case WM_VSCROLL: 

            switch(LOWORD (wParam)) { 
 
            /* User clicked the shaft above the scroll box. */ 
 
            case SB_PAGEUP: 
                 yInc = min(-1, -yClient / yChar); 
                 break; 
 
            /* User clicked the shaft below the scroll box. */ 
 
            case SB_PAGEDOWN: 
                 yInc = max(1, yClient / yChar); 
                 break; 
 
            /* User clicked the top arrow. */ 
 
            case SB_LINEUP: 
                 yInc = -1; 
                 break; 
 
            /* User clicked the bottom arrow. */ 
 
            case SB_LINEDOWN: 
                 yInc = 1; 
                 break; 
 
            /* User dragged the scroll box. */ 
 
            case SB_THUMBTRACK: 
                 yInc = HIWORD(wParam) - yPos; 
                 break; 
 
            default: 
                 yInc = 0; 
 
        } 
 
        /* 
         * If applying the vertical scrolling increment does not 
         * take the scrolling position out of the scrolling range, 
         * increment the scrolling position, adjust the position 
         * of the scroll box, and update the window. UpdateWindow 
         * sends the WM_PAINT message. 
         */ 
 
        if (yInc = max(-yPos, min(yInc, yMax - yPos))) { 
            yPos += yInc; 
            ScrollWindowEx(scroll, 0, -yChar * yInc, 
                (CONST RECT *) NULL, (CONST RECT *) NULL, 
                (HRGN) NULL, (LPRECT) NULL, SW_INVALIDATE); 
            si.cbSize = sizeof(si); 
            si.fMask  = SIF_POS; 
            si.nPos   = yPos; 
            SetScrollInfo(scroll, SB_VERT, &si, TRUE); 
            UpdateWindow (scroll); 
        } 
		
	} //End of switch(message)

	//Let Windows handle it..
	return DefWindowProc(scroll,message,wParam,lParam);
} //End of DisplayI2H


LONG FAR PASCAL DisplayH2O(HWND scroll, unsigned int message,
						unsigned int wParam, LONG lParam)
/* Handles incoming messages for the scrolling window displaying 
Hidden to Output Weights. */
{
	HDC hdc;  
	PAINTSTRUCT ps; 
	TEXTMETRIC tm; 
	SCROLLINFO si; 
 
	/* These variables are required to display text. */ 
 
	static int xClient;     /* width of client area                  */ 
	static int yClient;     /* height of client area                 */ 
	static int xClientMax;  /* maximum width of client area          */ 
 
	static int xChar;       /* horizontal scrolling unit             */ 
	static int yChar;       /* vertical scrolling unit               */ 
	static int xUpper;      /* average width of uppercase letters    */ 
 
	static int xPos;        /* current horizontal scrolling position */ 
	static int yPos;        /* current vertical scrolling position   */ 
 
	static int xMax;        /* maximum horiz. scrolling position     */ 
	static int yMax;        /* maximum vert. scrolling position      */ 
 
	int yInc;               /* vertical scrolling increment          */ 
 
	long i;                  /* loop counter                          */ 
	int x, y;               /* horiz. and vert. printing coords      */ 
 
	long FirstLine;          /* first line in the invalidated area    */ 
	long LastLine;           /* last line in the invalidated area     */ 

	char tempa[100],tempb[20]; /* Used to parse output lines */
	div_t div_result;		/* Division result structure */
	long HiddenCount; 
	long OutputCount;



/* This is the number of maximum number of lines that need
	to be displayed.  */	
long LINES=NUM_HIDDEN*NUM_OUTPUT;
 
	switch (message) 
	{ 

		case WM_LBUTTONDOWN:
				//User presses mouse get rid of window
				DestroyWindow(scroll);
			break;
			
		 case WM_CREATE :
			 
 		   	
			/* Get the handle of the client area's device context. */ 
 
			hdc = GetDC (scroll); 
 
	        /* Extract font dimensions from the text metrics. */ 
 
			GetTextMetrics (hdc, &tm); 
			xChar = tm.tmAveCharWidth; 
			xUpper = (tm.tmPitchAndFamily & 1 ? 3 : 2) * xChar/2; 
			yChar = tm.tmHeight + tm.tmExternalLeading; 
			
			/* Free the device context. */  
			ReleaseDC (scroll, hdc);  
	       /* 
		    * Set an arbitrary maximum width for client area. 
			* (xClientMax is the sum of the widths of 48 average 
			* lowercase letters and 12 uppercase letters.) 
			*/  
	        xClientMax = 48 * xChar + 12 * xUpper; 
		    return 0; 
 
    case WM_SIZE: 
 
        /* Retrieve the dimensions of the client area. */ 
 
        yClient = HIWORD (lParam); 
        xClient = LOWORD (lParam); 
 
        /* 
         * Determine the maximum vertical scrolling position. 
         * The two is added for extra space below the lines 
         * of text. 
         */ 
 
        yMax = max (0, LINES + 2 - yClient/yChar); 
 
        /* 
         * Make sure the current vertical scrolling position 
         * does not exceed the maximum. 
         */ 
 
        yPos = min (yPos, yMax); 
 
        /* 
         * Adjust the vertical scrolling range and scroll box 
         * position to reflect the new yMax and yPos values. 
         */ 
 
        si.cbSize = sizeof(si); 
        si.fMask  = SIF_RANGE | SIF_PAGE | SIF_POS; 
        si.nMin   = 0; 
        si.nMax   = yMax; 
        si.nPage  = yClient / yChar; 
        si.nPos   = yPos; 
        SetScrollInfo(scroll, SB_VERT, &si, TRUE); 
 
        /* 
         * Determine the maximum horizontal scrolling position. 
         * The two is added for extra space to the right of the 
         * lines of text. 
         */ 
 
        xMax = max (0, 2 + (xClientMax - xClient)/xChar); 
 
        /* 
         * Make sure the current horizontal scrolling position 
         * does not exceed the maximum. 
         */ 
 
        xPos = min (xPos, xMax); 
 
        /* 
         * Adjust the horizontal scrolling range and scroll box 
         * position to reflect the new xMax and xPos values. 
         */ 
 
        si.cbSize = sizeof(si); 
        si.fMask  = SIF_RANGE | SIF_PAGE | SIF_POS; 
        si.nMin   = 0; 
        si.nMax   = xMax; 
        si.nPage  = xClient / xChar; 
        si.nPos   = xPos; 
        SetScrollInfo(scroll, SB_HORZ, &si, TRUE); 
 
        return 0; 
 
    case WM_PAINT: 
 
        /* Prepare the window for painting. */ 
 
        hdc = BeginPaint(scroll, &ps); 
 
        /* 
         * Use the current vertical scrolling position and 
         * coordinates of the invalid rectangle to determine 
         * the range of new lines that should be drawn in the 
         * client area. 
         */ 
 
        FirstLine = max (0, yPos + ps.rcPaint.top/yChar - 1); 
        LastLine = min (LINES, yPos + ps.rcPaint.bottom/yChar); 
 
        /* Display these lines. */ 		
		for (i = FirstLine;i < LastLine;i++) 
		{ 
			div_result = div( i, NUM_OUTPUT);
			HiddenCount=div_result.quot;
			OutputCount=div_result.rem;
			x = xChar * (1 - xPos); 
		    y = yChar * (1 - yPos + i);
			strcpy(tempa,"Hidden Node: "); ltoa(HiddenCount,tempb,10);
strcat(tempa,tempb);
			strcat(tempa," Output Node: "); ltoa(OutputCount,tempb,10);
strcat(tempa,tempb);
			strcat(tempa," Weight: "); 
			ConvertFloat(tempb,Net.h2o[HiddenCount][OutputCount],8);
			strcat(tempa,tempb);
			//Clear line
			TextOut(hdc,x,y,"                                            
        ",52);
			TextOut(hdc,x+50,y,"                                         
           ",52);
			TextOut(hdc, x, y, tempa, strlen(tempa)); 
		}  
 
        /* Indicate that painting is finished. */ 
 
        EndPaint(scroll, &ps);
        break;  
 
    case WM_VSCROLL: 

            switch(LOWORD (wParam)) { 
 
            /* User clicked the shaft above the scroll box. */ 
 
            case SB_PAGEUP: 
                 yInc = min(-1, -yClient / yChar); 
                 break; 
 
            /* User clicked the shaft below the scroll box. */ 
 
            case SB_PAGEDOWN: 
                 yInc = max(1, yClient / yChar); 
                 break; 
 
            /* User clicked the top arrow. */ 
 
            case SB_LINEUP: 
                 yInc = -1; 
                 break; 
 
            /* User clicked the bottom arrow. */ 
 
            case SB_LINEDOWN: 
                 yInc = 1; 
                 break; 
 
            /* User dragged the scroll box. */ 
 
            case SB_THUMBTRACK: 
                 yInc = HIWORD(wParam) - yPos; 
                 break; 
 
            default: 
                 yInc = 0; 
 
        } 
 
        /* 
         * If applying the vertical scrolling increment does not 
         * take the scrolling position out of the scrolling range, 
         * increment the scrolling position, adjust the position 
         * of the scroll box, and update the window. UpdateWindow 
         * sends the WM_PAINT message. 
         */ 
 
        if (yInc = max(-yPos, min(yInc, yMax - yPos))) { 
            yPos += yInc; 
            ScrollWindowEx(scroll, 0, -yChar * yInc, 
                (CONST RECT *) NULL, (CONST RECT *) NULL, 
                (HRGN) NULL, (LPRECT) NULL, SW_INVALIDATE); 
            si.cbSize = sizeof(si); 
            si.fMask  = SIF_POS; 
            si.nPos   = yPos; 
            SetScrollInfo(scroll, SB_VERT, &si, TRUE); 
            UpdateWindow (scroll); 
        } 
		
	} //End of switch(message)

	//Let Windows handle it..
	return DefWindowProc(scroll,message,wParam,lParam);
} //End of DisplayH2O


LONG FAR PASCAL DisplayDesired(HWND scroll, unsigned int message,
						unsigned int wParam, LONG lParam)
/* Handles incoming messages for the scrolling window displaying 
desired output of the network. */
{
	HDC hdc;  
	PAINTSTRUCT ps; 
	TEXTMETRIC tm; 
	SCROLLINFO si; 
 
	/* These variables are required to display text. */ 
 
	static int xClient;     /* width of client area                  */ 
	static int yClient;     /* height of client area                 */ 
	static int xClientMax;  /* maximum width of client area          */ 
 
	static int xChar;       /* horizontal scrolling unit             */ 
	static int yChar;       /* vertical scrolling unit               */ 
	static int xUpper;      /* average width of uppercase letters    */ 
 
	static int xPos;        /* current horizontal scrolling position */ 
	static int yPos;        /* current vertical scrolling position   */ 
 
	static int xMax;        /* maximum horiz. scrolling position     */ 
	static int yMax;        /* maximum vert. scrolling position      */ 
 
	int yInc;               /* vertical scrolling increment          */ 
 
	long i;                  /* loop counter                          */ 
	int x, y;               /* horiz. and vert. printing coords      */ 
 
	long FirstLine;          /* first line in the invalidated area    */ 
	long LastLine;           /* last line in the invalidated area     */ 

	char tempa[100],tempb[20]; /* Used to parse output lines */
	div_t div_result;		/* Division result structure */
	long SetCount;          /* Keep track of what input set */
	long NodeCount;			/* Keep track of what node in the input set */

/* This is the number of maximum number of lines that need
	to be displayed.  */	
long LINES=NUM_OUTPUT*INPUT_SET;
 
	switch (message) 
	{ 

		case WM_LBUTTONDOWN:
				//User presses mouse get rid of window
				DestroyWindow(scroll);
			break;
			
		 case WM_CREATE :
			 
 		   	
			/* Get the handle of the client area's device context. */ 
 
			hdc = GetDC (scroll); 
 
	        /* Extract font dimensions from the text metrics. */ 
 
			GetTextMetrics (hdc, &tm); 
			xChar = tm.tmAveCharWidth; 
			xUpper = (tm.tmPitchAndFamily & 1 ? 3 : 2) * xChar/2; 
			yChar = tm.tmHeight + tm.tmExternalLeading; 
			
			/* Free the device context. */  
			ReleaseDC (scroll, hdc);  
	       /* 
		    * Set an arbitrary maximum width for client area. 
			* (xClientMax is the sum of the widths of 48 average 
			* lowercase letters and 12 uppercase letters.) 
			*/  
	        xClientMax = 48 * xChar + 12 * xUpper; 
		    return 0; 
 
    case WM_SIZE: 
 
        /* Retrieve the dimensions of the client area. */ 
 
        yClient = HIWORD (lParam); 
        xClient = LOWORD (lParam); 
 
        /* 
         * Determine the maximum vertical scrolling position. 
         * The two is added for extra space below the lines 
         * of text. 
         */ 
 
        yMax = max (0, LINES + 2 - yClient/yChar); 
 
        /* 
         * Make sure the current vertical scrolling position 
         * does not exceed the maximum. 
         */ 
 
        yPos = min (yPos, yMax); 
 
        /* 
         * Adjust the vertical scrolling range and scroll box 
         * position to reflect the new yMax and yPos values. 
         */ 
 
        si.cbSize = sizeof(si); 
        si.fMask  = SIF_RANGE | SIF_PAGE | SIF_POS; 
        si.nMin   = 0; 
        si.nMax   = yMax; 
        si.nPage  = yClient / yChar; 
        si.nPos   = yPos; 
        SetScrollInfo(scroll, SB_VERT, &si, TRUE); 
 
        /* 
         * Determine the maximum horizontal scrolling position. 
         * The two is added for extra space to the right of the 
         * lines of text. 
         */ 
 
        xMax = max (0, 2 + (xClientMax - xClient)/xChar); 
 
        /* 
         * Make sure the current horizontal scrolling position 
         * does not exceed the maximum. 
         */ 
 
        xPos = min (xPos, xMax); 
 
        /* 
         * Adjust the horizontal scrolling range and scroll box 
         * position to reflect the new xMax and xPos values. 
         */ 
 
        si.cbSize = sizeof(si); 
        si.fMask  = SIF_RANGE | SIF_PAGE | SIF_POS; 
        si.nMin   = 0; 
        si.nMax   = xMax; 
        si.nPage  = xClient / xChar; 
        si.nPos   = xPos; 
        SetScrollInfo(scroll, SB_HORZ, &si, TRUE); 
 
        return 0; 
 
    case WM_PAINT: 
 
        /* Prepare the window for painting. */ 
 
        hdc = BeginPaint(scroll, &ps); 
 
        /* 
         * Use the current vertical scrolling position and 
         * coordinates of the invalid rectangle to determine 
         * the range of new lines that should be drawn in the 
         * client area. 
         */ 
 
        FirstLine = max (0, yPos + ps.rcPaint.top/yChar - 1); 
        LastLine = min (LINES, yPos + ps.rcPaint.bottom/yChar); 
 
        /* Display these lines. */ 		
		for (i = FirstLine;i < LastLine;i++) 
		{ 
			div_result = div( i, NUM_OUTPUT);
			SetCount=div_result.quot;
			NodeCount=div_result.rem;
			x = xChar * (1 - xPos); 
		    y = yChar * (1 - yPos + i);
			strcpy(tempa,"Input Set: "); ltoa(SetCount,tempb,10);
strcat(tempa,tempb);
			strcat(tempa," OutputNode: "); ltoa(NodeCount,tempb,10);
strcat(tempa,tempb);
			strcat(tempa," DesiredActivation: "); 
			ConvertFloat(tempb,DESIRED_OUTPUT[SetCount][NodeCount],8);
			strcat(tempa,tempb);
			TextOut(hdc,x,y,"                                            
        ",52);
			TextOut(hdc,x+50,y,"                                         
           ",52);
			TextOut(hdc, x, y, tempa, strlen(tempa)); 
		}  
 
        /* Indicate that painting is finished. */ 
 
        EndPaint(scroll, &ps);
        break;  
 
    case WM_VSCROLL: 

            switch(LOWORD (wParam)) { 
 
            /* User clicked the shaft above the scroll box. */ 
 
            case SB_PAGEUP: 
                 yInc = min(-1, -yClient / yChar); 
                 break; 
 
            /* User clicked the shaft below the scroll box. */ 
 
            case SB_PAGEDOWN: 
                 yInc = max(1, yClient / yChar); 
                 break; 
 
            /* User clicked the top arrow. */ 
 
            case SB_LINEUP: 
                 yInc = -1; 
                 break; 
 
            /* User clicked the bottom arrow. */ 
 
            case SB_LINEDOWN: 
                 yInc = 1; 
                 break; 
 
            /* User dragged the scroll box. */ 
 
            case SB_THUMBTRACK: 
                 yInc = HIWORD(wParam) - yPos; 
                 break; 
 
            default: 
                 yInc = 0; 
 
        } 
 
        /* 
         * If applying the vertical scrolling increment does not 
         * take the scrolling position out of the scrolling range, 
         * increment the scrolling position, adjust the position 
         * of the scroll box, and update the window. UpdateWindow 
         * sends the WM_PAINT message. 
         */ 
 
        if (yInc = max(-yPos, min(yInc, yMax - yPos))) { 
            yPos += yInc; 
            ScrollWindowEx(scroll, 0, -yChar * yInc, 
                (CONST RECT *) NULL, (CONST RECT *) NULL, 
                (HRGN) NULL, (LPRECT) NULL, SW_INVALIDATE); 
            si.cbSize = sizeof(si); 
            si.fMask  = SIF_POS; 
            si.nPos   = yPos; 
            SetScrollInfo(scroll, SB_VERT, &si, TRUE); 
            UpdateWindow (scroll); 
        } 
		
	} //End of switch(message)

	//Let Windows handle it..
	return DefWindowProc(scroll,message,wParam,lParam);
} //End of DisplayDesired

inline void ConvertFloat(char *string,double source,int precision)
/* Tiresome way of going about converting a float to
a string. */
{
   int  decimal, sign,i,len;
   char *buffer;
   char temp[100];
   
   buffer = _fcvt( source, precision, &decimal, &sign );   
   if (sign)
	   strcpy(string,"-");
   else 
	   strcpy(string," ");
	if (decimal<=0)
	{
		strcat(string,"0.");
		len=strlen(buffer);
		for (i=0; i<(precision-len); i++)
			strcat(string,"0");
		strcat(string,buffer);
	}
	else
	{
		strcpy(temp,buffer);
		temp[decimal]='\0';
		strcat(string,temp);
		strcat(string,".");
		strcat(string,&buffer[decimal]);
	} 
} //End of ConvertFloat


void Capture(HWND parent)
/* Takes input from VFW API (camera) and will convert
it to bitmap data.  It will then run the image
through the network displaying network output. 
>>NOTE:  8 bit greyscale!!!<< */
{
	HWND win;
	HWND ghWndCap ; //Handle to capture window
	BOOL ok;
	HBITMAP hbmp;
	PBYTE lpvBits;
	BITMAPINFO bi;
	BITMAPINFO *pbi;
	DWORD i;
	HDC hdc;
	HPALETTE hpal;
	int xdim=160,ydim=120;
	int a,b;
	int NetCount;
	MSG msg;


	if (!NET_INIT)
	{
		MessageBox(parent,"Network Not Initialized!","Video Capture",
			MB_ICONHAND);
		return;
	}

	//Get width of area to recognize
	ZeroMemory(INPUTSTRING,strlen(INPUTSTRING));
	UserInput("Enter WIDTH of capture area:",300,100,parent);
	while (FLAGWIN!=NULL) 
	{
		GetMessage(&msg,NULL,0,0);
		TranslateMessage(&msg);
		DispatchMessage(&msg); 
	} 
	xdim=atoi(INPUTSTRING);
	if (xdim>160)
	{
		MessageBox(parent,"X dimension must be 160 or less!",
			"Video Capture",MB_ICONSTOP);
		return;
	}

	//Get Height of area to recognize
	ZeroMemory(INPUTSTRING,strlen(INPUTSTRING));
	UserInput("Enter HEIGHT of capture area",300,100,parent);
	while (FLAGWIN!=NULL) 
	{
		GetMessage(&msg,NULL,0,0);
		TranslateMessage(&msg);
		DispatchMessage(&msg); 
	} 
	ydim=atoi(INPUTSTRING);
	if (ydim>120)
	{
		MessageBox(parent,"Y dimension must be 120 or less!",
			"Video Capture",MB_ICONSTOP);
		return;
	}

	if (xdim*ydim>NUM_INPUT)
	{
		MessageBox(parent,"Image size larger than input layer of network!"
			,"Video Capture",MB_ICONSTOP);
		return;
	}
  
	win=CreateWindow("ChildClass","Video Capture Window",
		WS_OVERLAPPEDWINDOW,0,0,320, 
		240,parent,NULL,NULL,NULL);

	ghWndCap = capCreateCaptureWindow((LPTSTR)TEXT("Cap Win"),
			WS_CHILD | WS_VISIBLE,
			160-(xdim/2),120-(ydim/2), xdim, ydim,
			(HWND) win, (int) 0) ;

	/* Display the window before attaching it to camera since it may
	take time to connect and the user wants to see something happen. */
	ShowWindow(win,1);	
	
	/* Note that the QuickCam is driver 0 on my system.
	This could change if I had another video driver installed. 
	--> Word of caution: If the program hangs or crashes while you
	are connected to the capture driver you will need to reboot
	the machine before you can reconnect again. why?? don't know.. */
	ok=capDriverConnect(ghWndCap, 0); 

	if (!ok)
	{
		MessageBox(parent,"Unable to connect to QuickCam Driver!","Video
Capture",MB_ICONWARNING);
		return;
	}

	//Set capture rate and start incoming stream
	capPreviewRate(ghWndCap, 30);
	capPreview(ghWndCap, TRUE);	

	//Create DC to parent Window
	hdc=GetDC(ghWndCap);

	//Now allocate space for bits
	if ((lpvBits = (PBYTE)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,19200)) == NULL) 
	{
		MessageBox(parent, "Failed in Memory Allocation for lpvBits!", "Video
Capture", MB_ICONWARNING);
		return;
	}

	//Allocate space for bitmap header and palette
	if ((pbi=(PBITMAPINFO)malloc(sizeof(BITMAPINFO)+(sizeof(RGBQUAD)*256)))==NULL)
	{
		MessageBox(parent,"Failed to allocate memory for bitmap!","Video
Capture",
			MB_ICONWARNING);
		return;
	}
	
	//Loop here continuosly grabbing frames
	do
	{	 
		ZeroMemory(pbi,(sizeof(BITMAPINFO)+(sizeof(RGBQUAD)*256)));
		ZeroMemory(lpvBits,sizeof(BYTE)*19200);

		//Grab a frame from the video stream
		if (!capGrabFrameNoStop(ghWndCap))
		{
			MessageBox(parent,"Unable to grab frame from input stream!",
				"Video Capture",MB_ICONWARNING);
			capDriverDisconnect(ghWndCap);
			if (lpvBits!=NULL)
					GlobalFree(lpvBits);
			if (hbmp!=NULL)
				DeleteObject(hbmp);
			if (pbi!=NULL)
				free(pbi);
			EmptyClipboard();
			CloseClipboard();
			ReleaseDC(hdc,ghWndCap);
			return;
		}

		//Copy the frame to the clipboard
		if (!capEditCopy(ghWndCap))
		{
			MessageBox(parent,"Cannot copy bitmap to clipboard!","Video
Capture",
				MB_ICONWARNING);
			capDriverDisconnect(ghWndCap);
			if (lpvBits!=NULL)
					GlobalFree(lpvBits);
			if (hbmp!=NULL)
				DeleteObject(hbmp);
			if (pbi!=NULL)
				free(pbi);
			EmptyClipboard();
			CloseClipboard();
			ReleaseDC(hdc,ghWndCap);
			return;
		}

		//Open Clipboard and extract the frame and associated palette.
		while (!OpenClipboard(NULL));	
		hbmp=GetClipboardData(CF_BITMAP);
		hpal=GetClipboardData(CF_PALETTE);

		if (hbmp==NULL | hpal==NULL)
		{
			MessageBox(parent,"Unable to Create Bitmap!","Video Capture"
			,MB_ICONWARNING);
			capDriverDisconnect(ghWndCap);
			if (lpvBits!=NULL)
					GlobalFree(lpvBits);
			if (hbmp!=NULL)
				DeleteObject(hbmp);
			if (pbi!=NULL)
				free(pbi);
			EmptyClipboard();
			CloseClipboard();
			ReleaseDC(hdc,ghWndCap);
			return;
		}

		/* Now we need to extract raw pixel data from Bitmap and put it into
		input layer of network. */

		//Select the palette into the device context.
		SelectPalette(
		hdc,
		hpal,
		FALSE //FALSE forces it into foreground mode
		);
	
		//This info must be filled in order to extract pixel data..
		bi.bmiHeader.biSize=0x28;
		bi.bmiHeader.biBitCount=0x0;	
		bi.bmiHeader.biClrImportant=0x0; 

		/* Call GetDIBits to return the raw data of the image since
		we can't look inside the handle ourselves.  If number of scan
		lines is set to 0 DIBits returns the entire image. */

		i=GetDIBits(
			hdc,	// handle of device context 
			hbmp,	// handle of bitmap 
			0,	// first scan line to set in destination bitmap  
			0,	// number of scan lines to copy 
			NULL,	// address of array for bitmap bits 
			&bi,	// address of structure with bitmap data 
			DIB_RGB_COLORS	// RGB or palette index 	
			); 
		
		ZeroMemory(pbi,sizeof(BITMAPINFO)+(sizeof(RGBQUAD)*256));
		memcpy(pbi,&bi,sizeof(BITMAPINFO));		

		 i=GetDIBits(
			hdc,	// handle of device context 
			hbmp,	// handle of bitmap 
			0,	// first scan line to set in destination bitmap  
			120,	// number of scan lines to copy 
			(LPVOID)lpvBits,	// address of array for bitmap bits 
			pbi,	// address of structure with bitmap data 
			DIB_RGB_COLORS	// RGB or palette index 
			);  	

		//Check to make sure input layer of net is large enough
		if (xdim*ydim>NUM_INPUT)
		{
			MessageBox(parent,"Input Layer of Network too small!"
				,"Recognize Image",MB_ICONSTOP);
			capDriverDisconnect(ghWndCap);
			if (lpvBits!=NULL)
					GlobalFree(lpvBits);
			if (hbmp!=NULL)
				DeleteObject(hbmp);
			if (pbi!=NULL)
				free(pbi);
			EmptyClipboard();
			CloseClipboard();
			ReleaseDC(hdc,ghWndCap);
			return;
		}

		/* Copy the image into the neural network and compute the output. */
		NetCount=0;
		for (b=ydim; b>=1; b--)
			for (a=0; a<xdim; a++)
			{
			
Net.input[0][NetCount].activation=(pbi->bmiColors[lpvBits[(19200-(b*160))+a]].rgbBlue
/255.0);
				NetCount++;
			}
		
		/* Here we go.. Compute calculates network output! */
		Compute(0);	 

		GetMessage(&msg,NULL,0,0);
		TranslateMessage(&msg);
		DispatchMessage(&msg); //return control to Windows

		//Display Output Activations
		ViewInputActivations(parent);
		ViewOutputActivations(parent);

		//Clean up the clipboard
		EmptyClipboard();
		CloseClipboard();
	
	} while (MessageBox(parent,"Continue?","Recognize Image",MB_YESNO)==IDYES);

	//Disconnect from camera
	capDriverDisconnect(ghWndCap);

	if (lpvBits!=NULL)
		GlobalFree(lpvBits);
	if (hbmp!=NULL)
		DeleteObject(hbmp);	
	if (pbi!=NULL)
		free(pbi);	
	ReleaseDC(hdc,ghWndCap);
} //END OF CAPTURE!!


void WhatISee(HWND parent)
/* This function does almost the same thing as the capture function
except instead of feeding the image into the network it will instead
write the bits into a log file.  In this way you can manually look
at what the camera "sees". */
{		
	HWND ghWndCap; 
	BOOL ok;
	HBITMAP hbmp;
	FILE *file;
	PBYTE lpvBits;
	BITMAPINFO bi;
	PBITMAPINFO pbi;
	DWORD i;
	HDC hdc;
	HPALETTE hpal;
	OPENFILENAME ofn;
	char filename[80]="";
	int xdim=160,ydim=120;
	int a,b;
	MSG msg;

	//Get width of area to capture
	ZeroMemory(INPUTSTRING,strlen(INPUTSTRING));
	UserInput("Enter WIDTH of capture area:",300,100,parent);
	while (FLAGWIN!=NULL) 
	{
		GetMessage(&msg,NULL,0,0);
		TranslateMessage(&msg);
		DispatchMessage(&msg); 
	} 
	xdim=atoi(INPUTSTRING);
	if (xdim>160)
	{
		MessageBox(parent,"X dimension must be 160 or less!",
			"Video Capture",MB_ICONSTOP);
		return;
	}  

	//Get Height of area to capture
	ZeroMemory(INPUTSTRING,strlen(INPUTSTRING));
	UserInput("Enter HEIGHT of capture area",300,100,parent);
	while (FLAGWIN!=NULL) 
	{
		GetMessage(&msg,NULL,0,0);
		TranslateMessage(&msg);
		DispatchMessage(&msg); 
	} 
	ydim=atoi(INPUTSTRING);
	if (ydim>120)
	{
		MessageBox(parent,"Y dimension must be 120 or less!",
			"Video Capture",MB_ICONSTOP);
		return;
	}

	//Create a window to be connected with capture window
	UserInput("Video Capture Window",320,240,parent);
	
  
	ghWndCap = capCreateCaptureWindow((LPTSTR)TEXT("Cap Win"),
			WS_CHILD | WS_VISIBLE,
			160-(xdim/2), 120-(ydim/2), xdim, ydim,
			(HWND) FLAGWIN, (int) 0);

	
	/* Note that the QuickCam is driver 0 on my system.
	This could change if I had another video driver installed. 
	--> Word of caution: If the program hangs or crashes while you
	are connected to the capture driver you will need to reboot
	the machine before you can reconnect again. why?? don't know.. */
	ok=capDriverConnect(ghWndCap, 0); 

	if (!ok)
	{
		MessageBox(parent,"Unable to connect to QuickCam Driver!","Video
Capture",MB_ICONWARNING);
		return;
	}

	//Create DC to capture window
	hdc=GetDC(ghWndCap);

	//Set capture rate and start incoming stream
	capPreviewRate(ghWndCap, 90);
	capPreview(ghWndCap, TRUE);	

	do
	{ //Wait here until user closes window

		GetMessage(&msg,NULL,0,0);
		TranslateMessage(&msg);

		//Grab a frame from the video stream
		capGrabFrameNoStop(ghWndCap);

		//Copy the frame to the clipboard
		capEditCopy(ghWndCap);

		DispatchMessage(&msg); 
	} while (FLAGWIN!=NULL);

	/* Disconnect from camera immediately, we don't really need
	to be connected anymore and it's safer. */
	capDriverDisconnect(ghWndCap);

	//Open Clipboard and extract the frame and associated palette.
	while (!OpenClipboard(NULL));	
	hbmp=GetClipboardData(CF_BITMAP);
	hpal=GetClipboardData(CF_PALETTE);

	if (hbmp==NULL)
	{
		MessageBox(parent,"Unable to Create Bitmap!","Video Capture"
		,MB_ICONWARNING);
		return;
	}

	if (hpal==NULL)
	{
		MessageBox(parent,"Unable to Create Bitmap Palette!","Video Capture",
			MB_ICONWARNING);
		return;
	}

	//Get filename		
	// Initialize OPENFILENAME
	ofn.lStructSize = sizeof(OPENFILENAME);
	ofn.hInstance=NULL;
	ofn.hwndOwner = parent;
	ofn.lpstrFile = filename;
	ofn.nMaxFile = sizeof(filename);
	ofn.lpstrFilter = "All\0*.*\0Image Log File\0*.LOG\0";
	ofn.lpstrCustomFilter=NULL;
	ofn.nFilterIndex = 2;
	ofn.lpstrFileTitle = NULL;
	ofn.nMaxFileTitle = 0;
	
	ofn.lpstrInitialDir = NULL;
	ofn.lpstrTitle="Save Image Log File";
	ofn.Flags = OFN_PATHMUSTEXIST;

	// Display the Open dialog box. 
	if (GetSaveFileName(&ofn)!=TRUE)
	{
		MessageBox(parent,"Invalid Filename.","Create Image
Log",MB_ICONWARNING);
		return;
	}

	//Open log file
	if (!(file=fopen(filename,"w")))
	{
		MessageBox(parent,"Unable to create file!","Create Image
Log",MB_ICONWARNING);
		return;
	}
	
	//Select the palette into the device context.
	SelectPalette(
    hdc,
    hpal,
    FALSE //FALSE forces it into foreground mode
   );
	
	//This info must be filled in order to extract pixel data..
	bi.bmiHeader.biSize=0x28;
	bi.bmiHeader.biBitCount=0x0;	
	bi.bmiHeader.biClrImportant=0x0; 

	/* Call GetDIBits to return the raw data of the image since
	we can't look inside the handle ourselves.  If number of scan
	lines is set to 0 DIBits returns the entire image. */

	i=GetDIBits(
		hdc,	// handle of device context 
		hbmp,	// handle of bitmap 
		0,	// first scan line to set in destination bitmap  
		ydim,	// number of scan lines to copy 
		NULL,	// address of array for bitmap bits 
		&bi,	// address of structure with bitmap data 
		DIB_RGB_COLORS	// RGB or palette index 	
		); 

	fprintf(file,"Number of bytes required: %x\n",sizeof(BITMAPINFOHEADER));
	fprintf(file,"Bytes Returned: %d\n",i);
	fprintf(file,"\nData Returned\n");
	fprintf(file,"biSize: %02x\n",bi.bmiHeader.biSize);
	fprintf(file,"biWidth: %02x\n",bi.bmiHeader.biWidth);
	fprintf(file,"biHeight: %02x\n",bi.bmiHeader.biHeight);
	fprintf(file,"biPlanes: %02x\n",bi.bmiHeader.biPlanes);
	fprintf(file,"biBitCount: %02x\n",bi.bmiHeader.biBitCount); 
	fprintf(file,"biSizeImage: %02x\n",bi.bmiHeader.biSizeImage);
	fprintf(file,"biCompression: %02x\n",bi.bmiHeader.biCompression);
	fprintf(file,"biXPelsPerMeter: %02x\n",bi.bmiHeader.biXPelsPerMeter);
	fprintf(file,"biYPelsPerMeter: %02x\n",bi.bmiHeader.biYPelsPerMeter);
	fprintf(file,"biClrUsed: %02x\n",bi.bmiHeader.biClrUsed);
	fprintf(file,"biClrImportant: %02x\n",bi.bmiHeader.biClrImportant); 

	//Now allocate space for bits
	if ((lpvBits = (PBYTE)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,19200)) == NULL) 
	{
        MessageBox(parent, "Failed in Memory Allocation for lpvBits!", "Video
Capture", MB_OK);
		return;
	}

	ZeroMemory(lpvBits,sizeof(BYTE)*19200);
	pbi=(PBITMAPINFO)malloc(sizeof(BITMAPINFO)+(sizeof(RGBQUAD)*256));
	ZeroMemory(pbi,(sizeof(BITMAPINFO)+(sizeof(RGBQUAD)*256)));
	memcpy(pbi,&bi,sizeof(BITMAPINFO));

	 i=GetDIBits(
		hdc,	// handle of device context 
		hbmp,	// handle of bitmap 
		0,	// first scan line to set in destination bitmap  
		120,	// number of scan lines to copy 
		(LPVOID)lpvBits,	// address of array for bitmap bits 
		pbi,	// address of structure with bitmap data 
		DIB_RGB_COLORS	// RGB or palette index 
		);  

	fprintf(file,"\nSecond Bytes Returned: %d\n",i);
	fprintf(file,"biSize: %02x\n",pbi->bmiHeader.biSize);
	fprintf(file,"biWidth: %02x\n",pbi->bmiHeader.biWidth);
	fprintf(file,"biHeight: %02x\n",pbi->bmiHeader.biHeight);
	fprintf(file,"biPlanes: %02x\n",pbi->bmiHeader.biPlanes);
	fprintf(file,"biBitCount: %02x\n",pbi->bmiHeader.biBitCount); 
	fprintf(file,"biSizeImage: %02x\n",pbi->bmiHeader.biSizeImage);
	fprintf(file,"biCompression: %02x\n",pbi->bmiHeader.biCompression);
	fprintf(file,"biXPelsPerMeter: %02x\n",pbi->bmiHeader.biXPelsPerMeter);
	fprintf(file,"biYPelsPerMeter: %02x\n",pbi->bmiHeader.biYPelsPerMeter);
	fprintf(file,"biClrUsed: %02x\n",pbi->bmiHeader.biClrUsed);
	fprintf(file,"biClrImportant: %02x\n",pbi->bmiHeader.biClrImportant); 	

	fprintf(file,"\n\nColor Table\n\n");
	
	for (i=0; i<256; i++)
	{
		fprintf(file,"Color Number: %d\n",i);				
	
		fprintf(file,"rgbBlue: %d\n",pbi->bmiColors[i].rgbBlue);
		fprintf(file,"rgbGreen: %d\n",pbi->bmiColors[i].rgbGreen);	
	
		fprintf(file,"rgbRed: %d\n",pbi->bmiColors[i].rgbRed);
		fputs("\n",file);
	}
	
	//Lets dump the bits
	fprintf(file,"\nRaw Data\n");
	for (b=ydim; b>=1; b--)
		for (a=0; a<xdim; a++)
		
fprintf(file,"%f\n",(pbi->bmiColors[lpvBits[(19200-(b*160))+a]].rgbBlue/255.0));
		
	fclose(file);

	if (lpvBits!=NULL)
		GlobalFree(lpvBits);
	if (hbmp!=NULL)
		DeleteObject(hbmp);
	if (hpal!=NULL)
		DeleteObject(hpal);
	if (pbi!=NULL)
		free(pbi);
	EmptyClipboard();
	CloseClipboard();
	ReleaseDC(hdc,ghWndCap);
}

void RunAllSets(HWND parent)
/* This function will take all the input sets and compute
the network output one at a time.  It puts the results into
a file specified as the output by the user. */
{

	OPENFILENAME ofn;
	char filename[100];
	FILE *file;
	int i,j;

	//Check to make sure network is initialized...
	if (!NET_INIT)
	{
		MessageBox(parent,"Network Not Initialized!","Run All Image Sets",
			MB_ICONHAND);
		return;
	}

	//First Get Filename
	ZeroMemory(filename,strlen(filename));
	// Initialize OPENFILENAME
	ofn.lStructSize = sizeof(OPENFILENAME);
	ofn.hInstance=NULL;
	ofn.hwndOwner = parent;
	ofn.lpstrFile = filename;
	ofn.nMaxFile = sizeof(filename);
	ofn.lpstrFilter = "All\0*.*\0Image Log File\0*.LOG\0";
	ofn.lpstrCustomFilter=NULL;
	ofn.nFilterIndex = 2;
	ofn.lpstrFileTitle = NULL;
	ofn.nMaxFileTitle = 0;
	
	ofn.lpstrInitialDir = NULL;
	ofn.lpstrTitle="Log File";
	ofn.Flags = OFN_PATHMUSTEXIST;

	// Display the Open dialog box. 
	if (GetSaveFileName(&ofn)!=TRUE)
	{
		MessageBox(parent,"Invalid Filename.","Run all Image
Sets",MB_ICONSTOP);
		return;
	}

	//Open file for write
	file=fopen(filename,"w");

	for (i=0; i<INPUT_SET; i++)
	{
		Compute(i);
		for (j=0; j<NUM_OUTPUT; j++)
			fprintf(file,"%08f ",Net.output[j].activation);
		fprintf(file,"\n");
	}

	fclose(file);
	MessageBox(parent,"All Image Sets Run Successfully","Complete!",MB_OK);
}


---------------- Header File ICU.H ------------------------------------


/* 1/28/97 J. P. Neural Net */

#include <windows.h>
#include <strstrea.h>
#include <stddef.h>
#include <memory.h>
#include <winioctl.h>
#include <wingdi.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <windowsx.h>
#include <commdlg.h>
#include <mmreg.h> 
#include <io.h>	 
#include <fcntl.h> 
#include <vfw.h>
#include <math.h>
#include <time.h>


//Forward Declarations
int PASCAL WinMain(HANDLE hThisInst, HANDLE hPrevInst,
				   LPSTR lpszArgs, int nWinMode);
LONG FAR PASCAL WindowFunc(HWND hwnd, unsigned int message,
						unsigned int wParam, LONG lParam);
LONG FAR PASCAL ChildFunc(HWND child, unsigned int message,
						unsigned int wParam, LONG lParam);
LONG FAR PASCAL DisplayInputNodes(HWND scroll, unsigned int message,
						unsigned int wParam, LONG lParam);
LONG FAR PASCAL DisplayHiddenNodes(HWND scroll, unsigned int message,
						unsigned int wParam, LONG lParam);
LONG FAR PASCAL DisplayOutputNodes(HWND scroll, unsigned int message,
						unsigned int wParam, LONG lParam);
LONG FAR PASCAL DisplayI2H(HWND scroll, unsigned int message,
						unsigned int wParam, LONG lParam);
LONG FAR PASCAL DisplayH2O(HWND scroll, unsigned int message,
						unsigned int wParam, LONG lParam);
LONG FAR PASCAL DisplayDesired(HWND scroll, unsigned int message,
						unsigned int wParam, LONG lParam);
BOOLEAN AllocSpace(void);
void FreeSpace(void);
void NetInit(HWND hwnd);
void GetInput(HWND hwnd);
void Compute(int);
void BackProp(int);
int Good(int);
void Epoch(HWND hwnd);
void LoadNet(HWND hwnd);
void LoadDSRD(HWND hwnd);
void SavNet(HWND hwnd);
void SetDOutput(HWND hwnd);
void ViewParams(HWND parent);
void Menu(HWND);
void ProcessSelection(int xcount, int ycount, HWND hwnd);
void clrscr(HWND hwnd);
void DisplayText(char title[50],char output[100],HWND parent,int priority);
void UserInput(char *title,int width,int height,HWND parent);
inline void ConvertFloat(char *string,double source,int precision);
void ViewInputActivations(HWND parent);
void ViewHiddenActivations(HWND parent);
void ViewOutputActivations(HWND parent);
void ViewI2H(HWND parent);
void ViewH2O(HWND parent);
void ViewDesiredOutput(HWND parent);
void Capture(HWND parent);
void WhatISee(HWND parent);
void RunAllSets(HWND hwnd);

//Global Environment Parameters
#define SIGMOID(x) (1.0/(1.0+exp(-x)))
#define RANDOM ((double)rand()/(RAND_MAX))
#define square(x) ((x)*(x))

//Neural Network specific structures
typedef struct Unit
{
	double input; //Total input
	double activation; //Total output (input through sigmoid function)
} Unit;

typedef struct Net
{
	Unit **input; //[INPUT_SET][NUM_INPUT]
	Unit *hidden; //[NUM_HIDDEN]
	Unit *output; //[NUM_OUTPUT]
	double *error; //Overall network error [INPUT_SET]

	//Connections between layers
	double **i2h; //input to hidden [NUM_INPUT][NUM_HIDDEN]
	double **h2o; //hidden to output [NUM_HIDDEN][NUM_OUTPUT]
} NET; 




T.RTitleUserPersonal
Name
DateLines