//===========================================================================
// Custom Solution Wizard - NSNetwork Class Implementation
//
//---------------------------------------------------------------------------
// This file is provided to demonstrate how classes can be constructed to
// encapsulate the functions in a Custom Solution Wizard generated DLL.
// The classes in this file can be used without modication, but are not
// required for interaction with generated DLLs.
//===========================================================================

//===========================================================================
// Includes
//===========================================================================
#include "stdafx.h"
#include "NSNetwork.h"

//===========================================================================
//===========================================================================
// CLASS: NSNetwork
//===========================================================================
//===========================================================================

//---------------------------------------------------------------------------
// CLASS: NSNetwork			FUNCTION: <constructor> (LPCSTR)
//---------------------------------------------------------------------------
NSNetwork::NSNetwork(LPCSTR dllPathName)
{
	//---------------------------------------------------------------------------
	// Load the neural network DLL.
	//---------------------------------------------------------------------------
	m_hDLL = LoadLibrary(dllPathName);
	m_pNetworkInstance = 0;

	//---------------------------------------------------------------------------
	// If the DLL load was successful, get the addresses of the DLL functions.
	//---------------------------------------------------------------------------
	if (m_hDLL)
	{
		//---------------------------------------------------------------------------
		// Load functions common to both RECALL and LEARNING DLLs.
		//---------------------------------------------------------------------------
		m_NSCreateNetwork = (NSCreateNetwork)GetProcAddress(m_hDLL, "createNetwork");
		m_NSDestroyNetwork = (NSDestroyNetwork)GetProcAddress(m_hDLL, "destroyNetwork");
		m_NSGetInputOutputInfo = (NSGetInputOutputInfo)GetProcAddress(m_hDLL, "getInputOutputInfo");
		m_NSGetResponse = (NSGetResponse)GetProcAddress(m_hDLL, "getResponse");
		m_NSGetSensitivity = (NSGetSensitivity)GetProcAddress(m_hDLL, "getSensitivity");
		m_NSLoadWeights = (NSLoadWeights)GetProcAddress(m_hDLL, "loadWeights");
		m_NSSaveWeights = (NSSaveWeights)GetProcAddress(m_hDLL, "saveWeights");
		m_NSRandomizeWeights = (NSRandomizeWeights)GetProcAddress(m_hDLL, "randomizeWeights");
		m_NSResetNetwork = (NSResetNetwork)GetProcAddress(m_hDLL, "resetNetwork");

		//---------------------------------------------------------------------------
		// Verify functions common to both RECALL and LEARNING DLLs loaded correctly.
		//---------------------------------------------------------------------------
		if (!m_NSCreateNetwork ||
			!m_NSDestroyNetwork ||
			!m_NSGetInputOutputInfo ||
			!m_NSGetResponse ||
			!m_NSGetSensitivity ||
			!m_NSLoadWeights ||
			!m_NSSaveWeights ||
			!m_NSRandomizeWeights ||
			!m_NSResetNetwork)
		{
			FreeLibrary(m_hDLL);
			m_hDLL = 0;
		}
	}
}

//---------------------------------------------------------------------------
// CLASS: NSNetwork			FUNCTION: <destructor>
//---------------------------------------------------------------------------
NSNetwork::~NSNetwork()
{
	//---------------------------------------------------------------------------
	// If the network instance is still set, release it.
	//---------------------------------------------------------------------------
	if (IsInitialized())
	{
		m_NSDestroyNetwork(m_pNetworkInstance);
		m_pNetworkInstance = 0;
	}

	//---------------------------------------------------------------------------
	// Release the neural network DLL if it is loaded.
	//---------------------------------------------------------------------------
	if (IsLoaded())
	{
		FreeLibrary(m_hDLL);
		m_hDLL = 0;
	}
}

//---------------------------------------------------------------------------
// CLASS: NSNetwork			FUNCTION: GetInputs()
//---------------------------------------------------------------------------
// Return the number of inputs for the generated DLL or -1 on failure.
//---------------------------------------------------------------------------
int NSNetwork::GetInputs()
{
	int numInputs;
	int numOutputs;
	if (!IsInitialized())
		return -1;
	if (m_NSGetInputOutputInfo(m_pNetworkInstance,numInputs,numOutputs))
		return -1;
	return numInputs;
}

//---------------------------------------------------------------------------
// CLASS: NSNetwork			FUNCTION: GetOutputs()
//---------------------------------------------------------------------------
// Return the number of outputs for the generated DLL or -1 on failure.
//---------------------------------------------------------------------------
int NSNetwork::GetOutputs()
{
	int numInputs;
	int numOutputs;
	if (!IsInitialized())
		return -1;
	if (m_NSGetInputOutputInfo(m_pNetworkInstance,numInputs,numOutputs))
		return -1;
	return numOutputs;
}

//---------------------------------------------------------------------------
// CLASS: NSNetwork			FUNCTION: GetInputOutputInfo(int,int)
//---------------------------------------------------------------------------
// Obtain the number of inputs and outputs for the generated DLL.
// Returns 0 on success, -1 if not initialized, or an error code from the DLL.
//---------------------------------------------------------------------------
int NSNetwork::GetInputOutputInfo(int& numInputs, int& numOutputs)
{
	if (!IsInitialized())
		return -1;
	return m_NSGetInputOutputInfo(m_pNetworkInstance,numInputs,numOutputs);
}

//---------------------------------------------------------------------------
// CLASS: NSNetwork			FUNCTION: GetResponse(int,double*,double*)
//---------------------------------------------------------------------------
// Obtain the neural network response to a set of input data.
// Returns 0 on success, -1 if not initialized, or an error code from the DLL.
//---------------------------------------------------------------------------
int NSNetwork::GetResponse(int exemplars, double* inputData, double* outputData)
{
	if (!IsInitialized())
		return -1;
	return m_NSGetResponse(m_pNetworkInstance,exemplars,inputData,outputData);
}

//---------------------------------------------------------------------------
// CLASS: NSNetwork			FUNCTION: GetSensitivity(int,double*,double*,double)
//---------------------------------------------------------------------------
// Obtain the neural network sensitivity to a set of input data.
// Returns 0 on success, -1 if not initialized, or an error code from the DLL.
//---------------------------------------------------------------------------
int NSNetwork::GetSensitivity(int exemplars, double* inputData, double* sensitivityData, double dither)
{
	if (!IsInitialized())
		return -1;
	return m_NSGetSensitivity(m_pNetworkInstance,exemplars,inputData,sensitivityData,dither);
}

//---------------------------------------------------------------------------
// CLASS: NSNetwork			FUNCTION: LoadWeights(LPCSTR)
//---------------------------------------------------------------------------
// Load a weights file.
// Returns 0 on success, -1 if not initialized, or an error code from the DLL.
//---------------------------------------------------------------------------
int NSNetwork::LoadWeights(LPCSTR pathName)
{
	if (!IsInitialized())
		return -1;
	return m_NSLoadWeights(m_pNetworkInstance,pathName);
}

//---------------------------------------------------------------------------
// CLASS: NSNetwork			FUNCTION: RandomizeWeights()
//---------------------------------------------------------------------------
// Randomize the weights in the network.
// Returns 0 on success, -1 if not initialized, or an error code from the DLL.
//---------------------------------------------------------------------------
int NSNetwork::RandomizeWeights()
{
	if (!IsInitialized())
		return -1;
	return m_NSRandomizeWeights(m_pNetworkInstance);
}

//---------------------------------------------------------------------------
// CLASS: NSNetwork			FUNCTION: ResetNetwork()
//---------------------------------------------------------------------------
// Reset the network.
// Returns 0 on success, -1 if not initialized, or an error code from the DLL.
//---------------------------------------------------------------------------
int NSNetwork::ResetNetwork()
{
	if (!IsInitialized())
		return -1;
	return m_NSResetNetwork(m_pNetworkInstance);
}

//---------------------------------------------------------------------------
// CLASS: NSNetwork			FUNCTION: SaveWeights(LPCSTR)
//---------------------------------------------------------------------------
// Save a weights file.
// Returns 0 on success, -1 if not initialized, or an error code from the DLL.
//---------------------------------------------------------------------------
int NSNetwork::SaveWeights(LPCSTR pathName)
{
	if (!IsInitialized())
		return -1;
	return m_NSSaveWeights(m_pNetworkInstance,pathName);
}

//===========================================================================
//===========================================================================
// CLASS: NSLearningNetwork
//===========================================================================
//===========================================================================

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork		FUNCTION: <constructor> (LPCSTR)
//---------------------------------------------------------------------------
NSLearningNetwork::NSLearningNetwork(LPCSTR dllPathName):
	NSNetwork(dllPathName)
{
	//---------------------------------------------------------------------------
	// If the DLL load was successful, get the addresses of the learning DLL functions.
	//---------------------------------------------------------------------------
	if (IsLoaded())
	{
		//---------------------------------------------------------------------------
		// Load functions unique to learning DLLs.
		//---------------------------------------------------------------------------
		m_NSTrain = (NSTrain)GetProcAddress(m_hDLL, "train");
		m_NSGetBestCost = (NSGetBestCost)GetProcAddress(m_hDLL, "getBestCost");
		m_NSSetBestCost = (NSSetBestCost)GetProcAddress(m_hDLL, "setBestCost");
		m_NSGetBestWeightsPathName = (NSGetBestWeightsPathName)GetProcAddress(m_hDLL, "getBestWeightsPathName");
		m_NSSetBestWeightsPathName = (NSSetBestWeightsPathName)GetProcAddress(m_hDLL, "setBestWeightsPathName");
		m_NSGetSaveBestWeightsEnabled = (NSGetSaveBestWeightsEnabled)GetProcAddress(m_hDLL, "getSaveBestWeightsEnabled");
		m_NSSetSaveBestWeightsEnabled = (NSSetSaveBestWeightsEnabled)GetProcAddress(m_hDLL, "setSaveBestWeightsEnabled");
		m_NSGetSaveBestWeightsForTraining = (NSGetSaveBestWeightsForTraining)GetProcAddress(m_hDLL, "getSaveBestWeightsForTraining");
		m_NSSetSaveBestWeightsForTraining = (NSSetSaveBestWeightsForTraining)GetProcAddress(m_hDLL, "setSaveBestWeightsForTraining");
		m_NSGetCrossValidationEnabled = (NSGetCrossValidationEnabled)GetProcAddress(m_hDLL, "getCrossValidationEnabled");
		m_NSSetCrossValidationEnabled = (NSSetCrossValidationEnabled)GetProcAddress(m_hDLL, "setCrossValidationEnabled");
		m_NSGetAutoComputeInputNormCoeff = (NSGetAutoComputeInputNormCoeff)GetProcAddress(m_hDLL, "getAutoComputeInputNormCoeff");
		m_NSSetAutoComputeInputNormCoeff = (NSSetAutoComputeInputNormCoeff)GetProcAddress(m_hDLL, "setAutoComputeInputNormCoeff");
		m_NSGetAutoComputeOutputNormCoeff = (NSGetAutoComputeOutputNormCoeff)GetProcAddress(m_hDLL, "getAutoComputeOutputNormCoeff");
		m_NSSetAutoComputeOutputNormCoeff = (NSSetAutoComputeOutputNormCoeff)GetProcAddress(m_hDLL, "setAutoComputeOutputNormCoeff");
		m_NSRemoveInputNormalization = (NSRemoveInputNormalization)GetProcAddress(m_hDLL, "removeInputNormalization");
		m_NSRemoveOutputNormalization = (NSRemoveOutputNormalization)GetProcAddress(m_hDLL, "removeOutputNormalization");
		m_NSGetInputNormMin = (NSGetInputNormMin)GetProcAddress(m_hDLL, "getInputNormMin");
		m_NSSetInputNormMin = (NSSetInputNormMin)GetProcAddress(m_hDLL, "setInputNormMin");
		m_NSGetInputNormMax = (NSGetInputNormMax)GetProcAddress(m_hDLL, "getInputNormMax");
		m_NSSetInputNormMax = (NSSetInputNormMax)GetProcAddress(m_hDLL, "setInputNormMax");
		m_NSGetOutputNormMin = (NSGetOutputNormMin)GetProcAddress(m_hDLL, "getOutputNormMin");
		m_NSSetOutputNormMin = (NSSetOutputNormMin)GetProcAddress(m_hDLL, "setOutputNormMin");
		m_NSGetOutputNormMax = (NSGetOutputNormMax)GetProcAddress(m_hDLL, "getOutputNormMax");
		m_NSSetOutputNormMax = (NSSetOutputNormMax)GetProcAddress(m_hDLL, "setOutputNormMax");
		m_NSGetNormalizeInputByChannel = (NSGetNormalizeInputByChannel)GetProcAddress(m_hDLL, "getNormalizeInputByChannel");
		m_NSSetNormalizeInputByChannel = (NSSetNormalizeInputByChannel)GetProcAddress(m_hDLL, "setNormalizeInputByChannel");
		m_NSGetNormalizeOutputByChannel = (NSGetNormalizeOutputByChannel)GetProcAddress(m_hDLL, "getNormalizeOutputByChannel");
		m_NSSetNormalizeOutputByChannel = (NSSetNormalizeOutputByChannel)GetProcAddress(m_hDLL, "setNormalizeOutputByChannel");
		m_NSGetCrossValidationCostData = (NSGetCrossValidationCostData)GetProcAddress(m_hDLL, "getCrossValidationCostData");
		m_NSGetCostData = (NSGetCostData)GetProcAddress(m_hDLL, "getCostData");
		m_NSGetNumberOfEpochsTrained = (NSGetNumberOfEpochsTrained)GetProcAddress(m_hDLL, "getNumberOfEpochsTrained");
		m_NSGetEpochOfBestCost = (NSGetEpochOfBestCost)GetProcAddress(m_hDLL, "getEpochOfBestCost");
		m_NSSeedRandom = (NSSeedRandom)GetProcAddress(m_hDLL, "seedRandom");

		//---------------------------------------------------------------------------
		// Verify functions unique to learning DLLs loaded correctly.
		// Note: Do not free DLL on failure so that caller can use IsLoaded()/IsInitialized().
		//---------------------------------------------------------------------------
		if (!m_NSTrain ||
			!m_NSGetBestCost ||
			!m_NSSetBestCost ||
			!m_NSGetBestWeightsPathName ||
			!m_NSSetBestWeightsPathName ||
			!m_NSGetSaveBestWeightsEnabled ||
			!m_NSSetSaveBestWeightsEnabled ||
			!m_NSGetSaveBestWeightsForTraining ||
			!m_NSSetSaveBestWeightsForTraining ||
			!m_NSGetCrossValidationEnabled ||
			!m_NSSetCrossValidationEnabled ||
			!m_NSGetAutoComputeInputNormCoeff ||
			!m_NSSetAutoComputeInputNormCoeff ||
			!m_NSGetAutoComputeOutputNormCoeff ||
			!m_NSSetAutoComputeOutputNormCoeff ||
			!m_NSRemoveInputNormalization ||
			!m_NSRemoveOutputNormalization ||
			!m_NSGetInputNormMin ||
			!m_NSSetInputNormMin ||
			!m_NSGetInputNormMax ||
			!m_NSSetInputNormMax ||
			!m_NSGetOutputNormMin ||
			!m_NSSetOutputNormMin ||
			!m_NSGetOutputNormMax ||
			!m_NSSetOutputNormMax ||
			!m_NSGetNormalizeInputByChannel ||
			!m_NSSetNormalizeInputByChannel ||
			!m_NSGetNormalizeOutputByChannel ||
			!m_NSSetNormalizeOutputByChannel ||
			!m_NSGetCrossValidationCostData ||
			!m_NSGetCostData ||
			!m_NSGetNumberOfEpochsTrained ||
			!m_NSGetEpochOfBestCost ||
			!m_NSSeedRandom)
		{
		}
		//---------------------------------------------------------------------------
		// If all functions available, create an instance of the neural network.
		//---------------------------------------------------------------------------
		else
		{
			m_NSCreateNetwork(m_pNetworkInstance,LEARNING);
		}
	}
}

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork			FUNCTION: RemoveInputNormalization()
//---------------------------------------------------------------------------
// Remove the normalization of the input data.
// Returns 0 on success, -1 if not initialized, or an error code from the DLL.
//---------------------------------------------------------------------------
int NSLearningNetwork::RemoveInputNormalization()
{
	if (!IsInitialized())
		return -1;
	return m_NSRemoveInputNormalization(m_pNetworkInstance);
}

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork			FUNCTION: RemoveOutputNormalization()
//---------------------------------------------------------------------------
// Remove the normalization of the output  data.
// Returns 0 on success, -1 if not initialized, or an error code from the DLL.
//---------------------------------------------------------------------------
int NSLearningNetwork::RemoveOutputNormalization()
{
	if (!IsInitialized())
		return -1;
	return m_NSRemoveOutputNormalization(m_pNetworkInstance);
}

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork			FUNCTION: SeedRandom(unsigned int)
//---------------------------------------------------------------------------
// Seed the random number generator.
// Returns 0 on success, -1 if not initialized, or an error code from the DLL.
//---------------------------------------------------------------------------
int NSLearningNetwork::SeedRandom(unsigned int seed)
{
	if (!IsInitialized())
		return -1;
	return m_NSSeedRandom(m_pNetworkInstance, seed);
}

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork			FUNCTION: Train(int,int,double*,double*)
//---------------------------------------------------------------------------
// Train the network without cross-validation.
// Returns 0 on success, -1 if not initialized, or an error code from the DLL.
//---------------------------------------------------------------------------
int NSLearningNetwork::Train(int epochs, int exemplars, double* inputData, double* desiredData)
{
	if (!IsInitialized())
		return -1;
	return m_NSTrain(m_pNetworkInstance,epochs,exemplars,inputData,desiredData,0,0,0);
}

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork			FUNCTION: Train(int,int,double*,double*,int,double*,double*)
//---------------------------------------------------------------------------
// Train the network with cross-validation.
// NOTE: SetCrossValidationEnabled(true) must be called for cross-validation to be activated.
// Returns 0 on success, -1 if not initialized, or an error code from the DLL.
//---------------------------------------------------------------------------
int NSLearningNetwork::Train(int epochs, int exemplars, double* inputData, double* desiredData, int cvExemplars, double* cvInputData, double* cvDesiredData)
{
	if (!IsInitialized())
		return -1;
	return m_NSTrain(m_pNetworkInstance,epochs,exemplars,inputData,desiredData,cvExemplars,cvInputData,cvDesiredData);
}

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork		FUNCTION: GetAutoComputeInputNormCoeff()
//---------------------------------------------------------------------------
// Return whether or not the input normalization coefficients will
// automatically be calculated.
//---------------------------------------------------------------------------
bool NSLearningNetwork::GetAutoComputeInputNormCoeff()
{
	if (!IsInitialized())
		return false;
	bool autoComputeInputNormCoeff;
	if (m_NSGetAutoComputeInputNormCoeff(m_pNetworkInstance,autoComputeInputNormCoeff))
		return false;
	return autoComputeInputNormCoeff;
}

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork		FUNCTION: GetAutoComputeOutputNormCoeff()
//---------------------------------------------------------------------------
// Return whether or not the output normalization coefficients will
// automatically be calculated.
//---------------------------------------------------------------------------
bool NSLearningNetwork::GetAutoComputeOutputNormCoeff()
{
	if (!IsInitialized())
		return false;
	bool autoComputeOutputNormCoeff;
	if (m_NSGetAutoComputeOutputNormCoeff(m_pNetworkInstance,autoComputeOutputNormCoeff))
		return false;
	return autoComputeOutputNormCoeff;
}

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork		FUNCTION: GetBestCost()
//---------------------------------------------------------------------------
// Return the best cost or -1 on failure.
//---------------------------------------------------------------------------
double NSLearningNetwork::GetBestCost()
{
	double bestCost;
	if (!IsInitialized())
		return -1;
	if (m_NSGetBestCost(m_pNetworkInstance,bestCost))
		return -1;
	return bestCost;
}

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork		FUNCTION: GetBestWeightsPathName()
//---------------------------------------------------------------------------
// Return the best weights path name or an empty string on failure.
//---------------------------------------------------------------------------
CString NSLearningNetwork::GetBestWeightsPathName()
{
	char buffer[1024];
	int bufferUsed;
	if (!IsInitialized())
		return "";
	if (m_NSGetBestWeightsPathName(m_pNetworkInstance,buffer,sizeof(buffer),bufferUsed))
		return "";
	return buffer;
}

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork		FUNCTION: GetCostData(double *)
//---------------------------------------------------------------------------
// Fills the costData array with the training learning curve (an array of cost
// data for the training dataset). You must allocate the memory for the cost
// data before passing its pointer to this function. Use GetNumberOfEpochsTrained
// to determine the necessary size of the array.
// Returns 0 on success, -1 if not initialized, or an error code from the DLL.
//---------------------------------------------------------------------------
int NSLearningNetwork::GetCostData(double *costData)
{
	if (!IsInitialized())
		return -1;
	return m_NSGetCostData(m_pNetworkInstance, costData);
}

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork		FUNCTION: GetCrossValidationCostData(double *)
//---------------------------------------------------------------------------
// Fills the CVCostData array with the cross validation learning curve (an
// array of cost data for the cross validation dataset). You must allocate
// the memory for the cost data before passing its pointer to this function.
// Use GetNumberOfEpochsTrained to determine the necessary size of the array.
// Returns 0 on success, -1 if not initialized, or an error code from the DLL.
//---------------------------------------------------------------------------
int NSLearningNetwork::GetCrossValidationCostData(double *CVCostData)
{
	if (!IsInitialized())
		return -1;
	return m_NSGetCrossValidationCostData(m_pNetworkInstance, CVCostData);
}

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork		FUNCTION: GetCrossValidationEnabled()
//---------------------------------------------------------------------------
// Return whether or not cross validation will be used during training.
//---------------------------------------------------------------------------
bool NSLearningNetwork::GetCrossValidationEnabled()
{
	if (!IsInitialized())
		return false;
	bool crossValidationEnabled;
	if (m_NSGetCrossValidationEnabled(m_pNetworkInstance,crossValidationEnabled))
		return false;
	return crossValidationEnabled;
}

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork		FUNCTION: GetEpochOfBestCost()
//---------------------------------------------------------------------------
// Return the epoch during which the best cost was obtained.
//---------------------------------------------------------------------------
int NSLearningNetwork::GetEpochOfBestCost()
{
	if (!IsInitialized())
		return -1;
	int epochOfBestCost;
	m_NSGetEpochOfBestCost(m_pNetworkInstance, epochOfBestCost);
	return epochOfBestCost;
}

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork		FUNCTION: GetInputNormMax()
//---------------------------------------------------------------------------
// Returns the upper bound for the input normalization.
//---------------------------------------------------------------------------
double NSLearningNetwork::GetInputNormMax()
{
	if (!IsInitialized())
		return -1;
	double inputNormMax;
	m_NSGetInputNormMax(m_pNetworkInstance, inputNormMax);
	return inputNormMax;
}

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork		FUNCTION: GetInputNormMin()
//---------------------------------------------------------------------------
// Returns the lower bound for the input normalization.
//---------------------------------------------------------------------------
double NSLearningNetwork::GetInputNormMin()
{
	if (!IsInitialized())
		return -1;
	double inputNormMin;
	m_NSGetInputNormMin(m_pNetworkInstance, inputNormMin);
	return inputNormMin;
}

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork		FUNCTION: GetNormalizeInputByChannel()
//---------------------------------------------------------------------------
// Return whether or not the input normalization coefficients will
// calculated by channel (for each column of data individually) or across the
// entire input dataset.
//---------------------------------------------------------------------------
bool NSLearningNetwork::GetNormalizeInputByChannel()
{
	if (!IsInitialized())
		return false;
	bool normalizeInputByChannel;
	if (m_NSGetNormalizeInputByChannel(m_pNetworkInstance, normalizeInputByChannel))
		return false;
	return normalizeInputByChannel;
}

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork		FUNCTION: GetNormalizeOutputByChannel()
//---------------------------------------------------------------------------
// Return whether or not the output normalization coefficients will
// calculated by channel (for each column of data individually) or across the
// entire output dataset.
//---------------------------------------------------------------------------
bool NSLearningNetwork::GetNormalizeOutputByChannel()
{
	if (!IsInitialized())
		return false;
	bool normalizeOutputByChannel;
	if (m_NSGetNormalizeOutputByChannel(m_pNetworkInstance, normalizeOutputByChannel))
		return false;
	return normalizeOutputByChannel;
}

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork		FUNCTION: GetNumberOfEpochsTrained()
//---------------------------------------------------------------------------
// Returns the number of epochs that the network has been trained for (the
// network may not train for the complete number of epochs set due to the
// existance of transmitters that may stop the network early).
//---------------------------------------------------------------------------
int NSLearningNetwork::GetNumberOfEpochsTrained()
{
	if (!IsInitialized())
		return -1;
	int numberOfEpochsTrained;
	m_NSGetNumberOfEpochsTrained(m_pNetworkInstance, numberOfEpochsTrained);
	return numberOfEpochsTrained;
}

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork		FUNCTION: GetOutputNormMax()
//---------------------------------------------------------------------------
// Returns the upper bound for the output normalization.
//---------------------------------------------------------------------------
double NSLearningNetwork::GetOutputNormMax()
{
	if (!IsInitialized())
		return -1;
	double outputNormMax;
	m_NSGetOutputNormMax(m_pNetworkInstance, outputNormMax);
	return outputNormMax;
}

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork		FUNCTION: GetOutputNormMin()
//---------------------------------------------------------------------------
// Returns the upper bound for the output normalization.
//---------------------------------------------------------------------------
double NSLearningNetwork::GetOutputNormMin()
{
	if (!IsInitialized())
		return -1;
	double outputNormMin;
	m_NSGetOutputNormMin(m_pNetworkInstance, outputNormMin);
	return outputNormMin;
}

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork		FUNCTION: GetSaveBestWeightsEnabled()
//---------------------------------------------------------------------------
// Return whether or not the best weights will be saved during training.
//---------------------------------------------------------------------------
bool NSLearningNetwork::GetSaveBestWeightsEnabled()
{
	bool saveBestWeightsEnabled;
	if (!IsInitialized())
		return false;
	if (m_NSGetSaveBestWeightsEnabled(m_pNetworkInstance,saveBestWeightsEnabled))
		return false;
	return saveBestWeightsEnabled;
}

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork		FUNCTION: GetSaveBestWeightsForTraining()
//---------------------------------------------------------------------------
// Return whether the best weights will be saved for training or cross validation.
//---------------------------------------------------------------------------
bool NSLearningNetwork::GetSaveBestWeightsForTraining()
{
	bool saveBestWeightsForTraining;
	if (!IsInitialized())
		return false;
	if (m_NSGetSaveBestWeightsForTraining(m_pNetworkInstance,saveBestWeightsForTraining))
		return false;
	return saveBestWeightsForTraining;
}

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork		FUNCTION: SetAutoComputeInputNormCoeff(bool)
//---------------------------------------------------------------------------
// Turn the auto-computation of input normalization coefficients on or off.
// Returns 0 on success, -1 if not initialized, or an error code from the DLL.
//---------------------------------------------------------------------------
int NSLearningNetwork::SetAutoComputeInputNormCoeff(bool autoComputeInputNormCoeff)
{
	if (!IsInitialized())
		return -1;
	return m_NSSetAutoComputeInputNormCoeff(m_pNetworkInstance, autoComputeInputNormCoeff);
}

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork		FUNCTION: SetAutoComputeOutputNormCoeff(bool)
//---------------------------------------------------------------------------
// Turn the auto-computation of output normalization coefficients on or off.
// Returns 0 on success, -1 if not initialized, or an error code from the DLL.
//---------------------------------------------------------------------------
int NSLearningNetwork::SetAutoComputeOutputNormCoeff(bool autoComputeOutputNormCoeff)
{
	if (!IsInitialized())
		return -1;
	return m_NSSetAutoComputeOutputNormCoeff(m_pNetworkInstance, autoComputeOutputNormCoeff);
}

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork		FUNCTION: SetBestCost(double)
//---------------------------------------------------------------------------
// Set the best cost.
// Returns 0 on success, -1 if not initialized, or an error code from the DLL.
//---------------------------------------------------------------------------
int NSLearningNetwork::SetBestCost(double bestCost)
{
	if (!IsInitialized())
		return -1;
	return m_NSSetBestCost(m_pNetworkInstance,bestCost);
}

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork		FUNCTION: SetBestWeightsPathName(LPCSTR)
//---------------------------------------------------------------------------
// Set the path name to save the best weights to.
// Returns 0 on success, -1 if not initialized, or an error code from the DLL.
//---------------------------------------------------------------------------
int NSLearningNetwork::SetBestWeightsPathName(LPCSTR pathName)
{
	if (!IsInitialized())
		return -1;
	return m_NSSetBestWeightsPathName(m_pNetworkInstance,pathName);
}

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork		FUNCTION: SetCrossValidationEnabled(bool)
//---------------------------------------------------------------------------
// Turn the cross-validation on or off.
// Returns 0 on success, -1 if not initialized, or an error code from the DLL.
//---------------------------------------------------------------------------
int NSLearningNetwork::SetCrossValidationEnabled(bool crossValidationEnabled)
{
	if (!IsInitialized())
		return -1;
	return m_NSSetCrossValidationEnabled(m_pNetworkInstance,crossValidationEnabled);
}

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork		FUNCTION: SetInputNormMax(double)
//---------------------------------------------------------------------------
// Sets the upper bound for the input normalization.
// Returns 0 on success, -1 if not initialized, or an error code from the DLL.
//---------------------------------------------------------------------------
int NSLearningNetwork::SetInputNormMax(double inputNormMax)
{
	if (!IsInitialized())
		return -1;
	return m_NSSetInputNormMax(m_pNetworkInstance, inputNormMax);
}

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork		FUNCTION: SetInputNormMin(double)
//---------------------------------------------------------------------------
// Sets the lower bound for the input normalization.
// Returns 0 on success, -1 if not initialized, or an error code from the DLL.
//---------------------------------------------------------------------------
int NSLearningNetwork::SetInputNormMin(double inputNormMin)
{
	if (!IsInitialized())
		return -1;
	return m_NSSetInputNormMin(m_pNetworkInstance, inputNormMin);
}

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork		FUNCTION: SetNormalizeInputByChannel(bool)
//---------------------------------------------------------------------------
// Turn by-channel normalization of the input data on or off.
// Returns 0 on success, -1 if not initialized, or an error code from the DLL.
//---------------------------------------------------------------------------
int NSLearningNetwork::SetNormalizeInputByChannel(bool normalizeInputByChannel)
{
	if (!IsInitialized())
		return -1;
	return m_NSSetNormalizeInputByChannel(m_pNetworkInstance, normalizeInputByChannel);
}

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork		FUNCTION: SetNormalizeOutputByChannel(bool)
//---------------------------------------------------------------------------
// Turn by-channel normalization of the output data on or off.
// Returns 0 on success, -1 if not initialized, or an error code from the DLL.
//---------------------------------------------------------------------------
int NSLearningNetwork::SetNormalizeOutputByChannel(bool normalizeOutputByChannel)
{
	if (!IsInitialized())
		return -1;
	return m_NSSetNormalizeOutputByChannel(m_pNetworkInstance, normalizeOutputByChannel);
}

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork		FUNCTION: SetOutputNormMax(double)
//---------------------------------------------------------------------------
// Sets the upper bound for the output normalization.
// Returns 0 on success, -1 if not initialized, or an error code from the DLL.
//---------------------------------------------------------------------------
int NSLearningNetwork::SetOutputNormMax(double outputNormMax)
{
	if (!IsInitialized())
		return -1;
	return m_NSSetOutputNormMax(m_pNetworkInstance, outputNormMax);
}

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork		FUNCTION: SetOutputNormMin(double)
//---------------------------------------------------------------------------
// Sets the lower bound for the output normalization.
// Returns 0 on success, -1 if not initialized, or an error code from the DLL.
//---------------------------------------------------------------------------
int NSLearningNetwork::SetOutputNormMin(double outputNormMin)
{
	if (!IsInitialized())
		return -1;
	return m_NSSetOutputNormMin(m_pNetworkInstance, outputNormMin);
}

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork		FUNCTION: SetSaveBestWeightsEnabled(bool)
//---------------------------------------------------------------------------
// Turn the saving of the best weights on or off.
// Returns 0 on success, -1 if not initialized, or an error code from the DLL.
//---------------------------------------------------------------------------
int NSLearningNetwork::SetSaveBestWeightsEnabled(bool saveBestWeightsEnabled)
{
	if (!IsInitialized())
		return -1;
	return m_NSSetSaveBestWeightsEnabled(m_pNetworkInstance,saveBestWeightsEnabled);
}

//---------------------------------------------------------------------------
// CLASS: NSLearningNetwork		FUNCTION: SetSaveBestWeightsForTraining(bool)
//---------------------------------------------------------------------------
// Turn the saving of the best weights for training on or off.
// Returns 0 on success, -1 if not initialized, or an error code from the DLL.
//---------------------------------------------------------------------------
int NSLearningNetwork::SetSaveBestWeightsForTraining(bool saveBestWeightsForTraining)
{
	if (!IsInitialized())
		return -1;
	return m_NSSetSaveBestWeightsForTraining(m_pNetworkInstance,saveBestWeightsForTraining);
}

//===========================================================================
//===========================================================================
// CLASS: NSRecallNetwork
//===========================================================================
//===========================================================================

//---------------------------------------------------------------------------
// CLASS: NSRecallNetwork		FUNCTION: <constructor> (LPCSTR)
//---------------------------------------------------------------------------
NSRecallNetwork::NSRecallNetwork(LPCSTR dllPathName):
	NSNetwork(dllPathName)
{
	//---------------------------------------------------------------------------
	// If DLL loaded successfully, create an instance of the neural network.
	//---------------------------------------------------------------------------
	if (IsLoaded())
	{
		m_NSCreateNetwork(m_pNetworkInstance,RECALL);
	}
}