00001 /*************************************************************************** 00002 * SpikeStream Simulation * 00003 * Copyright (C) 2007 by David Gamez * 00004 * david@davidgamez.eu * 00005 * Version 0.1 * 00006 * * 00007 * This program is free software; you can redistribute it and/or modify * 00008 * it under the terms of the GNU General Public License as published by * 00009 * the Free Software Foundation; either version 2 of the License, or * 00010 * (at your option) any later version. * 00011 * * 00012 * This program is distributed in the hope that it will be useful, * 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00015 * GNU General Public License for more details. * 00016 * * 00017 * You should have received a copy of the GNU General Public License * 00018 * along with this program; if not, write to the * 00019 * Free Software Foundation, Inc., * 00020 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 00021 ***************************************************************************/ 00022 00023 #ifndef NEURON_H 00024 #define NEURON_H 00025 00026 //SpikeStream includes 00027 #include "TaskHolder.h" 00028 #include "ConnectionHolder.h" 00029 #include "NeuronTaskHolder.h" 00030 #include "SimulationClock.h" 00031 #include "GlobalVariables.h" 00032 00033 //Other includes 00034 #include <vector> 00035 #include <map> 00036 00037 00038 //-------------------------------- Neuron --------------------------------- 00039 /*! This class acts as the base class inherited by all neuron classes. 00040 This base class handles all the message passing aspects of the neuron, 00041 and derived classes should add in the modelling aspect to control when 00042 the neuron fires. 00043 00044 During a time step each firing synapse changes the membrane potential 00045 of the neuron if it decides to pass on the spike. This changing of the 00046 membrane potential should call the update method of the neuron if the 00047 neuron's state has not already been updated in that time step. Finally 00048 when all spikes have been received, the function calculateFinalState() 00049 is called instructing the neuron to decide whether it should fire or 00050 not. This is because excitatory and inhibitory spikes can arrive 00051 simultaneously within the same time step, so the final neuron state can 00052 only be calculated after all spikes have arrived. 00053 00054 NOTE Neuron ids from 0-10 are reserved and should never appear in the 00055 database 00056 00057 NOTE When the synapse potential is changed as a way of injecting noise 00058 the preSynapticNeuronID in changeMembranePotential will be set to zero. 00059 */ 00060 00061 /* FIXME IT WOULD BE MUCH BETTER TO HOLD THE SIMULATION CLOCK AS A STATIC 00062 REFERENCE, BUT WHEN THIS IS SET USING Neuron::setSimulationClock() IT 00063 DOES NOT CHANGE THE ADDRESS IN CLASSES INHERITING FROM NEURON. WOULD BE 00064 GOOD IF THIS COULD BE SORTED OUT. */ 00065 //-------------------------------------------------------------------------- 00066 00067 class Neuron { 00068 public: 00069 Neuron(); 00070 virtual ~Neuron(); 00071 00072 00073 /*-------------------------------------------------------------------------------- 00074 ------ Methods that subclasses of Neuron may or have to implement ------ 00075 --------------------------------------------------------------------------------*/ 00076 00077 /*! Calculates the final state of the neuron after all spikes have been received. The neuron 00078 should be updated by this method if it is not updated already. */ 00079 virtual void calculateFinalState() = 0; 00080 00081 /* A synapse may change the membrane potential of the neuron. */ 00082 virtual void changePostSynapticPotential(double amount, unsigned int preSynapticNeuronID) = 0; 00083 00084 /*! Returns a description of this neuron class for debugging only. 00085 Destruction of the new string is the responsibility of the invoking method. */ 00086 virtual const string* getDescription() = 0; 00087 00088 /*! Sets the parameters of the neuron. These should be defined in their own 00089 database, whose name is listed in the NeuronTypes database. This is called 00090 on only one instance of the neuron class with the parameters being set 00091 and held statically. The parametersChanged() method is called after 00092 the static setting of the parameters to inform each neuron class 00093 that the parameters have changed. */ 00094 virtual bool setParameters(map<string, double> paramMap) = 0; 00095 00096 /*! Called after the parameters have been statically changed to inform each 00097 neuron class that the parameters have been changed. This enables them 00098 to update their learning state, for example, after learning has been 00099 switched off. */ 00100 virtual void parametersChanged() = 0; 00101 00102 /*! This method returns an string containing an XML description of the variables 00103 that are available for monitoring within this class. Overload this method and 00104 getMonitoringData() if you want to send monitoring information back to the main 00105 application. This will enable you to view a graph of the membrane potential, 00106 for example. */ 00107 virtual string getMonitoringInfo(); 00108 00109 /*! Returns a monitor data struct (defined in GlobalVariables.h) containing the 00110 data that is being monitored. This returned data must match that defined in 00111 the string returned by getMonitoringInfo() */ 00112 virtual MonitorData* getMonitoringData(); 00113 00114 00115 /*---------------------------------------------------------------------- 00116 ------ Public methods implemented by Neuron class ------ 00117 ----------------------------------------------------------------------*/ 00118 void fireNeuron(); 00119 int getNeuronFireCount(); 00120 unsigned int getNeuronID(); 00121 00122 00123 //Declare SpikeStreamSimulation a friends to enable loading of the neurons 00124 friend class SpikeStreamSimulation; 00125 00126 00127 protected: 00128 //=========================== VARIABLES =================================== 00129 /*! ID of this neuron. */ 00130 unsigned int neuronID; 00131 00132 /*! Reference to the main simulation clock. */ 00133 //FIXME THIS WOULD BE BETTER STATIC BUT CREATES PROBLEMS - SEE INTRO 00134 SimulationClock *simulationClock; 00135 00136 /*! Time at which neuron last fired. */ 00137 double neuronFireTime; 00138 00139 /*! Number of times neuron has fired since the beginning of the simulation. */ 00140 int neuronFireCount; 00141 00142 /*! Pointer to the synapse map, which is used by some neuron models. 00143 Uses void pointer to avoid include problems. The type of this map is: 00144 dense_hash_map<unsigned int, dense_hash_map<unsigned int, Synapse*, hash<unsigned int> >*, hash<unsigned int> > 00145 See SpikeStreamSimulation for more details about this map. */ 00146 void* synapseMapPtr; 00147 00148 /*! Pointer to all the synpse classes that connect to this neuron 00149 Stored as void pointer to avoid include problems. */ 00150 vector<void*> preSynapseVector; 00151 00152 /*! Holds the monitoring data for the neuron. */ 00153 MonitorData monitorData; 00154 00155 00156 private: 00157 //========================= VARIABLES ============================= 00158 /*! Array containing references to all the spike task holders that 00159 this neuron communicates with. */ 00160 TaskHolder **spikeTaskHolderArray; 00161 00162 /*! Size of spikeTaskHolderArray. */ 00163 unsigned int numberOfSpikeTaskHolders; 00164 00165 /*! Reference to the neuron task holder for this neuron group. */ 00166 NeuronTaskHolder *neuronTaskHolder; 00167 00168 /*! The connection map connects task IDs with vectors of connection Holders 00169 The connectionHolders in each vector are destined for the same task, 00170 but each has a different delay and is inserted into a different spike 00171 buffer. */ 00172 /* FIXME THINK ABOUT ALLOCATING CONNECTION HOLDERS ON THE HEAP SINCE THER 00173 MAY BE A LARGE NUMBER OF THEM. */ 00174 map<int, vector<ConnectionHolder> > connectionMap; 00175 00176 /*! Holds the complete list of synapse ids that this neuron is connected to 00177 These are compressed by subtracting the start neuron ID from the neuron ID 00178 When messages are unpacked the start neuron ID is added back on to get the 00179 correct neuron ID. Connection holders point to parts of this array.*/ 00180 unsigned short *connectionArray; 00181 00182 /*! The number of synapse ids in the connectionArray, which is not its length 00183 because each compressed neuron ID is an unsigned short and so two fit into 00184 a single unsigned integer. */ 00185 unsigned int numberOfConnections; 00186 00187 /*! Declare bufferInsertionPoint here to save redeclaring it in fireNeuron 00188 each time method is called. */ 00189 int bufferInsertionPoint; 00190 00191 /*! Declare destTID here to save redeclaring it in fireNeuron 00192 each time method is called. */ 00193 int destTID; 00194 00195 00196 //================================= METHODS ================================== 00197 void printConnections(); 00198 void setNeuronID(unsigned int neuronID); 00199 void setSimulationClock(SimulationClock* simClock); 00200 void setSynapseMapPtr(void* synMapPtr); 00201 00202 }; 00203 00204 00205 #endif //NEURON_H 00206
1.4.4