/***************************************************************************
 *                                                                         *
 *                       NNF - Neural Net Framework                        *
 *        An high-speed implementation of feed-forward neural nets         *
 *                                                                         *
 *                                                                         *
 *                                                                         *
 *                                                                         *
 *   Copyright (C) 2005 by Alessandro Presta                               *
 *   alessandro.presta@gmail.com                                           *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Lesser General Public License as        *
 *   published by the Free Software Foundation; either version 2.1 of the  *
 *   License, or (at your option) any later version.                       *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU Lesser General Public      *
 *   License                                                               *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
 
/***************************************************************************
 *   Adaption: by Dick van Harten, 18 september 2005, dick@vanharten.info  *
 *                                                                         *
 *   Change:   - c++ style comments replaced by c-style comments to        *
 *               accommodate ISO C90                                       * 
 *             - changed double by double				   *
 *	       - moved includes from headerfile to c file		   *
 ***************************************************************************/

 
 
#ifndef  __NNF_H__
#define  __NNF_H__

#include 

/* -- NEURON ACTIVATION FUNCTIONS						-- */
/* -- The three main functions for calculating input for one neuron		-- */

/* -- sigmoidal-logistic: returns continuous values between 0 and 1		-- */
#define  NNF_FUNC_SIGMA_LOGISTIC(x) ( 1 / (1 + exp(-(x))) )  

/* -- sigmoidal-hyperbolic: returns continuous values between -1 and 1		-- */
#define  NNF_FUNC_SIGMA_HYPERBOLIC(x) ( tanh((x)) )

/* -- step: returns 0 if x < t, 1 if x >= t			 		-- */
#define  NNF_FUNC_STEP(x,t)  ( (x) >= (t) ? 1 : 0 )

/* -- sign: returns the sign of x						-- */
#define  NNF_FUNC_SIGN(x)  ( (x) >= 0 ? 1 : -1 )

/* -- Enumerator for the activation functions					-- */
enum {
	NNF_SIGMA_LOGISTIC,
	NNF_SIGMA_HYPERBOLIC,
	NNF_STEP,
	NNF_SIGN
};

/* -- NEURAL NET DATA STRUCTURE							-- */
/* -- The structure for managing a neural net					-- */

/* -- Neural net type definition	   					-- */
typedef struct {
 
 	int layers;		/* -- layers of the net			 	-- */
 	int *neurons;		/* -- neurons in each layer		 	-- */
 	double epsilon;		/* -- learning constant			 	-- */
 	int activationFunction;	/* -- chosen activation function	 	-- */
 	double step;		/* -- (only for step function)		 	-- */
 	double ***weight;	/* -- weight of the synapse between two neurons	-- */              
 	double **bias;		/* -- bias weight of each neuron		-- */
 	double **value;		/* -- values for each neuron			-- */
 	double **delta;		/* -- delta for each neuron			-- */
 
} NNF_NeuralNet;


void NNF_Init(NNF_NeuralNet* net, int layrs, int neurs[], int range);
		/* -- initializes the neural net							-- */
		/* --   net is a pointer to the neural net						-- */
		/* --   layrs is the number of layers in the net					-- */
		/* --   neurs[] is the array of the neurons						-- */
		/* --	(its size must correspond to the number of layers)				-- */
		/* --   range is the limit for random weights generated during the initialization	-- */
	
void NNF_Load(NNF_NeuralNet* net, FILE* loadFile);
		/* -- initializes the neural net loading it from a file					-- */
		/* --   net is a pointer to the neural net						-- */
		/* --   loadFile is a pointer to a text file, usually opened with fopen("filename","r")	-- */

void NNF_FileInit(NNF_NeuralNet* net, FILE* loadFile);
		/* -- initializes the neural net loading it from a file					-- */
		/* --   net is a pointer to the neural net						-- */
		/* --   loadFile is a pointer to a text file, usually opened with fopen("filename","r")	-- */


void NNF_Save(NNF_NeuralNet* net, FILE* saveFile);
		/* -- saves the neural net configuration on a file					-- */
		/* --   net is a pointer to the neural net						-- */
		/* --   saveFile is a pointer to a text file, usually opened with fopen("filename","w")	-- */

#ifdef ALL
void NNF_Reset(NNF_NeuralNet* net, int range);
		/* -- resets the weights of the neural net						-- */
		/* --   net is a pointer to the neural net						-- */
		/* --   range is the limit for random weights						-- */	
#endif
				
double* NNF_Execute(NNF_NeuralNet* net, double input[]);
		/* -- executes the neural net with the given input					-- */
		/* --   net is a pointer to the neural net						-- */
		/* --   input[] is the array of the input 						-- */
		/* --	(its size must correspond to the number of neurons in the first layer)		-- */
		/* --   return value is an array with the calculated output				-- */
		/* --	(its size corresponds to the number of neurons in the last layer		-- */

#ifdef TRAIN	
void NNF_BackPropagate(NNF_NeuralNet* net, double desired[]);
		/* -- teaches the neural net associating the desired values with the given output	-- */
		/* --   net is a pointer to the neural net						-- */
		/* --   desired[] is the array of the desired output					-- */
		/* --	(its size must correspond to the number of neurons in the last layer		-- */
#endif
		
#ifdef ALL
void NNF_Delete(NNF_NeuralNet* net);
		/* -- deletes the neural net; calls free() for all the dinamically allocated memory	-- */
		/* -- call this function when you don't need the net anymore				-- */
		


#endif
#endif