// - - - - - - - - - - - - - - - - - - - - - - -
// File: neuron.h                               |
// Purpose: provides interface for class Neuron |
// Author: Taivo Lints, Estonia                 |
// Date: May, 2003                              |
// Copyright: see copyright.txt                 |
// - - - - - - - - - - - - - - - - - - - - - - -

#ifndef NEURON_H
#define NEURON_H

#include "connection.h"
#include <vector>
using namespace std;

class Neuron {      // Represents a typical neuron for artificial neural
                    // networks. Activation function is sigmoidal (logistic
                    // function 1 / (1 + exp(-av)) where "a" is slope parameter
                    // and "v" is internal activity level). Neuron supports
                    // backpropagation learning.


  public:

    // ******************************
    // * Construction & Destruction *
    // ******************************

    Neuron(vector<Neuron*>* pvpNeurons, bool flag_comp_neuron);
                    // Neuron constructor. Needs a pointer to the vpNeurons
                    // vector where this neuron will belong (because it
                    // needs to communicate with other neurons). Also needs
                    // to know the type of this neuron (if flag_comp_neuron
                    // is "true", then it will be computational neuron;
                    // if "false", then input node).

    Neuron(const Neuron& rN);  // Neuron copy-constructor.

    Neuron& operator=(const Neuron& rN);  // Operator overloading.

    ~Neuron();      // Neuron destructor.


    // **************************
    // * Parameters & variables *
    // **************************

    vector<Neuron*>* pvpNeurons; // Pointer to the vpNeurons vector where this
                                 // neuron belongs.

    double treshold;         // Treshold (or bias) value for lowering or
                             // increasing the sum (internal activity level)
                             // before applying the activation function.

    double slope_parameter;  // Slope parameter of the sigmoid function
                             // ("a" in the equation 1 / (1 + exp(-av)) ).
                             // When the slope parameter approaches infinity,
                             // the sigmoid function becomes simply a
                             // treshold function.

    double learning_rate;    // How fast should neuron learn. 
                             // Too small makes learning too slow.
                             // Too big rate may give no learning results
                             // at all (i.e. no convergence).

    double max_weight;       // Maximal allowed weight for connections. Weights
                             // will be in range -max_weight..+max_weight.

    double output;           // Output value of this neuron.

    vector<Connection*> vpConnections;  // All connections owned by this neuron.
                             // If you decide to rearrange something in
                             // vpNeurons in your NeuralNetwork object, then
                             // do NOT forget to update this vector here!

    double error;            // Error value for backpropagation learning.

    // *************
    // * Functions *
    // *************

    void add_connection(int source, double weight); // Adds a connection
                             // to vpConnections vector. Does NOT verify
                             // it's correctness! "source" is source neuron's
                             // index in vpNeurons vector in class
                             // NeuralNetwork.
    
    void update();           // Reads inputs through connections and
                             // calculates the output.

    void learn();            // Modifies weights of the connections
                             // according to the error. Also backpropagates
                             // error. Should be applied starting from the
                             // last neuron and moving towards the input
                             // layer (to BACKpropagate the error).


  // *******************
  // * Protected stuff *
  // *******************

  // You can't use that stuff from outside code, except from child classes.

  protected:

    bool flag_comp_neuron;   // If true, then this neuron is computational
                             // neuron; if false, then it is input node.
                             // This flag is set by constructor.

};

#endif // NEURON_H