00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "STDP1Synapse.h"
00025 #include "Debug.h"
00026 #include "SimulationClock.h"
00027
00028
00029 #include <cmath>
00030 #include <iostream>
00031 using namespace std;
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #define MONITOR_WEIGHT
00042
00043
00044
00045 const string STDP1Synapse::calciumThreshUpLow("CalciumThreshUpLow");
00046 const string STDP1Synapse::calciumThreshUpHigh("CalciumThreshUpHigh");
00047 const string STDP1Synapse::calciumThreshDownLow("CalciumThreshDownLow");
00048 const string STDP1Synapse::calciumThreshDownHigh("CalciumThreshDownHigh");
00049 const string STDP1Synapse::weightChangeThreshold("WeightChangeThreshold");
00050 const string STDP1Synapse::weightIncreaseAmnt("WeightIncreaseAmnt");
00051 const string STDP1Synapse::weightDecreaseAmnt("WeightDecreaseAmnt");
00052 const string STDP1Synapse::driftThreshold("DriftThreshold");
00053 const string STDP1Synapse::positiveDrift("PositiveDrift");
00054 const string STDP1Synapse::negativeDrift("NegativeDrift");
00055 const string STDP1Synapse::maximumDrift("MaximumDrift");
00056 const string STDP1Synapse::minimumDrift("MinimumDrift");
00057 const string STDP1Synapse::learning("Learning");
00058 const string STDP1Synapse::disable("Disable");
00059
00060
00061
00062 extern "C" {
00063 Synapse* getClass(){
00064 return new STDP1Synapse;
00065 }
00066 }
00067
00068
00069
00070 STDP1Synapse::STDP1Synapse() : Synapse() {
00071
00072 spikeTimeStep = -1;
00073 lastUpdateTime = 0.0;
00074 oldLearningMode = false;
00075
00076
00077 int count = 0;
00078 #ifdef MONITOR_WEIGHT
00079 count++;
00080 #endif//MONITOR_WEIGHT
00081
00082 monitorData.dataArray = new double[count];
00083 monitorData.length = count;
00084 }
00085
00086
00087
00088 STDP1Synapse::~STDP1Synapse(){
00089 #ifdef MEMORY_DEBUG
00090 cout<<"DESTROYING STDPSynapse."<<endl;
00091 #endif//MEMORY_DEBUG
00092
00093 delete [] monitorData.dataArray;
00094 }
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 void STDP1Synapse::calculateFinalState(){
00106 if((*parameterMap)[learning] == 1.0)
00107 calculateWeight(false);
00108 }
00109
00110
00111
00112
00113 const string* STDP1Synapse::getDescription(){
00114 string* tempstr = new string("STDP1 Synapse");
00115 return tempstr;
00116 }
00117
00118
00119
00120
00121 MonitorData* STDP1Synapse::getMonitoringData(){
00122
00123
00124
00125 if((*parameterMap)[learning] == 1.0)
00126 calculateWeight(false);
00127
00128 #ifdef MONITOR_WEIGHT
00129 monitorData.dataArray[0] = weight;
00130 #endif//MONITOR_WEIGHT
00131
00132 return &monitorData;
00133 }
00134
00135
00136
00137 string STDP1Synapse::getMonitoringInfo(){
00138 string xmlString = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>";
00139 xmlString += "<monitor_info>";
00140
00141 #ifdef MONITOR_WEIGHT
00142 xmlString += "<data><description>Weight</description><range_high>1.0</range_high><range_low>-1.0</range_low></data>";
00143 #endif//MONITOR_WEIGHT
00144
00145 xmlString += "</monitor_info>";
00146 return xmlString;
00147 }
00148
00149
00150
00151 short STDP1Synapse::getShortWeight(){
00152
00153 if((*parameterMap)[learning] == 1.0)
00154 calculateWeight(false);
00155
00156
00157 short shortWeight = (short)rint(weight * 127.0);
00158
00159
00160 #ifdef SAVE_WEIGHTS_DEBUG
00161 cout<<"STDP1Synapse ["<<preSynapticNeuronID<<", "<<postSynapticNeuron->getNeuronID()<<"]: Saving short weight. Weight = "<<weight<<"; short weight = "<<shortWeight<<endl;
00162 if(shortWeight > MAX_SHORT_WEIGHT || shortWeight < MIN_SHORT_WEIGHT){
00163 cerr<<"STDP1Synapse ["<<preSynapticNeuronID<<", "<<postSynapticNeuron->getNeuronID()<<"]: BYTE WEIGHT OUT OF RANGE: "<<shortWeight<<endl;
00164 return 0;
00165 }
00166 #endif//SAVE_WEIGHTS_DEBUG
00167
00168 return shortWeight;
00169 }
00170
00171
00172
00173 double STDP1Synapse::getWeight(){
00174
00175 if((*parameterMap)[learning] == 1.0)
00176 calculateWeight(false);
00177
00178 return weight;
00179 }
00180
00181
00182
00183
00184
00185 bool STDP1Synapse::parametersChanged(){
00186 if(checkParameters()){
00187 if(!oldLearningMode && (*parameterMap)[learning] == 1.0){
00188 lastUpdateTime = simulationClock->getSimulationTime();
00189 oldLearningMode = true;
00190 }
00191 else if (oldLearningMode && (*parameterMap)[learning] == 0.0){
00192 calculateWeight(false);
00193 oldLearningMode = false;
00194 }
00195 return true;
00196 }
00197 else{
00198 return false;
00199 }
00200 }
00201
00202
00203
00204 void STDP1Synapse::processSpike(){
00205
00206 if((*parameterMap)[disable] == 1.0)
00207 return;
00208
00209
00210
00211
00212 if((*parameterMap)[learning] == 1.0){
00213
00214 calculateWeight(true);
00215
00216
00217 spikeTimeStep = simulationClock->getTimeStep();
00218 }
00219
00220
00221 postSynapticNeuron->changePostSynapticPotential(weight, preSynapticNeuronID);
00222 }
00223
00224
00225
00226 bool STDP1Synapse::testFunction(){
00227 cout<<"STDP1Synapse ["<<preSynapticNeuronID<<", "<<postSynapticNeuron->getNeuronID()<<"]: Test function called. "<<endl;
00228 return true;
00229 }
00230
00231
00232
00233
00234 void STDP1Synapse::updateWeight(double membranePotential, double calciumConc){
00235 #ifdef LEARNING_DEBUG
00236 cout<<"STDP1Synapse ["<<preSynapticNeuronID<<", "<<postSynapticNeuron->getNeuronID()<<"]: Updating weight."<<endl;
00237 #endif//LEARNING_DEBUG
00238
00239
00240
00241
00242 if((*parameterMap)[learning] == 1.0){
00243
00244
00245 if(spikeTimeStep != simulationClock->getTimeStep()){
00246 #ifdef LEARNING_DEBUG
00247 cout<<"STDP1Synapse ["<<preSynapticNeuronID<<", "<<postSynapticNeuron->getNeuronID()<<"]: Spike has not received a spike. Applying positive or negative drift and returning."<<endl;
00248 #endif//LEARNING_DEBUG
00249 return;
00250 }
00251
00252
00253
00254
00255
00256 if(membranePotential > (*parameterMap)[weightChangeThreshold]){
00257 if(calciumConc > (*parameterMap)[calciumThreshUpLow] && calciumConc < (*parameterMap)[calciumThreshUpHigh]){
00258
00259 weight += (*parameterMap)[weightIncreaseAmnt];
00260 normaliseWeight();
00261 return;
00262 }
00263 }
00264 else{
00265 if(calciumConc > (*parameterMap)[calciumThreshDownLow] && calciumConc < (*parameterMap)[calciumThreshDownHigh]){
00266
00267 weight -= (*parameterMap)[weightDecreaseAmnt];
00268 normaliseWeight();
00269 return;
00270 }
00271 }
00272
00273
00274 if(weight > (*parameterMap)[driftThreshold] ){
00275 weight += (*parameterMap)[positiveDrift] * simulationClock->getTimeStepDuration_ms();
00276 if(weight > (*parameterMap)[maximumDrift])
00277 weight = (*parameterMap)[maximumDrift];
00278 }
00279 else{
00280 weight -= (*parameterMap)[negativeDrift] * simulationClock->getTimeStepDuration_ms();
00281 if(weight < (*parameterMap)[minimumDrift])
00282 weight = (*parameterMap)[minimumDrift];
00283 }
00284
00285
00286 normaliseWeight();
00287 }
00288 }
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302 void STDP1Synapse::calculateWeight(bool spikeReceived){
00303
00304 currentTime = simulationClock->getSimulationTime();
00305
00306 if(lastUpdateTime == currentTime)
00307 return;
00308
00309 if(weight > (*parameterMap)[driftThreshold] ){
00310 if(spikeReceived)
00311 weight += (*parameterMap)[positiveDrift] * (currentTime - lastUpdateTime - simulationClock->getTimeStepDuration_ms());
00312 else
00313 weight += (*parameterMap)[positiveDrift] * (currentTime - lastUpdateTime);
00314
00315
00316 if(weight > (*parameterMap)[maximumDrift])
00317 weight = (*parameterMap)[maximumDrift];
00318 }
00319 else{
00320 if(spikeReceived)
00321 weight -= (*parameterMap)[negativeDrift] * (currentTime - lastUpdateTime - simulationClock->getTimeStepDuration_ms());
00322 else
00323 weight -= (*parameterMap)[negativeDrift] * (currentTime - lastUpdateTime);
00324
00325
00326 if(weight < (*parameterMap)[minimumDrift])
00327 weight = (*parameterMap)[minimumDrift];
00328 }
00329
00330
00331 normaliseWeight();
00332
00333
00334 lastUpdateTime = currentTime;
00335 }
00336
00337
00338
00339 bool STDP1Synapse::checkParameters(){
00340
00341 if(parameterMap->count(calciumThreshUpLow) != 1){
00342 cerr<<"STDP1Synapse ["<<preSynapticNeuronID<<", "<<postSynapticNeuron->getNeuronID()<<"]: PARAMETER calciumThreshUpLow NOT FOUND WITH KEY \""<<calciumThreshUpLow<<"\""<<endl;
00343 return false;
00344 }
00345
00346 if(parameterMap->count(calciumThreshUpHigh) != 1){
00347 cerr<<"STDP1Synapse ["<<preSynapticNeuronID<<", "<<postSynapticNeuron->getNeuronID()<<"]: PARAMETER calciumThreshUpHigh NOT FOUND WITH KEY \""<<calciumThreshUpHigh<<"\""<<endl;
00348 return false;
00349 }
00350
00351 if(parameterMap->count(calciumThreshDownLow) != 1){
00352 cerr<<"STDP1Synapse ["<<preSynapticNeuronID<<", "<<postSynapticNeuron->getNeuronID()<<"]: PARAMETER calciumThreshDownLow NOT FOUND WITH KEY \""<<calciumThreshDownLow<<"\""<<endl;
00353 return false;
00354 }
00355
00356 if(parameterMap->count(calciumThreshDownHigh) != 1){
00357 cerr<<"STDP1Synapse ["<<preSynapticNeuronID<<", "<<postSynapticNeuron->getNeuronID()<<"]: PARAMETER calciumThreshDownHigh NOT FOUND WITH KEY \""<<calciumThreshDownHigh<<"\""<<endl;
00358 return false;
00359 }
00360
00361 if(parameterMap->count(weightChangeThreshold) != 1){
00362 cerr<<"STDP1Synapse ["<<preSynapticNeuronID<<", "<<postSynapticNeuron->getNeuronID()<<"]: PARAMETER weightChangeThreshold NOT FOUND WITH KEY \""<<weightChangeThreshold<<"\""<<endl;
00363 return false;
00364 }
00365
00366 if(parameterMap->count(weightIncreaseAmnt) != 1){
00367 cerr<<"STDP1Synapse ["<<preSynapticNeuronID<<", "<<postSynapticNeuron->getNeuronID()<<"]: PARAMETER weightIncreaseAmnt NOT FOUND WITH KEY "<<weightIncreaseAmnt<<endl;
00368 return false;
00369 }
00370
00371 if(parameterMap->count(weightDecreaseAmnt) != 1){
00372 cerr<<"STDP1Synapse ["<<preSynapticNeuronID<<", "<<postSynapticNeuron->getNeuronID()<<"]: PARAMETER weightDecreaseAmnt NOT FOUND WITH KEY \""<<weightDecreaseAmnt<<"\""<<endl;
00373 return false;
00374 }
00375
00376 if(parameterMap->count(driftThreshold) != 1){
00377 cerr<<"STDP1Synapse ["<<preSynapticNeuronID<<", "<<postSynapticNeuron->getNeuronID()<<"]: PARAMETER driftThreshold NOT FOUND WITH KEY \""<<driftThreshold<<"\""<<endl;
00378 return false;
00379 }
00380
00381 if(parameterMap->count(positiveDrift) != 1){
00382 cerr<<"STDP1Synapse ["<<preSynapticNeuronID<<", "<<postSynapticNeuron->getNeuronID()<<"]: PARAMETER positiveDrift NOT FOUND WITH KEY \""<<positiveDrift<<"\""<<endl;
00383 return false;
00384 }
00385
00386 if(parameterMap->count(negativeDrift) != 1){
00387 cerr<<"STDP1Synapse ["<<preSynapticNeuronID<<", "<<postSynapticNeuron->getNeuronID()<<"]: PARAMETER negativeDrift NOT FOUND WITH KEY \""<<negativeDrift<<"\""<<endl;
00388 return false;
00389 }
00390
00391 if(parameterMap->count(maximumDrift) != 1){
00392 cerr<<"STDP1Synapse ["<<preSynapticNeuronID<<", "<<postSynapticNeuron->getNeuronID()<<"]: PARAMETER maximumDrift NOT FOUND WITH KEY \""<<maximumDrift<<"\""<<endl;
00393 return false;
00394 }
00395
00396 if(parameterMap->count(minimumDrift) != 1){
00397 cerr<<"STDP1Synapse ["<<preSynapticNeuronID<<", "<<postSynapticNeuron->getNeuronID()<<"]: PARAMETER minimumDrift NOT FOUND WITH KEY \""<<minimumDrift<<"\""<<endl;
00398 return false;
00399 }
00400
00401 if(parameterMap->count(learning) != 1){
00402 cerr<<"STDP1Synapse ["<<preSynapticNeuronID<<", "<<postSynapticNeuron->getNeuronID()<<"]: PARAMETER learning NOT FOUND WITH KEY \""<<learning<<"\""<<endl;
00403 return false;
00404 }
00405
00406 if(parameterMap->count(disable) != 1){
00407 cerr<<"STDP1Synapse ["<<preSynapticNeuronID<<", "<<postSynapticNeuron->getNeuronID()<<"]: PARAMETER disable NOT FOUND WITH KEY \""<<disable<<"\""<<endl;
00408 return false;
00409 }
00410
00411
00412 #ifdef SYNAPSE_PARAMETERS_DEBUG
00413 printParameters();
00414 #endif//SYNAPSE_PARAMETERS_DEBUG
00415
00416 return true;
00417 }
00418
00419
00420
00421
00422
00423
00424 void STDP1Synapse::normaliseWeight(){
00425 if(weight > MAX_DOUBLE_WEIGHT)
00426 weight = MAX_DOUBLE_WEIGHT;
00427 else if(weight < 0)
00428 weight = 0;
00429 }
00430
00431
00432
00433 void STDP1Synapse::printParameters(){
00434 cout<<"------------------ SETTING STDP1Synapse PARAMETERS -----------------------"<<endl;
00435 cout<<"calciumThreshUpLow = "<<(*parameterMap)[calciumThreshUpLow]<<endl;
00436 cout<<"calciumThreshUpHigh= "<<(*parameterMap)[calciumThreshUpHigh]<<endl;
00437 cout<<"calciumThreshDownLow = "<<(*parameterMap)[calciumThreshDownLow]<<endl;
00438 cout<<"calciumThreshDownHigh = "<<(*parameterMap)[calciumThreshDownHigh]<<endl;
00439 cout<<"weightChangeThreshold = "<<(*parameterMap)[weightChangeThreshold]<<endl;
00440 cout<<"weightIncreaseAmnt = "<<(*parameterMap)[weightIncreaseAmnt]<<endl;
00441 cout<<"weightDecreaseAmnt = "<<(*parameterMap)[weightDecreaseAmnt]<<endl;
00442 cout<<"driftThreshold = "<<(*parameterMap)[driftThreshold]<<endl;
00443 cout<<"positiveDrift = "<<(*parameterMap)[positiveDrift]<<endl;
00444 cout<<"negativeDrift = "<<(*parameterMap)[negativeDrift]<<endl;
00445 cout<<"maximumDrift = "<<(*parameterMap)[maximumDrift]<<endl;
00446 cout<<"minimumDrift = "<<(*parameterMap)[minimumDrift]<<endl;
00447 cout<<"Learning mode = "<<(*parameterMap)[learning]<<endl;
00448 cout<<"Disable = "<<(*parameterMap)[disable]<<endl;
00449 cout<<"---------------------------------------------------------------------------"<<endl;
00450 }
00451
00452