📄 basicneuron.cpp
字号:
/*************************************************************************** basicneuron.cpp - description ------------------- copyright : (C) 2000, 2001, 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 "basicneuron.h"#include "functionlookup.h"#include "network.h"#include "dendrite.h"#include "logging.h"#include "utilities.h"#include "physicalproperties.h"using namespace std;using namespace Amygdala;unsigned int BasicNeuron::pspStepSize = 0;unsigned int BasicNeuron::pspLSize = 0;BasicNeuronProperties::BasicNeuronProperties(): SpikingNeuronProperties(), synTimeConst(10.0){}BasicNeuronProperties::BasicNeuronProperties(bool initializePhysicalProps): SpikingNeuronProperties(initializePhysicalProps), synTimeConst(10.0){ if(initializePhysicalProps){ PhysicalProperties::RGB color = {55, 200, 200}; physProps->SetBodyColor(color); }}BasicNeuronProperties::BasicNeuronProperties(const BasicNeuronProperties& rhs): SpikingNeuronProperties(rhs){ synTimeConst = rhs.synTimeConst;}BasicNeuronProperties::~BasicNeuronProperties(){}BasicNeuronProperties* BasicNeuronProperties::Copy() const{ return new BasicNeuronProperties(*this);}std::map< std::string, std::string > BasicNeuronProperties::GetPropertyMap() const{ std::map< std::string, std::string > props = SpikingNeuronProperties::GetPropertyMap(); props["synTimeConst"] = Utilities::ftostr(synTimeConst); return props;}///////// End BasicNeuronProperties //////////BasicNeuron::BasicNeuron(AmIdInt neuronId, const BasicNeuronProperties& neuronProps): SpikingNeuron(neuronId, neuronProps), histBeginIdx(0), maxThreshCrs(0), pspLookup(0), dPspLookup(0){ if (!pspStepSize) { Init(); } InitLookup();}BasicNeuron::~BasicNeuron(){}void BasicNeuron::SetProperties(BasicNeuronProperties* props){ delete neuronProps; neuronProps = props->Copy();}void BasicNeuron::SpikeCleanup(){ // reset inputHist vector inputHist.clear(); histBeginIdx = 0;}void BasicNeuron::CalcState(float& state, float& deriv, const AmTimeInt& calcTime, const AmTimeInt& historySize){ AmTimeInt i, funcTime, tblIndex; float funcWeight, stepSizeInv = 1.0/pspStepSize; InputHist input; state = 0.0; deriv = 0.0; for (i=histBeginIdx; i<historySize; i++) { input = inputHist[i]; funcTime = calcTime - input.time; funcWeight = input.weight; #ifdef DEBUG_NEURON cout << "funcTime: " << funcTime << endl; cout << "funcWeight: " << funcWeight << endl; #endif tblIndex = (unsigned int)(funcTime * stepSizeInv); if (tblIndex < pspLSize) { // don't go beyond the end of the tables state = state + (funcWeight * (pspLookup[tblIndex])); deriv = deriv + (funcWeight * (dPspLookup[tblIndex])); } else { ++histBeginIdx; } }}void BasicNeuron::ProcessInput(const AmTimeInt& inTime){ // If the neuron is within a refractory period, if ( (inTime - spikeTime) <= refPeriod ) { if (inTime > refPeriod) { dendrite->ResetTrigger(); return; } } unsigned int i, iterate, converged, histSize, tblIndex; AmTimeInt calcTime, funcTime; float currState = 0.0; float currDeriv = 0.0; float stateDelta = 0.0; float threshCrs = 0.0; float lstThreshCrs = 0.0; InputHist tmpInput; iterate = 1; converged = 0; calcTime = 0; funcTime = 0; histSize = 0; tblIndex = 0; if (!maxThreshCrs) { maxThreshCrs = pspLSize * pspStepSize; // find the convergence resolution (the resolution at which two values // of threshCrs are considered to be identical) -- must be <= simStepSize if (simStepSize > pspStepSize) { if (pspStepSize > (simStepSize / 2.0)) { convergeRes = pspStepSize; } else { convergeRes = simStepSize / 2.0; } } else { convergeRes = simStepSize; } } calcTime = inTime; inputTime = inTime; currTime = inTime; float inWeightPos, inWeightNeg; dendrite->GetStimulationLevel(inWeightPos, inWeightNeg); // Commented out until training classes are complete /*if (trainingMode) { dendrite->GetStimulationLevel(inWeightPos, inWeightNeg); } else { dendrite->GetStimulationLevel(inWeightPos, inWeightNeg); }*/ // neg and pos weights are combined here because excitatory and // inhibitory synapses behave identically in this neuron model tmpInput.weight = inWeightPos + inWeightNeg; tmpInput.time = inTime; inputHist.push_back(tmpInput); histSize = inputHist.size(); // Return if the neuron is going to spike during the current time // step and the input weight is positive if (inTime == schedSpikeTime) { if (tmpInput.weight > 0.0) { return; } } #ifdef DEBUG_NEURON cout << "\nNeuron " << nId << " receiving a spike.\n"; for (i=0; i<histSize; i++) { tmpInput = inputHist[i]; cout << "inTimeHist[" << i << "] " << tmpInput.time << endl; cout << "inWeightHist[" << i << "] " << tmpInput.weight << endl; } cout << "calcTime: " << calcTime << endl; cout << "inTime: " << inTime << endl; cout << "currTime: " << currTime << endl; #endif i = 0; // Use Newton's method to determine if and when the spike will occur /************************************************************************** * 1) Determine the membrane potential (currState) at time (calcTime - * inTimeHist[i]) by summing the state of each inTimeHist[] * (use pspLookup). * 2) Find the derivative of the function for calcTime (dPspLookup). * 3) Calculate intercept with thresholdPtnl. * 4) Set new calcTime to time of intercept. * 5) Repeat until: * a) Two successive iterations result in a change in calcTime * smaller than convergeRes (the convergence resolution). * (Converges) * b) The derivative of the function becomes negative. * (Does not converge) **************************************************************************/ // Take care of a special case first: // If this is the first input (starting from a rest potential) // then the PSP can only cross the threshold at t = synTimeConst // because of constraints on the maximum value of weights. #ifdef DEBUG_NEURON cout << "Starting main loop...\n"; #endif if (histSize == 1) { iterate = 0; funcTime = (AmTimeInt)(dynamic_cast<BasicNeuronProperties*>(neuronProps)->GetSynapseConst())*1000; tblIndex = (funcTime / pspStepSize); currState = (inputHist[0].weight) * (pspLookup[tblIndex]); if (currState >= 1.0) { calcTime += funcTime; converged = 1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -