00001 #include "SpikingInputNeuron.h"
00002
00003 #include <algorithm>
00004 using std::sort;
00005 using std::transform;
00006 using std::copy;
00007 using std::equal;
00008 using std::insert_iterator;
00009 using std::unique;
00010
00011 #include <iostream>
00012 using std::cout;
00013 using std::endl;
00014
00015 SpikingInputNeuron::SpikingInputNeuron() : SingleOutputSpikeSender(), sorted(false)
00016 {
00017
00018 }
00019
00020 SpikingInputNeuron::SpikingInputNeuron(const std::vector<double> &spikeTimes) : SingleOutputSpikeSender(),
00021 spikeTimes(spikeTimes), sorted(false)
00022 {
00023 }
00024
00025 class quantifier
00026 {
00027 public:
00028 quantifier( double quant ) : _quant(quant)
00029 {}
00030 ;
00031
00032 double operator() ( double v)
00033 {
00034 return ((int)(v / _quant)) * _quant;
00035 }
00036
00037 double _quant;
00038 };
00039
00040 void SpikingInputNeuron::adjustSpikesToTimeGrid( double dt )
00041 {
00042 transform( spikeTimes.begin(), spikeTimes.end(), spikeTimes.begin(), quantifier( dt ) );
00043 }
00044
00045 void SpikingInputNeuron::sort_spikes()
00046 {
00047
00048 sort( spikeTimes.begin(), spikeTimes.end() );
00049 spikeTimes.erase( unique<std::vector<double>::iterator>(spikeTimes.begin(), spikeTimes.end()), spikeTimes.end() ) ;
00050 sorted = true;
00051 }
00052
00053
00054 void SpikingInputNeuron::setSpikes(const std::vector<double> &theSpikeTimes)
00055 {
00056 spikeTimes = theSpikeTimes;
00057 sorted = false;
00058 }
00059
00060 const std::vector<double> &SpikingInputNeuron::getSpikeTimes() const
00061 {
00062 return spikeTimes;
00063 }
00064
00065 void SpikingInputNeuron::addSpike( double st, bool force_sort )
00066 {
00067 spikeTimes.push_back( st );
00068 sorted = false;
00069 }
00070
00071 int SpikingInputNeuron::reset( double dt )
00072 {
00073 SingleOutputSpikeSender::reset();
00074
00075 if( ! sorted ) {
00076 sort_spikes();
00077 }
00078
00079 currentStep = nextSpikeIdx = 0;
00080 numStepsToNextSpike = -1;
00081 if( spikeTimes.size() > nextSpikeIdx ) {
00082 numStepsToNextSpike = (long)( -0.001 * dt + spikeTimes[ nextSpikeIdx ] / dt );
00083 }
00084 return 0;
00085 }
00086
00087 int SpikingInputNeuron::reset( double dt, double startT)
00088 {
00089 if( ! sorted ) {
00090 sort_spikes();
00091 }
00092
00093 currentStep = long(startT / dt);
00094 nextSpikeIdx = 0;
00095 if( spikeTimes.size() > nextSpikeIdx ) {
00096 numStepsToNextSpike = (long)( -0.001 * dt + spikeTimes[ nextSpikeIdx ] / dt - currentStep );
00097 }
00098 return 0;
00099 }
00100
00101
00102 int SpikingInputNeuron::advance(AdvanceInfo const &ai)
00103 {
00104 currentStep++;
00105 if( ( spikeTimes.size() > nextSpikeIdx ) && ( numStepsToNextSpike-- == 0 ) ) {
00106 nextSpikeIdx++;
00107 numStepsToNextSpike = -1;
00108 if( spikeTimes.size() > nextSpikeIdx ) {
00109 numStepsToNextSpike = (long)( ( -0.001 * ai.dt.in_sec() + spikeTimes[ nextSpikeIdx ] ) / ai.dt.in_sec() ) - currentStep ;
00110 }
00111 out_port.setSpike( ai, spikeTimes[ nextSpikeIdx-1 ] );
00112 return ADVANCEFLAG_HASSPIKED;
00113 } else {
00114 return 0;
00115 }
00116 }
00117
00118 void SpikingInputNeuron::printSpikeTimes()
00119 {
00120 for( size_t i=0; i<spikeTimes.size(); i++) {
00121 cerr << spikeTimes[i] << " ";
00122 }
00123 cerr << endl;
00124 }
00125
00126