/*************************************************************************** * SRMTimeDrivenModel.cpp * * ------------------- * * copyright : (C) 2011 by Jesus Garrido and Francisco Naveros * * email : jgarrido@atc.ugr.es, fnaveros@atc.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 #include #include "../../include/neuron_model/SRMTimeDrivenModel.h" #include "../../include/neuron_model/VectorSRMState.h" #include "../../include/neuron_model/VectorNeuronState.h" #include "../../include/spike/EDLUTFileException.h" #include "../../include/spike/Neuron.h" #include "../../include/spike/InternalSpike.h" #include "../../include/spike/PropagatedSpike.h" #include "../../include/simulation/Utils.h" #include "../../include/openmp/openmp.h" using namespace std; void SRMTimeDrivenModel::LoadNeuronModel(string ConfigFile) throw (EDLUTFileException){ FILE *fh; long Currentline = 0L; fh=fopen(ConfigFile.c_str(),"rt"); if(!fh){ // Error: Neuron model file doesn't exist throw EDLUTFileException(13,59,31,1,Currentline); } Currentline=1L; skip_comments(fh,Currentline); if (!fscanf(fh, "%u", &this->NumberOfChannels)==1){ throw EDLUTFileException(13,57,3,1,Currentline); } this->tau = (float *) new float [this->NumberOfChannels]; this->W = (float *) new float [this->NumberOfChannels]; for (unsigned int i=0; iNumberOfChannels; ++i){ skip_comments(fh,Currentline); if(!fscanf(fh,"%f",&this->tau[i])==1){ throw EDLUTFileException(13,58,3,1,Currentline); } } skip_comments(fh,Currentline); if(!fscanf(fh,"%f",&this->vr)==1){ throw EDLUTFileException(13,56,3,1,Currentline); } for (unsigned int i=0; iNumberOfChannels; ++i){ skip_comments(fh,Currentline); if(!fscanf(fh,"%f",&this->W[i])==1){ throw EDLUTFileException(13,55,3,1,Currentline); } } skip_comments(fh,Currentline); if(!fscanf(fh,"%f",&this->r0)==1){ throw EDLUTFileException(13,54,3,1,Currentline); } skip_comments(fh,Currentline); if(!fscanf(fh,"%f",&this->v0)==1){ throw EDLUTFileException(13,53,3,1,Currentline); } skip_comments(fh,Currentline); if(!fscanf(fh,"%f",&this->vf)==1){ throw EDLUTFileException(13,52,3,1,Currentline); } skip_comments(fh,Currentline); if(!fscanf(fh,"%f",&this->tauabs)==1){ throw EDLUTFileException(13,51,3,1,Currentline); } skip_comments(fh,Currentline); if(!fscanf(fh,"%f",&this->taurel)==1){ throw EDLUTFileException(13,50,3,1,Currentline); } // Initialize the neuron state this->InitialState = (VectorSRMState *) new VectorSRMState(5,this->NumberOfChannels, true); //TIME DRIVEN STEP this->integrationMethod = LoadIntegrationMethod::loadIntegrationMethod((TimeDrivenNeuronModel *)this, fh, &Currentline, 0, 0, 0); } void SRMTimeDrivenModel::SynapsisEffect(int index, Interconnection * InputConnection){ ((VectorSRMState *) this->GetVectorNeuronState())->AddActivity(index, InputConnection); } float SRMTimeDrivenModel::PotentialIncrement(int index, VectorSRMState * State){ float Increment = 0; for (unsigned int i=0; iNumberOfChannels; ++i){ VectorBufferedState::Iterator itEnd = State->End(); for (VectorBufferedState::Iterator it=State->Begin(index,i); it!=itEnd; ++it){ float TimeDifference = it.GetSpikeTime(); float Weight = it.GetConnection()->GetWeight(); float EPSPMax = sqrt(this->tau[i]/2)*ExponentialTable::GetResult(-0.5); float EPSP = sqrt(TimeDifference)*ExponentialTable::GetResult(-(TimeDifference/this->tau[i]))/EPSPMax; // Inhibitory channels must define negative W values Increment += Weight*this->W[i]*EPSP; } } return Increment; } bool SRMTimeDrivenModel::CheckSpikeAt(int index, VectorSRMState * State, double CurrentTime){ double Probability = State->GetStateVariableAt(index,4); return (((double) rand())/RAND_MAXtau; this->tau = 0; delete [] this->W; this->W = 0; } void SRMTimeDrivenModel::LoadNeuronModel() throw (EDLUTFileException) { this->LoadNeuronModel(this->GetModelID() + ".cfg"); } VectorNeuronState * SRMTimeDrivenModel::InitializeState(){ return ((VectorSRMState *) InitialState); } InternalSpike * SRMTimeDrivenModel::ProcessInputSpike(Interconnection * inter, Neuron * target, double time){ InternalSpike * ProducedSpike = 0; // Update Cell State if (this->UpdateState(target->GetIndex_VectorNeuronState(),target->GetVectorNeuronState(),time)){ ProducedSpike = new InternalSpike(time,target); } // Add the effect of the input spike this->SynapsisEffect(target->GetIndex_VectorNeuronState(),inter); return ProducedSpike; } bool SRMTimeDrivenModel::UpdateState(int index, VectorNeuronState * State, double CurrentTime){ float * sqrt_tau = new float[this->NumberOfChannels]; for (unsigned int i=0; iNumberOfChannels; ++i){ sqrt_tau[i]=sqrt(this->tau[i]/2)*ExponentialTable::GetResult(-0.5); } VectorSRMState * SRMstate=(VectorSRMState *)State; bool * internalSpike=State->getInternalSpike(); int Size=State->GetSizeState(); int i; double ElapsedTime; for (i=0; iGetLastUpdateTime(i); State->AddElapsedTime(i, ElapsedTime); /////////////////////////// float Increment = 0; for (unsigned int j=0; jNumberOfChannels; ++j){ VectorBufferedState::Iterator itEnd = SRMstate->End(); for (VectorBufferedState::Iterator it=SRMstate->Begin(i,j); it!=itEnd; ++it){ float TimeDifference = it.GetSpikeTime(); float Weight = it.GetConnection()->GetWeight(); float EPSPMax = sqrt_tau[j]; float EPSP = sqrt(TimeDifference)*ExponentialTable::GetResult(-(TimeDifference/this->tau[j]))/EPSPMax; // Inhibitory channels must define negative W values Increment += Weight*this->W[j]*EPSP; } } /////////////////////////// float Potential = this->vr + Increment; State->SetStateVariableAt(i,1,Potential); float FiringRate; if((Potential-this->v0) > (10*this->vf)){ FiringRate = this->r0*(Potential-this->v0)/this->vf; } else { float texp=ExponentialTable::GetResult((Potential-this->v0)/this->vf); FiringRate =this->r0*log(1+texp); } //double texp = ExponentialTable::GetResult((Potential-this->v0)/this->vf); //double FiringRate = this->r0 * log(1+texp); State->SetStateVariableAt(i,2,FiringRate); double TimeSinceSpike = State->GetLastSpikeTime(i); float Aux = TimeSinceSpike-this->tauabs; float Refractoriness = 0; if (TimeSinceSpike>this->tauabs){ Refractoriness = 1./(1.+(this->taurel*this->taurel)/(Aux*Aux)); } State->SetStateVariableAt(i,3,Refractoriness); float Probability = (1 - ExponentialTable::GetResult(-FiringRate*Refractoriness*((float)ElapsedTime))); State->SetStateVariableAt(i,4,Probability); State->SetLastUpdateTime(i,CurrentTime); if (this->CheckSpikeAt(i,(VectorSRMState *) State, CurrentTime)){ State->NewFiredSpike(i); internalSpike[i]=true; }else{ internalSpike[i]=false; } float * NeuronState=State->GetStateVariableAt(i); this->integrationMethod->NextDifferentialEcuationValue(i,NeuronState,NULL); } delete [] sqrt_tau; return false; } ostream & SRMTimeDrivenModel::PrintInfo(ostream & out) { out << "- SRM Time-Driven Model: " << this->GetModelID() << endl; out << "\tNumber of channels: " << this->NumberOfChannels << endl; out << "\tTau: "; for (unsigned int i=0; iNumberOfChannels; ++i){ out << "\t" << this->tau[i]; } out << endl << "\tVresting: " << this->vr << endl; out << "\tWeight Scale: "; for (unsigned int i=0; iNumberOfChannels; ++i){ out << "\t" << this->W[i]; } out << endl << "\tFiring Rate: " << this->r0 << "Hz\tVthreshold: " << this->v0 << "V" << endl; out << "\tGain Factor: " << this->vf << "\tAbsolute Refractory Period: " << this->tauabs << "s\tRelative Refractory Period: " << this->taurel << "s" << endl; return out; } void SRMTimeDrivenModel::InitializeStates(int N_neurons, int OpenMPQueueIndex){ VectorSRMState * state = (VectorSRMState *) this->InitialState; float initialization[] = {0.0,0.0,0.0,0.0,0.0}; //Initialize the state variables state->InitializeSRMStates(N_neurons, initialization); for (int j=0; jNumberOfChannels; ++i){ state->SetBufferAmplitude(j,i,8*this->tau[i]); } } this->integrationMethod->InitializeStates(N_neurons, initialization); } int SRMTimeDrivenModel::CheckSynapseTypeNumber(int Type){ if(Type=0){ return Type; }else{ cout<<"Neuron model "<GetTypeID()<<", "<GetModelID()<<" does not support input synapses of type "<