/***************************************************************************
* TimeDrivenPropagatedSpike.cpp *
* ------------------- *
* copyright : (C) 2015 by Francisco Naveros *
* email : fnaveros@ugr.es *
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "../../include/spike/TimeDrivenPropagatedSpike.h"
#include "../../include/spike/Interconnection.h"
#include "../../include/spike/Neuron.h"
#include "../../include/spike/InternalSpike.h"
#include "../../include/neuron_model/NeuronModel.h"
#include "../../include/simulation/Simulation.h"
#include "../../include/simulation/EventQueue.h"
#include "../../include/learning_rules/LearningRule.h"
#include "../../include/learning_rules/AdditiveKernelChange.h"
#include "../../include/spike/Neuron.h"
#include "../../include/openmp/openmp.h"
TimeDrivenPropagatedSpike::TimeDrivenPropagatedSpike(double NewTime, int NewOpenMP_index, int NewMaxSize):Spike(NewTime, NULL), OpenMP_index(NewOpenMP_index), MaxSize(NewMaxSize), N_Elements(0) {
N_ConnectionsWithEqualDelay=new int[NewMaxSize];
ConnectionsWithEqualDelay=(Interconnection **) new Interconnection * [NewMaxSize];
}
TimeDrivenPropagatedSpike::~TimeDrivenPropagatedSpike(){
delete N_ConnectionsWithEqualDelay;
delete ConnectionsWithEqualDelay;
}
int TimeDrivenPropagatedSpike::GetN_Elementes(){
return N_Elements;
}
int TimeDrivenPropagatedSpike::GetMaxSize(){
return MaxSize;
}
bool TimeDrivenPropagatedSpike::IncludeNewSource(int NewN_connections, Interconnection * NewConnections){
N_ConnectionsWithEqualDelay[N_Elements]=NewN_connections;
ConnectionsWithEqualDelay[N_Elements]=NewConnections;
N_Elements++;
if(N_Elements<MaxSize){
return false;
}
return true;
}
//Optimized function. This function propagates all neuron output spikes that have the same delay.
void TimeDrivenPropagatedSpike::ProcessEvent(Simulation * CurrentSimulation, int RealTimeRestriction){
if(RealTimeRestriction<2){
CurrentSimulation->IncrementTotalPropagateEventCounter(omp_get_thread_num());
Interconnection * inter;
for(int i=0; i<N_Elements; i++){
inter=ConnectionsWithEqualDelay[i];
CurrentSimulation->IncrementTotalPropagateCounter(omp_get_thread_num(), N_ConnectionsWithEqualDelay[i]);
for (int j=0; j<N_ConnectionsWithEqualDelay[i]; j++){
Neuron * TargetNeuron = inter->GetTarget(); // target of the spike
InternalSpike * Generated = TargetNeuron->GetNeuronModel()->ProcessInputSpike(inter, TargetNeuron, this->time);
if (Generated!=0){
CurrentSimulation->GetQueue()->InsertEvent(OpenMP_index,Generated);
}
if(RealTimeRestriction<1){
LearningRule * ConnectionRule = inter->GetWeightChange_withoutPost();
// If learning, change weights
if(ConnectionRule != 0){
ConnectionRule->ApplyPreSynapticSpike(inter,this->time);
}
ConnectionRule = inter->GetWeightChange_withPost();
// If learning, change weights
if(ConnectionRule != 0){
ConnectionRule->ApplyPreSynapticSpike(inter,this->time);
}
}
inter++;
}
}
}
}
//Optimized function. This function propagates all neuron output spikes that have the same delay.
void TimeDrivenPropagatedSpike::ProcessEvent(Simulation * CurrentSimulation){
CurrentSimulation->IncrementTotalPropagateEventCounter(omp_get_thread_num());
Interconnection * inter;
for(int i=0; i<N_Elements; i++){
inter=ConnectionsWithEqualDelay[i];
CurrentSimulation->IncrementTotalPropagateCounter(omp_get_thread_num(), N_ConnectionsWithEqualDelay[i]);
for (int j=0; j<N_ConnectionsWithEqualDelay[i]; j++){
Neuron * TargetNeuron = inter->GetTarget(); // target of the spike
InternalSpike * Generated = TargetNeuron->GetNeuronModel()->ProcessInputSpike(inter, TargetNeuron, this->time);
if (Generated!=0){
CurrentSimulation->GetQueue()->InsertEvent(OpenMP_index,Generated);
}
LearningRule * ConnectionRule = inter->GetWeightChange_withoutPost();
// If learning, change weights
if(ConnectionRule != 0){
ConnectionRule->ApplyPreSynapticSpike(inter,this->time);
}
ConnectionRule = inter->GetWeightChange_withPost();
// If learning, change weights
if(ConnectionRule != 0){
ConnectionRule->ApplyPreSynapticSpike(inter,this->time);
}
inter++;
}
}
}
int TimeDrivenPropagatedSpike::GetOpenMP_index() const{
return OpenMP_index;
}
void TimeDrivenPropagatedSpike::PrintType(){
cout<<"TimeDrivenPropagatedSpike"<<endl;
}