#include "recall.h"

void setFunctionIO(NSFloat*, int, int, void*);

typedef BOOL (*OnEpochEnded_FUNCTION)(void *);



class NSLearningNetwork : public NSRecallNetwork
{
public:
                         NSLearningNetwork();
     int                 createNetwork();
     int                 train(int, int, double *, double *, int, double *, double *);
     int                 destroyNetwork();
     void                setDesiredFunctionIO(NSFloat *);
     int                 getResponse(int, double *, double *);
     int                 getSensitivity(int, double *, double *&, double);
     int                 randomizeWeights();
     int                 resetNetwork();
     int                 setBestCost(double);
     int                 getBestCost(double &);
     int                 getEpochOfBestCost(int &);
     int                 setBestWeightsPathName(char *);
     int                 getBestWeightsPathName(char *, int, int &);
     int                 setSaveBestWeightsEnabled(bool);
     int                 getSaveBestWeightsEnabled(bool &);
     int                 setSaveBestWeightsForTraining(bool);
     int                 getSaveBestWeightsForTraining(bool &);
     int                 setCrossValidationEnabled(bool);
     int                 getCrossValidationEnabled(bool &);
     int                 getInput(double *, double *, double, double *);
     int                 setAutoComputeInputNormCoeff(bool);
     int                 getAutoComputeInputNormCoeff(bool &);
     int                 setAutoComputeOutputNormCoeff(bool);
     int                 getAutoComputeOutputNormCoeff(bool &);
     int                 removeInputNormalization();
     int                 removeOutputNormalization();
     int                 setInputNormMin(double);
     int                 getInputNormMin(double &);
     int                 setInputNormMax(double);
     int                 getInputNormMax(double &);
     int                 setOutputNormMin(double);
     int                 getOutputNormMin(double &);
     int                 setOutputNormMax(double);
     int                 getOutputNormMax(double &);
     int                 setNormalizeInputByChannel(bool);
     int                 getNormalizeInputByChannel(bool &);
     int                 setNormalizeOutputByChannel(bool);
     int                 getNormalizeOutputByChannel(bool &);
     int                 getCostData(double *);
     int                 getCrossValidationCostData(double *);
     int                 getNumberOfEpochsTrained(int &);
     int                 seedRandom(unsigned int);

     int                 setUpdateMethod(int){return 2;};
     int                 getUpdateMethod(int &){return 2;};
     int                 setCustomExemplarsPerUpdate(int){return 2;};
     int                 getCustomExemplarsPerUpdate(int &){return 2;};
     int                 getGradient(double *, double *){return 2;};
     int                 setNumberOfInputs(int){return 2;};
     int                 setNumberOfOutputs(int){return 2;};
     int                 getNumberOfHiddenLayers(int &){return 2;};
     int                 setNumberOfHiddenLayerPEs(int, int){return 2;};
     int                 getNumberOfHiddenLayerPEs(int, int &){return 2;};
     int                 getNumberOfStepSizes(int &){return 2;};
     int                 setStepSize(int, double){return 2;};
     int                 getStepSize(int, double &){return 2;};
     int                 bumpStepSizes(double){return 2;};
     int                 getNumberOfMomentums(int &){return 2;};
     int                 setMomentum(int, double){return 2;};
     int                 getMomentum(int, double &){return 2;};
     int                 setSamplesPerExemplar(int){return 2;};
     int                 getSamplesPerExemplar(int &){return 2;};
     int                 setSamplesPerExemplarBackprop(int){return 2;};
     int                 getSamplesPerExemplarBackprop(int &){return 2;};
     int                 isDynamicNetwork(bool &){return 2;};
     int                 getNumberOfTDNNAxons(int &){return 2;};
     int                 setNumberOfTDNNAxonTaps(int, int){return 2;};
     int                 getNumberOfTDNNAxonTaps(int, int &){return 2;};
     int                 setOnEpochEndedFunctionPointer(void *){return 2;};
     int                 getCurrentCost(double &){return 2;};
     int                 getCurrentCrossValidationCost(double &){return 2;};
     int                 setInputDataMask(int *){return 2;};
     int                 getInputDataMask(int *){return 2;};
     int                 removeInputDataMask(bool){return 2;};
     int                 setUseRecencyOfObservationScaling(bool){return 2;};
     int                 setUseDirectionOfChangeScaling(bool){return 2;};
     int                 setUseMagnitudeOfChangeScaling(bool){return 2;};
     int                 setSmallChangeScale(double){return 2;};
     int                 setLargeChangeScale(double){return 2;};
     int                 setRightDirectionScale(double){return 2;};
     int                 setWrongDirectionScale(double){return 2;};
     int                 setSmallChangeRightDirectionScale(double){return 2;};
     int                 setLargeChangeRightDirectionScale(double){return 2;};
     int                 setSmallChangeWrongDirectionScale(double){return 2;};
     int                 setLargeChangeWrongDirectionScale(double){return 2;};
     int                 setDiscountRate(double){return 2;};
     int                 setDataPreDifferenced(bool){return 2;};
     int                 setGradientDescentMethod(int){return 2;};
     int                 getGradientDescentMethod(int &){return 2;};
     int                 setOutputLayerTransferFunction(int){return 2;};
     int                 getOutputLayerTransferFunction(int &){return 2;};
     int                 setHiddenLayerTransferFunction(int, int) {return 2;};
     int                 getHiddenLayerTransferFunction(int, int &) {return 2;};
     int                 setHiddenLayerBeta(int, double) {return 2;};
     int                 getHiddenLayerBeta(int, double &) {return 2;};
     int                 setOutputLayerBeta(double) {return 2;};
     int                 getOutputLayerBeta(double &) {return 2;};
     int                 setHiddenLayerBiasVariance(int, double) {return 2;};
     int                 getHiddenLayerBiasVariance(int, double &) {return 2;};
     int                 setOutputLayerBiasVariance(double) {return 2;};
     int                 getOutputLayerBiasVariance(double &) {return 2;};
     int                 getMAPE(int, double *, double *, int, double &) {return 2;};


protected:
     int                 startBackprop();
     int                 completeBackprop();
     int                 updateWeights();
     int                 createComponents();
     int                 setInitializations();
     int                 setInterconnections();
     int                 postInterconnections();
     int                 preRunGetReady();
     int                 loadComponentWeights(FILE *&);
     int                 saveComponentWeights(FILE *&);
     int                 startTesting();
     int                 endTesting();
     int                 setDefaultStepSizeDivisor(int);
     int                 fireConclude();
     int                 computeInputNormCoeff(double *, int);
     int                 computeOutputNormCoeff(double *, int);
     int                 computeNormCoeff(double *, double *, double *, int, int, double, double, bool);
     int                 computeInputNormCoeffAfterMask(double *, double *, double *, int, double, double, bool);
     int                 computeAmplitudeAndOffset(double &, double &, double, double, double, double);
BackAxon *inputAxonBackprop;
BackFullSynapse *hidden1SynapseBackprop;
Gradient *hidden1SynapseBackpropGradient;
BackAxon *hidden1AxonBackprop;
Gradient *hidden1AxonBackpropGradient;
BackFullSynapse *hidden2SynapseBackprop;
Gradient *hidden2SynapseBackpropGradient;
BackAxon *hidden2AxonBackprop;
Gradient *hidden2AxonBackpropGradient;
BackFullSynapse *hidden3SynapseBackprop;
Gradient *hidden3SynapseBackpropGradient;
BackAxon *hidden3AxonBackprop;
Gradient *hidden3AxonBackpropGradient;
BackFullSynapse *hidden4SynapseBackprop;
Gradient *hidden4SynapseBackpropGradient;
BackAxon *hidden4AxonBackprop;
Gradient *hidden4AxonBackpropGradient;
BackFullSynapse *hidden5SynapseBackprop;
Gradient *hidden5SynapseBackpropGradient;
BackAxon *hidden5AxonBackprop;
Gradient *hidden5AxonBackpropGradient;
BackFullSynapse *outputSynapseBackprop;
Gradient *outputSynapseBackpropGradient;
BackAxon *outputAxonBackprop;
Gradient *outputAxonBackpropGradient;
L2Criterion *criterion;
BackCriteriaControl *criterionBackprop;
BackDynamicControl *controlBackprop;
BackFullSynapse *recurrentSynapseBackprop;
Gradient *recurrentSynapseBackpropGradient;
BackFullSynapse *forwardSynapseBackprop;
Gradient *forwardSynapseBackpropGradient;

     FunctionIO          *desiredDataFunctionIO;
     double               *m_dpDesiredExemplarData;
     char                *m_cpBestWeightsPathName;
     bool                m_bSaveBestWeightsEnabled;
     int                 m_iEpochOfBestCost;
     bool                m_bSaveBestWeightsForTraining;
     bool                m_bCrossValidationEnabled;
     int                 m_iUpdateMethod;
     int                 m_iCustomExemplarsPerUpdate;
     bool                m_bAutoComputeInputNormCoeff;
     bool                m_bAutoComputeOutputNormCoeff;
     double               m_fInputNormMin;
     double               m_fInputNormMax;
     double               m_fOutputNormMin;
     double               m_fOutputNormMax;
     bool                m_bNormalizeInputByChannel;
     bool                m_bNormalizeOutputByChannel;
     int                 m_iGradientDescentMethod;
     int                 m_iNumberOfConjugateGradientComponents;
     int                 m_iSamplesPerExemplar;
     int                 m_iSamplesPerExemplarBackprop;
     double               *m_dpCostData;
     double               *m_dpCVCostData;
     int                 m_iNumberOfEpochsTrained;
     OnEpochEnded_FUNCTION onEpochEnded;
     double               m_fCurrentCost;
     double               m_fCurrentCVCost;
};
