📄 fastneuron.cpp
字号:
/*************************************************************************** fastneuron.cpp - description ------------------- begin : Tue Jan 22 2002 copyright : (C) 2002 by Matt Grover email : mgrover@amygdala.org ***************************************************************************//*************************************************************************** * * * 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 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/#include <cmath>#include <iostream>#include <stdexcept>#include "fastneuron.h"#include "functionlookup.h"#include "network.h"#include "physicalproperties.h"#include "utilities.h"#include "logging.h"using namespace std;using namespace Amygdala;FastNeuronProperties::FastNeuronProperties():SpikingNeuronProperties(){}FastNeuronProperties::FastNeuronProperties(const FastNeuronProperties& rhs): SpikingNeuronProperties(rhs), memTimeConst(rhs.memTimeConst) {}FastNeuronProperties::FastNeuronProperties(bool initializePhysicalProps): SpikingNeuronProperties(initializePhysicalProps){}FastNeuronProperties::~FastNeuronProperties(){}FastNeuronProperties* FastNeuronProperties::Copy() const{ return new FastNeuronProperties(*this); }FastNeuron::FastNeuron(AmIdInt neuronId, const FastNeuronProperties& props): SpikingNeuron(neuronId, props){ pspLookup = 0; pspLSize = 0; pspStepSize = 0; InitLookup();}FastNeuron::~FastNeuron(){}void FastNeuron::ProcessInput(const AmTimeInt& inTime){ LOGGER(6, "Neuron " << nId << "InputSpike"); // If the neuron is within a refractory period, if ( (inTime - spikeTime) <= refPeriod ) { if (inTime > refPeriod) { dendrite->ResetTrigger(); return; } } float inWeightPos, inWeightNeg; dendrite->GetStimulationLevel(inWeightPos, inWeightNeg); // If a spike is scheduled for this time step and the pre-synaptic // spike is excitatory, don't do anything more. if (inTime == schedSpikeTime) { if ((inWeightPos+inWeightNeg) > 0.0) { return; } } unsigned int tblIndex = (unsigned int)((float)(inTime - currTime) * stepSizeInv); if (tblIndex < pspLSize) { // don't go beyond the end of the tables membranePtnl = membranePtnl * pspLookup[tblIndex]; membranePtnl += (inWeightPos + inWeightNeg); } else { membranePtnl = (inWeightPos + inWeightNeg); } currTime = inTime; if (membranePtnl >= 1.0) { // Schedule a spike for the next time step. schedSpikeTime = inTime + simStepSize; Network::GetNetworkRef()->ScheduleSpike( schedSpikeTime, this ); }}float FastNeuron::GetMembranePtnl() const{ float currState=0.0; AmTimeInt inTime = Network::SimTime(); Utilities::RoundTime(inTime, pspStepSize); unsigned int tblIndex = (unsigned int)((float)(inTime - currTime) * stepSizeInv); if (tblIndex < pspLSize) { // don't go beyond the end of the tables currState = membranePtnl * pspLookup[tblIndex]; } else { currState = 0.0; } return currState;}void FastNeuron::InitLookup(){ pspLSize = 1000; FunctionLookup* fl = Network::GetNetworkRef()->GetFunctionLookup(); TableProperties props; props.SetClassName("FastNeuron"); props.SetTableSize(pspLSize); float membraneConst = dynamic_cast<FastNeuronProperties*>(neuronProps)->GetMembraneConst(); props.AddParam(membraneConst); try { pspLookup = fl->GetTableData(props); } catch (TableNotFoundException& e) { pspLookup = fl->MakeLookupTable(props); pspStepSize = 100; float calcTm = 0; for (unsigned int i=0; i<pspLSize; ++i) { calcTm = (float(i) * pspStepSize); PspKernel(calcTm, &pspLookup[i]); } }}// TODO: Replace this with code that will work with the new FunctionLookup/*float* FastNeuron::InitializeLookupTable(int index){ unsigned int i; switch (index) { case 0: pspLookup = new float[pspLSize]; for (i=0; i<pspLSize; i++) { pspLookup[i] = 0.0; } if ( FillLookupTables(index) ) { return pspLookup; } else { cerr << "FillLookupTables() failed in Neuron.\n"; return 0; } break; default: return 0; }}*/// Table params get replaced with TableProperties/*float* FastNeuron::GetTableParams(int index, int& numParams){ float* paramList; switch (index) { case 0: numParams = 1; paramList = new float[1]; paramList[0] = memTimeConst; break; default: return 0; } return paramList;}*//*int FastNeuron::SetLookupTables(FunctionLookup* funcRef){ // Get the pointer for the pspLookup table. If a table for this // class and set of constants has not been initialized, the FunctionLookup // class will call this.InitializeLookupTable() pspLookup = funcRef->GetLookupTable(this, 0, pspLSize, pspStepSize); // set stepSizeInv for InputSpike stepSizeInv = 1.0/pspStepSize; // test for table pointers if ( pspLookup == 0) { return 0; } return 1;}*//*int FastNeuron::FillLookupTables(int index){ if (pspLSize == 0 || pspStepSize == 0) { return 0; } float calcTm = 0.0; unsigned int i; switch (index) { case 0: // Fill the PSP table //cout << "Filling PSP Table..." << endl; for (i=0; i<pspLSize; i++) { calcTm = (float(i) * pspStepSize); PspKernel(calcTm, &pspLookup[i]); } break; default: return 0; } usePspLookup = true; return 1;}*/void FastNeuron::PspKernel(float calcTime, float* pspElement){ // Model the PSP as Ep = exp[ -t / Tm ] float expTerm, convCalcTime; // convert time from microseconds to miliseconds convCalcTime = calcTime * 0.001; //expTerm = -convCalcTime/(static_cast<FastNeuronProperties*>(neuronProps)->GetMembraneConst())*0.001; expTerm = -convCalcTime/(static_cast<FastNeuronProperties*>(neuronProps)->GetMembraneConst()); *pspElement = exp(expTerm);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -