//===========================================================================
// Custom Solution Wizard - NSNetwork Class Definition
//
// Copyright (c) 2000 - NeuroDimension, Inc.
//---------------------------------------------------------------------------
// 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.
//---------------------------------------------------------------------------
// Three sample classes are provided:
//
//		NSNetwork			Common parent to NSLearningNetwork and NSRecallNetwork.
//		NSLearningNetwork	Encapsulation of LEARNING DLL.
//		NSRecallNetwork		Encapsulation of RECALL DLL.
//
//===========================================================================

//===========================================================================
// Enum: NetworkType
//---------------------------------------------------------------------------
//	This value is used to differentiate between RECALL and LEARNING networks.
//===========================================================================
enum {RECALL, LEARNING};

//===========================================================================
// DLL Function TypeDefs
//---------------------------------------------------------------------------
//	These typedefs define the functions and function parameters in the generated DLL.
//===========================================================================

// Functions in both RECALL and LEARNING DLLs
typedef int (*NSCreateNetwork)(void *&pNeuralNetwork, int networkType);
typedef int (*NSDestroyNetwork)(void *pNeuralNetwork);
typedef int (*NSGetInputOutputInfo)(void *pNeuralNetwork, int &numInputs, int &numOutputs);
typedef int (*NSGetResponse)(void *pNeuralNetwork, int exemplars, double *inputData, double *outputData);
typedef int (*NSGetSensitivity)(void *pNeuralNetwork, int exemplars, double *inputData, double *&sensitivityData, double dither);
typedef int (*NSLoadWeights)(void *pNeuralNetwork, const char *weightsPathName);
typedef int (*NSSaveWeights)(void *pNeuralNetwork, const char *weightsPathName);
typedef int (*NSRandomizeWeights)(void *pNeuralNetwork);
typedef int (*NSResetNetwork)(void *pNeuralNetwork);

// Functions in LEARNING DLLs only
typedef int (*NSTrain)(void *pNeuralNetwork, int epochs, int exemplars, double *inputData, double *desiredData, int cvExemplars, double *cvInputData, double *cvDesiredData);
typedef int (*NSGetBestCost)(void *pNeuralNetwork, double &bestCost);
typedef int (*NSSetBestCost)(void *pNeuralNetwork, double bestCost);
typedef int (*NSGetBestWeightsPathName)(void *pNeuralNetwork, char *bestWeightsPathName, int bufferLength, int &pathNameLength);
typedef int (*NSSetBestWeightsPathName)(void *pNeuralNetwork, const char *bestWeightsPathName);
typedef int (*NSGetSaveBestWeightsEnabled)(void *pNeuralNetwork, bool &saveBestWeightsEnabled);
typedef int (*NSSetSaveBestWeightsEnabled)(void *pNeuralNetwork, bool saveBestWeightsEnabled);
typedef int (*NSGetSaveBestWeightsForTraining)(void *pNeuralNetwork, bool &saveBestWeightsForTraining);
typedef int (*NSSetSaveBestWeightsForTraining)(void *pNeuralNetwork, bool saveBestWeightsForTraining);
typedef int (*NSGetCrossValidationEnabled)(void *pNeuralNetwork, bool &crossValidationEnabled);
typedef int (*NSSetCrossValidationEnabled)(void *pNeuralNetwork, bool crossValidationEnabled);
typedef int (*NSSetAutoComputeInputNormCoeff)(void *pNeuralNetwork, bool autoComputeInputNormCoeff);
typedef int (*NSGetAutoComputeInputNormCoeff)(void *pNeuralNetwork, bool &autoComputeInputNormCoeff);
typedef int (*NSSetAutoComputeOutputNormCoeff)(void *pNeuralNetwork, bool autoComputeOutputNormCoeff);
typedef int (*NSGetAutoComputeOutputNormCoeff)(void *pNeuralNetwork, bool &autoComputeOutputNormCoeff);
typedef int (*NSRemoveInputNormalization)(void *pNeuralNetwork);
typedef int (*NSRemoveOutputNormalization)(void *pNeuralNetwork);
typedef int (*NSSetInputNormMin)(void *pNeuralNetwork, double inputNormMin);
typedef int (*NSGetInputNormMin)(void *pNeuralNetwork, double &inputNormMin);
typedef int (*NSSetInputNormMax)(void *pNeuralNetwork, double inputNormMax);
typedef int (*NSGetInputNormMax)(void *pNeuralNetwork, double &inputNormMax);
typedef int (*NSSetOutputNormMin)(void *pNeuralNetwork, double outputNormMin);
typedef int (*NSGetOutputNormMin)(void *pNeuralNetwork, double &outputNormMin);
typedef int (*NSSetOutputNormMax)(void *pNeuralNetwork, double outputNormMax);
typedef int (*NSGetOutputNormMax)(void *pNeuralNetwork, double &outputNormMax);
typedef int (*NSSetNormalizeInputByChannel)(void *pNeuralNetwork, bool normalizeInputByChannel);
typedef int (*NSGetNormalizeInputByChannel)(void *pNeuralNetwork, bool &normalizeInputByChannel);
typedef int (*NSSetNormalizeOutputByChannel)(void *pNeuralNetwork, bool normalizeOutputByChannel);
typedef int (*NSGetNormalizeOutputByChannel)(void *pNeuralNetwork, bool &normalizeOutputByChannel);
typedef int (*NSGetCrossValidationCostData)(void *pNeuralNetwork, double *CVCostData);
typedef int (*NSGetCostData)(void *pNeuralNetwork, double *costData);
typedef int (*NSGetNumberOfEpochsTrained)(void *pNeuralNetwork, int &numberOfEpochsTrained);
typedef int (*NSGetEpochOfBestCost)(void *pNeuralNetwork, int &epochOfBestCost);
typedef int (*NSSeedRandom)(void *pNeuralNetwork, unsigned int seed);


//===========================================================================
// CLASS: NSNetwork
//===========================================================================
class NSNetwork
{
public:
	//---------------------------------------------------------------------------
	// Public functions.
	//---------------------------------------------------------------------------
	NSNetwork(LPCSTR dllPathName);
	~NSNetwork();

	bool IsLoaded()			{return (m_hDLL != 0);};
	bool IsInitialized()	{return (IsLoaded() && m_pNetworkInstance);};

	int GetInputs();
	int GetOutputs();
	int GetInputOutputInfo(int& numInputs, int& numOutputs);
	int GetResponse(int exemplars, double* inputData, double* outputData);
	int GetSensitivity(int exemplars, double* inputData, double* sensitivityData, double dither);
	int LoadWeights(LPCSTR pathName);
	int RandomizeWeights();
	int ResetNetwork();
	int SaveWeights(LPCSTR pathName);

protected:
	//---------------------------------------------------------------------------
	// Protected variables.
	//---------------------------------------------------------------------------
	HINSTANCE m_hDLL;
	void* m_pNetworkInstance;
	NSCreateNetwork m_NSCreateNetwork;
	NSDestroyNetwork m_NSDestroyNetwork;
	NSLoadWeights m_NSLoadWeights;
	NSSaveWeights m_NSSaveWeights;
	NSRandomizeWeights m_NSRandomizeWeights;
	NSResetNetwork m_NSResetNetwork;
	NSGetInputOutputInfo m_NSGetInputOutputInfo;
	NSGetResponse m_NSGetResponse;
	NSGetSensitivity m_NSGetSensitivity;
};

//===========================================================================
// CLASS: NSLearningNetwork
//===========================================================================
class NSLearningNetwork : public NSNetwork
{
public:
	//---------------------------------------------------------------------------
	// Public functions.
	//---------------------------------------------------------------------------
	NSLearningNetwork(LPCSTR dllPathName);

	int RemoveInputNormalization();
	int RemoveOutputNormalization();
	int SeedRandom(unsigned int seed);
	int Train(int epochs, int exemplars, double* inputData, double* desiredData);
	int Train(int epochs, int exemplars, double* inputData, double* desiredData, int cvExemplars, double* cvInputData, double* cvDesiredData);
	bool GetAutoComputeInputNormCoeff();
	bool GetAutoComputeOutputNormCoeff();
	double GetBestCost();
	CString GetBestWeightsPathName();
	int GetCostData(double *costData);
	int GetCrossValidationCostData(double *CVCostData);
	bool GetCrossValidationEnabled();
	int GetEpochOfBestCost();
	double GetInputNormMax();
	double GetInputNormMin();
	bool GetNormalizeInputByChannel();
	bool GetNormalizeOutputByChannel();
	int GetNumberOfEpochsTrained();
	double GetOutputNormMax();
	double GetOutputNormMin();
	bool GetSaveBestWeightsEnabled();
	bool GetSaveBestWeightsForTraining();
	int SetAutoComputeInputNormCoeff(bool autoComputeInputNormCoeff);
	int SetAutoComputeOutputNormCoeff(bool autoComputeOutputNormCoeff);
	int SetBestCost(double bestCost);
	int SetBestWeightsPathName(LPCSTR pathName);
	int SetCrossValidationEnabled(bool value);
	int SetInputNormMax(double inputNormMax);
	int SetInputNormMin(double inputNormMin);
	int SetNormalizeInputByChannel(bool normalizeInputByChannel);
	int SetNormalizeOutputByChannel(bool normalizeOutputByChannel);
	int SetOutputNormMax(double outputNormMax);
	int SetOutputNormMin(double outputNormMin);
	int SetSaveBestWeightsEnabled(bool value);
	int SetSaveBestWeightsForTraining(bool value);

protected:
	//---------------------------------------------------------------------------
	// Protected variables.
	//---------------------------------------------------------------------------
	NSTrain m_NSTrain;
	NSGetBestCost m_NSGetBestCost;
	NSSetBestCost m_NSSetBestCost;
	NSGetBestWeightsPathName m_NSGetBestWeightsPathName;
	NSSetBestWeightsPathName m_NSSetBestWeightsPathName;
	NSGetCrossValidationEnabled m_NSGetCrossValidationEnabled;
	NSSetCrossValidationEnabled m_NSSetCrossValidationEnabled;
	NSGetSaveBestWeightsEnabled m_NSGetSaveBestWeightsEnabled;
	NSSetSaveBestWeightsEnabled m_NSSetSaveBestWeightsEnabled;
	NSGetSaveBestWeightsForTraining m_NSGetSaveBestWeightsForTraining;
	NSSetSaveBestWeightsForTraining m_NSSetSaveBestWeightsForTraining;
	NSSetAutoComputeInputNormCoeff m_NSSetAutoComputeInputNormCoeff;
	NSGetAutoComputeInputNormCoeff m_NSGetAutoComputeInputNormCoeff;
	NSSetAutoComputeOutputNormCoeff m_NSSetAutoComputeOutputNormCoeff;
	NSGetAutoComputeOutputNormCoeff m_NSGetAutoComputeOutputNormCoeff;
	NSRemoveInputNormalization m_NSRemoveInputNormalization;
	NSRemoveOutputNormalization m_NSRemoveOutputNormalization;
	NSSetInputNormMin m_NSSetInputNormMin;
	NSGetInputNormMin m_NSGetInputNormMin;
	NSSetInputNormMax m_NSSetInputNormMax;
	NSGetInputNormMax m_NSGetInputNormMax;
	NSSetOutputNormMin m_NSSetOutputNormMin;
	NSGetOutputNormMin m_NSGetOutputNormMin;
	NSSetOutputNormMax m_NSSetOutputNormMax;
	NSGetOutputNormMax m_NSGetOutputNormMax;
	NSSetNormalizeInputByChannel m_NSSetNormalizeInputByChannel;
	NSGetNormalizeInputByChannel m_NSGetNormalizeInputByChannel;
	NSSetNormalizeOutputByChannel m_NSSetNormalizeOutputByChannel;
	NSGetNormalizeOutputByChannel m_NSGetNormalizeOutputByChannel;
	NSGetCrossValidationCostData m_NSGetCrossValidationCostData;
	NSGetCostData m_NSGetCostData;
	NSGetNumberOfEpochsTrained m_NSGetNumberOfEpochsTrained;
	NSGetEpochOfBestCost m_NSGetEpochOfBestCost;
	NSSeedRandom m_NSSeedRandom;
};

//===========================================================================
// CLASS: NSRecallNetwork
//===========================================================================
class NSRecallNetwork : public NSNetwork
{
public:
	//---------------------------------------------------------------------------
	// Public functions.
	//---------------------------------------------------------------------------
	NSRecallNetwork(LPCSTR dllPathName);
};