Skip to content
Snippets Groups Projects
NeuralNetwork.cpp 3.87 KiB
Newer Older
  • Learn to ignore specific revisions
  • /**
     * DESCRIPTION OF THE FILE
     *
     * @author Michal Kravčenko
     * @date 13.6.18 - 
     */
    
    #include "NeuralNetwork.h"
    
    
    NeuralNetwork::NeuralNetwork() {
        this->neurons = new std::vector<Neuron*>(0);
    }
    
    NeuralNetwork::~NeuralNetwork() {
        if(this->neurons){
            delete this->neurons;
            this->neurons = nullptr;
        }
        if(this->output_neurons){
            delete this->output_neurons;
            this->output_neurons = nullptr;
        }
        if(this->input_neurons){
            delete this->input_neurons;
            this->input_neurons = nullptr;
        }
        if(this->active_eval_set){
            delete this->active_eval_set;
            this->active_eval_set = nullptr;
        }
    }
    
    void NeuralNetwork::add_neuron(Neuron *n) {
        this->neurons->push_back(n);
        this->in_out_determined = false;
    }
    
    void NeuralNetwork::determine_inputs_outputs() {
        if(this->output_neurons){
            delete this->output_neurons;
        }
    
        if(this->input_neurons){
            delete this->input_neurons;
        }
    
        this->output_neurons = new std::vector<Neuron*>(0);
        this->input_neurons = new std::vector<Neuron*>(0);
    
        if(this->active_eval_set == nullptr){
            this->active_eval_set = new std::vector<Neuron*>(this->neurons->size() * 2);
        }
        else{
            this->active_eval_set->resize(this->neurons->size() * 2);
        }
    
        for(Neuron* neuron: *this->neurons){
            if(neuron->get_connections_out()->empty()){
                //this neuron has no outgoing connections, it is the output neuron
                this->output_neurons->push_back(neuron);
            }
            else if(neuron->get_connections_in()->empty()){
                //this neuron has no incoming connections, it is the input neuron
                this->input_neurons->push_back(neuron);
            }
        }
    
        this->n_inputs = (int)this->input_neurons->size();
        this->n_outputs = (int)this->output_neurons->size();
    
        this->in_out_determined = true;
    }
    
    void NeuralNetwork::eval_single(std::vector<double> &input, std::vector<double> &output) {
        if(!this->in_out_determined){
            this->determine_inputs_outputs();
        }
    
    
        if(this->n_inputs != input.size()){
            printf("Error, input size != Network input size\n");
            return;
        }
    
        if(this->n_outputs != output.size()){
            printf("Error, output size != Network output size\n");
            return;
        }
    
        std::fill(output.begin(), output.end(), 0.0);
    
        //reset of the potentials
        for(Neuron* neuron: *this->neurons){
            neuron->set_potential(0.0);
            neuron->set_saturation_in(0);
            neuron->set_saturation_out(0);
        }
    
    
        int active_set_size[2];
        active_set_size[0] = 0;
        active_set_size[1] = 0;
    
        int idx1 = 0, idx2 = 1;
    
        active_set_size[0] = this->n_inputs;
        int i = 0;
        auto n = this->neurons->size();
    
        for(Neuron* neuron: *this->input_neurons){
    
            this->active_eval_set->at(i) = neuron;
    
            neuron->set_potential(input[i]);
    
    
            ++i;
        }
        Neuron* active_neuron;
        Neuron* target_neuron;
    
        while(active_set_size[idx1] > 0){
    
            //we iterate through the active neurons and propagate the signal
            for(i = 0; i < active_set_size[idx1]; ++i){
                active_neuron = this->active_eval_set->at(i + n * idx1);
                active_neuron->activate();
    
                for(Connection* connection: *(active_neuron->get_connections_out())){
                    connection->pass_signal();
    
                    target_neuron = connection->get_neuron_out();
                    target_neuron->adjust_saturation_in(1);
    
                    if(target_neuron->is_saturated_in()){
                        this->active_eval_set->at(active_set_size[idx2] + n * idx2) = target_neuron;
                        active_set_size[idx2]++;
                    }
                }
            }
    
            idx1 = idx2;
            idx2 = (idx1 + 1) % 2;
    
            active_set_size[idx2] = 0;
        }
    
        i = 0;
        for(Neuron* neuron: *this->output_neurons){
    
            output[i] = neuron->get_state();
            ++i;
        }
    }