#include "Cells.h"
#include "Synapses.h"
#include "Network.h"
#include <iostream>
#include <stdlib.h>
using namespace std;
#define DEBUG_RUN 0
Neuron::Neuron(int np, int ns): DynSys(np,ns) {
Id.LocalID = Network::AddNeuron(this);
}
void Neuron::Spike() {
#if DEBUG_RUN > 0
cout << " Spike from cell " << Id.LocalID << endl;
#endif
Network::AddSpike(Id);
}
void Neuron::PreTimeStep() {
#if DEBUG_RUN > 3
cout << " Neuron: determining inputs" << endl;
#endif
// Determine input from all synapses:
PulsesIn = 0;
I_external = 0;
int nSynapse = SynapseList.size();
for(int iSynapse=0; iSynapse<nSynapse; iSynapse++) {
#if DEBUG_RUN > 4
cout << " Checking synapse " << iSynapse << " of " << nSynapse << endl;
#endif
PulsesIn += SynapseList.at(iSynapse)->GetPulse(State[0]);
I_external += SynapseList.at(iSynapse)->GetCurrent(State[0]);
}
State[0]+=PulsesIn;
}
void Neuron::AddSynapse(Synapse* s) {
SynapseList.push_back(s);
//#if DEBUG_INPUT > 3
//cout << " Synapse " << s << " added to cell " << Id.LocalID << endl;
//#endif
}
NeuronTypeLIF::NeuronTypeLIF(): Neuron(4,1) {
/*
ParamId | Description
--------+-----------
0 | C
1 | V_rest
2 | V_thres
3 | V_reset
StateId | Description
--------+----------
0 | V
*/
MirrorVm = 0;
}
void NeuronTypeLIF::VectorField(double* dState, double* StateIn) {
// dV = -(V-Vrest)/tau
dState[0] = (I_external-(StateIn[0]-Param[1]))/Param[0];
}
void NeuronTypeLIF::PostTimeStep() {
// Check for threshold passing:
if(State[0] > Param[2]) {
State[0] = Param[3];
MirrorVm = 30;
Spike();
} else {
MirrorVm = State[0];
}
}
double NeuronTypeLIF::GetVm() {
return MirrorVm;
}
NeuronTypeIzhikevich::NeuronTypeIzhikevich(): Neuron(5,2) {
/*
ParamId | Description
--------+-----------
0 | Injected current (const)
1 | a
2 | b
3 | c
4 | d
StateId | Description
--------+-----------
0 | V
1 | u
*/
}
void NeuronTypeIzhikevich::VectorField(double* dState, double* StateIn) {
// dV = 0.04v^2 + 5v + 140 - u + I
// du = a(bv-u)
dState[0] = 0.04*StateIn[0]*StateIn[0] + 5*StateIn[0] + 140 - StateIn[1] + Param[0] + I_external;
dState[1] = Param[1]*(Param[2]*StateIn[0]-StateIn[1]);
}
void NeuronTypeIzhikevich::PostTimeStep() {
// if(Vm>=30)
if(State[0] >= 30) {
State[0] = Param[3];
State[1] = State[1]+Param[4];
Spike();
}
}
NeuronTypePoisson::NeuronTypePoisson(): Neuron(1,1) {
/*
ParamId | Description
--------+-----------
0 | Poisson rate (s^-1)
StateId | Description
--------+-----------
0 | V
*/
}
void NeuronTypePoisson::VectorField(double* dState, double* StateIn) {
dState[0]=0;
}
void NeuronTypePoisson::PreTimeStep() {
double r = ((double)rand())/RAND_MAX;
if(r<DynSys::dt*Param[0]/1000) { // Factor 1000 corrects for rate expressed in s^-1, while time is measured in ms by default
State[0] = 1;
} else {
State[0] = 0;
}
}
void NeuronTypePoisson::PostTimeStep() {
if(State[0]>0) Spike();
}