0001 function [ts, Theta, Y, Z, thm, thp] = run_networked_neuron(ThNN, ti, NeuronIndex, GradFlag, Verbose)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059 Theta=-1; ts=[]; Y=-1; Z=-1; thm=-1; thp=-1;
0060
0061
0062 if nargin<3
0063 disp('Error in run_networked_neuron: Not enough input arguements');
0064 disp(['Needed at least 3 inputs but only got ' num2str(nargin)]);
0065 return;
0066 end
0067 if (nargin < 4)
0068 GradFlag=1;
0069 end
0070 if (nargin < 5)
0071 Verbose=0;
0072 end
0073
0074
0075
0076 Delays=ThNN.Delays;
0077 Weights=ThNN.Weights;
0078 SimulationMethod=ThNN.SimulationMethod;
0079 TimeStep=ThNN.TimeStep;
0080 NIPS2007Gradient=ThNN.NIPS2007Gradient;
0081 try
0082 CurrentNeuron=struct(ThNN.Neurons(NeuronIndex));
0083 catch
0084 disp('Error in run_networked_neuron: NeuronIndex is not valid');
0085 return;
0086 end
0087 Io=CurrentNeuron.Io;
0088 Alpha=CurrentNeuron.Alpha;
0089 Beta=CurrentNeuron.Beta;
0090 ThFPP=CurrentNeuron.PositiveFixedPoint;
0091
0092
0093 thm=zeros(1,size(ti,1));
0094 thp=thm;
0095
0096
0097 for j=1:size(ti,1)
0098 ti(j,2)=max(ti(j,2)+Delays(ti(j,1),NeuronIndex),0);
0099 end
0100 if ~isempty(ti)
0101
0102
0103 [Temp1,Temp2]=sort(ti(:,2));
0104 ti=[ti(Temp2,1) Temp1];
0105 end
0106
0107
0108 if (Verbose==1)
0109 disp(' ');
0110 disp('********** Function "run" for single neurons in a theta neuron network **********');
0111 disp(['---> Using Simulation Method: ', num2str(SimulationMethod)]);
0112 end
0113
0114
0115
0116
0117 if strcmp(SimulationMethod,'Event-Driven')
0118 prev_time=0;
0119 prev_thp=CurrentNeuron.Phase;
0120 for j=1:size(ti,1)
0121
0122
0123
0124
0125
0126
0127 c1=tan(prev_thp/2)/Beta;
0128 if Io<0
0129 thm(j)=2*atan( Beta*(exp(-2*Beta*(ti(j,2)-prev_time))*(1+c1)-(1-c1))...
0130 /(exp(-2*Beta*(ti(j,2)-prev_time))*(1+c1)+1-c1) );
0131 else
0132 thm(j)=2*atan(Beta*((tan(Beta*(ti(j,2)-prev_time))+c1)/(1-c1*tan(Beta*(ti(j,2)-prev_time)))));
0133 end
0134 thp(j)=thm(j)+Alpha*Weights(ti(j,1),NeuronIndex)*(1+cos(thm(j)));
0135
0136
0137 if (thp(j)>pi && thm(j)<=pi)
0138 ts(end+1)=ti(j,2);
0139 thp(j)=thp(j)-2*pi;
0140 if j<size(ti,1) && Verbose
0141 disp(['---> Neuron ', num2str(NeuronIndex),' Output Spike Time ',num2str(length(ts)),': ' num2str(ts(end)), '(Fired on Non-Final Spike)']);
0142 elseif (Verbose==1)
0143 disp(['---> Neuron ', num2str(NeuronIndex),' Output Spike Time ',num2str(length(ts)),': ' num2str(ts(end)), '(Fired on Final Input Spike)']);
0144 end
0145
0146
0147
0148 elseif (Io<0 && prev_thp<pi && prev_thp>ThFPP && thm(j)>-pi && thm(j)<=(-ThFPP+10*eps))
0149 c1=tan(prev_thp/2)/Beta;
0150 ts(end+1)=prev_time+(1/Beta)*atanh(1/c1);
0151 if (Verbose==1)
0152 disp(['---> Neuron ', num2str(NeuronIndex),' Output Spike Time ',num2str(length(ts)),': ' num2str(ts(end)),' (Fired on Trajectory)']);
0153 end
0154
0155
0156 elseif (Io>0 && (thm(j)<prev_thp || (ti(j,2)-prev_time)>(pi/Beta) ))
0157 ts(end+1)=prev_time+(1/Beta)*( (pi/2) - atan(c1) );
0158 if (Verbose==1)
0159 disp(['---> Neuron ', num2str(NeuronIndex),' Output Spike Time ',num2str(length(ts)),': ' num2str(ts(end)), ' (Fired on Trajectory)']);
0160 end
0161
0162
0163 if (ti(j,2)-prev_time)>(pi/Beta)
0164 num_revs=floor((ti(j,2)-prev_time)/(pi/Beta));
0165 for k=2:num_revs
0166 ts(end+1)=ts(end)+pi/Beta;
0167 if (Verbose==1)
0168 disp(['---> Neuron ', num2str(NeuronIndex),' Output Spike Time ',num2str(length(ts)),': ' num2str(ts(end)), ' (Multiple Revolutions)']);
0169 end
0170 end
0171 if (ts(end)+pi/Beta)<ti(j,2)
0172 ts(end+1)=ts(end)+pi/Beta;
0173 if (Verbose==1)
0174 disp(['---> Neuron ', num2str(NeuronIndex),' Output Spike Time ',num2str(length(ts)),': ' num2str(ts(end)), ' (Final Revolution)']);
0175 end
0176 end
0177 end
0178 end
0179 if (Verbose==1)
0180 disp(' ');
0181 disp(['--->Input Spike Time ', num2str(j), ' (Input Neuron ', num2str(ti(j,1)), '): ', num2str(ti(j,2))]);
0182 disp(['--->Pre -Spike Phase: ' num2str(thm(j))]);
0183 disp(['--->Post-Spike Phase: ' num2str(thp(j))]);
0184 disp(['--->Weight and Delay: ' num2str(Weights(ti(j,1),NeuronIndex)), ' ', num2str(Delays(ti(j,1),NeuronIndex))]);
0185 if thp(j)<ThFPP && thp(j)>-ThFPP && Io<0;
0186 disp(['--->Operating Below Positive Fixed Point (',num2str(ThFPP),') - Neuron may not fire again']);
0187 end
0188 end
0189
0190 prev_time=ti(j,2);
0191 prev_thp=thp(j);
0192
0193 end
0194 if ~isempty(thp)
0195 c1=tan(thp(end)/2)/Beta;
0196 else
0197 c1=tan(CurrentNeuron.Phase/2)/Beta;
0198 end
0199
0200
0201 if (Io>0 && (isempty(ts) || ti(end,2)>ts(end)))
0202 if ~isempty(ti)
0203 ts(end+1)=ti(end,2)+(1/Beta)*( (pi/2) - atan(c1) );
0204 else
0205 ts(end+1)=(1/Beta)*( (pi/2) - atan(c1) );
0206 end
0207 if (Verbose==1)
0208 disp(['---> Neuron ', num2str(NeuronIndex),' Output Spike Time ',num2str(length(ts)),': ' num2str(ts(end)), ' (Next Cyclic Spike)']);
0209 end
0210
0211
0212 elseif ~isempty(thp) && (thp(end)>(ThFPP+1e-5)) && Io<0
0213 ts(end+1)=ti(end,2)+(1/Beta)*atanh(1/c1);
0214 if (Verbose==1)
0215 disp(['---> Neuron ', num2str(NeuronIndex),' Output Spike Time ',num2str(length(ts)),': ' num2str(ts(end)), ' (Final Trajectory Spike)']);
0216 end
0217
0218 elseif isempty(thp) && (CurrentNeuron.Phase>(ThFPP+1e-5)) && Io<0
0219 ts(end+1)=(1/Beta)*atanh(1/c1);
0220 if (Verbose==1)
0221 disp(['---> Neuron ', num2str(NeuronIndex),' Output Spike Time ',num2str(length(ts)),': ' num2str(ts(end)), ' (Final Trajectory Spike, No Input Spikes)']);
0222 end
0223 end
0224
0225
0226
0227 elseif strcmp(SimulationMethod,'Numerical')
0228 f_count=0;
0229
0230
0231 if Io<0
0232 t_bl=(1/Beta)*atanh(Beta/tan((ThFPP+0.0001)/2));
0233 if ~isempty(ti)
0234 int_limit=(ti(end,2)+1.5*t_bl)/TimeStep;
0235 else
0236 int_limit=1.1*t_bl/TimeStep;
0237 end
0238 else
0239 t_period=pi/Beta;
0240 int_limit=(ti(end,2)+1.5*t_period)/TimeStep;
0241 end
0242 Theta=zeros(1,ceil(int_limit));
0243 Theta(1)=ThFPP+0.0001;
0244 for j=1:int_limit
0245
0246
0247 Theta(j+1)=Theta(j)+TimeStep*((1-cos(Theta(j)))+Alpha*Io*(1+cos(Theta(j))));
0248
0249
0250 for k=(f_count+1):size(ti,1)
0251 if ((ti(k,2)>=j*TimeStep) && (ti(k,2)<(j+1)*TimeStep))
0252 if (Verbose==1)
0253 disp(' ');
0254 disp(['--->Input Spike Time ', num2str(k), ' (Neuron ', num2str(ti(k,1)), '): ', num2str(ti(k,2))]);
0255 end
0256 thm(k)=Theta(j+1);
0257 if (Verbose==1)
0258 disp(['--->Pre -Spike Phase: ' num2str(thm(k))]);
0259 end
0260 Theta(j+1)=Theta(j+1)+Weights(ti(k,1),NeuronIndex)*Alpha*(1+cos(Theta(j+1)));
0261 thp(k)=Theta(j+1);
0262 if (Verbose==1)
0263 disp(['--->Post-Spike Phase: ' num2str(thp(k))]);
0264 disp(['--->Weight and Delay: ' num2str(Weights(ti(k,1),NeuronIndex)), ' ', num2str(Delays(ti(k,1),NeuronIndex))]);
0265 if thp(k)<ThFPP && thp(k)>-ThFPP && Io<0;
0266 disp(['--->Operating Below Positive Fixed Point (',num2str(ThFPP),') - Neuron may not fire again']);
0267 end
0268 end
0269 f_count=f_count+1;
0270 else
0271 break;
0272 end
0273 end
0274
0275
0276 if ((f_count==size(ti,1) && Theta(j+1)<ThFPP && Io<0) || (~isempty(ts) && ti(end,2)<ts(end) && Io>0))
0277 break;
0278 end
0279
0280
0281 if Theta(j+1)>pi && Theta(j)<=pi
0282 ts(end+1)=j*TimeStep;
0283 if (Verbose==1)
0284 disp(['---> Neuron ', num2str(NeuronIndex),' Output Spike Time ',num2str(length(ts)),': ' num2str(ts(end))]);
0285 end
0286 Theta(j+1)=Theta(j+1)-2*pi;
0287 end
0288
0289
0290 if Theta(j+1)>-pi && Theta(j)<=-pi
0291 Theta(j+1)=Theta(j+1)+2*pi;
0292 end
0293 end
0294 Theta=Theta(1:j+1);
0295
0296
0297 else
0298 disp('Error in running networked theta neuron: Unknown theta neuron simulation method!');
0299 if (Verbose==1)
0300 disp('******** End function "run" for single neurons in a theta neuron network ********');
0301 end
0302 return;
0303 end
0304
0305
0306 if (Verbose==1) && ~isempty(ts)
0307 disp(' ');
0308 disp(['---> Neuron ', num2str(NeuronIndex),' Output Spike Times : ' num2str(ts)]);
0309 elseif (Verbose==1)
0310 disp(' ');
0311 disp(['---> Neuron ', num2str(NeuronIndex),' does not Fire after receiving all the input spikes!']);
0312 end
0313
0314
0315 if NIPS2007Gradient==1 && isempty(ts)
0316 ts=20;
0317 end
0318
0319
0320
0321 if GradFlag
0322
0323
0324 DthpDthpm1=zeros(1,length(thp));
0325 DthpDthpm1(1)=1;
0326 for m=2:length(thp)
0327 if Io<0
0328 c1=tan(thp(m-1)/2)/Beta;
0329 c2=tanh(-Beta*(ti(m,2)-ti(m-1,2)));
0330 DthpDthpm1(m)=(1-c2^2)*(1+(Beta*c1)^2)/((1+c1*c2)^2+(Beta*(c1+c2))^2);
0331
0332 if (Verbose==1)
0333 disp(' ');
0334 disp(['Test Numerical Gradient for Effect of Spike ', num2str(m-1), ' on Phase at Spike ', num2str(m)]);
0335 c1=tan(thp(m-1)/2)/Beta;
0336 thm_test(2)=(1-Alpha*Weights(ti(m,1),NeuronIndex)*sin(thm(m)))*...
0337 2*atan( Beta*(exp(-2*Beta*(ti(m,2)-ti(m-1,2)))*(1+c1)-(1-c1))...
0338 /(exp(-2*Beta*(ti(m,2)-ti(m-1,2)))*(1+c1)+1-c1) );
0339 c1=tan((thp(m-1)-0.001)/2)/Beta;
0340 thm_test(1)=(1-Alpha*Weights(ti(m,1),NeuronIndex)*sin(thm(m)))*...
0341 2*atan( Beta*(exp(-2*Beta*(ti(m,2)-ti(m-1,2)))*(1+c1)-(1-c1))...
0342 /(exp(-2*Beta*(ti(m,2)-ti(m-1,2)))*(1+c1)+1-c1) );
0343 c1=tan((thp(m-1)+0.001)/2)/Beta;
0344 thm_test(3)=(1-Alpha*Weights(ti(m,1),NeuronIndex)*sin(thm(m)))*...
0345 2*atan( Beta*(exp(-2*Beta*(ti(m,2)-ti(m-1,2)))*(1+c1)-(1-c1))...
0346 /(exp(-2*Beta*(ti(m,2)-ti(m-1,2)))*(1+c1)+1-c1) );
0347 df=gradient(thm_test,0.001);
0348 disp('Numerical and Analytical Should Agree');
0349 disp(['Numerical Value: ', num2str(df(2))]);
0350 disp(['Analytical Value: ', num2str(DthpDthpm1(m)*(1-Alpha*Weights(ti(m,1),NeuronIndex)*sin(thm(m))))]);
0351 end
0352 else
0353 c1=tan(thp(m-1)/2)/Beta;
0354 c2=tan(Beta*(ti(m,2)-ti(m-1,2)));
0355 DthpDthpm1(m)=(1+c2^2)*(1+(Beta*c1)^2)/((1-c1*c2)^2+(Beta*(c1+c2))^2);
0356
0357 if (Verbose==1)
0358 disp(' ');
0359 disp(['Test Numerical Gradient for Effect of Spike ', num2str(m-1), ' on Phase at Spike ', num2str(m)]);
0360 c1=tan((thp(m-1)-0.001)/2)/Beta;
0361 thm_test(1)=(1-Alpha*Weights(ti(m,1),NeuronIndex)*sin(thm(m)))*...
0362 2*atan(Beta*((tan(Beta*(ti(m,2)-ti(m-1,2)))+c1)/(1-c1*tan(Beta*(ti(m,2)-ti(m-1,2))))));
0363 c1=tan(thp(m-1)/2)/Beta;
0364 thm_test(2)=(1-Alpha*Weights(ti(m,1),NeuronIndex)*sin(thm(m)))*...
0365 2*atan(Beta*((tan(Beta*(ti(m,2)-ti(m-1,2)))+c1)/(1-c1*tan(Beta*(ti(m,2)-ti(m-1,2))))));
0366 c1=tan((thp(m-1)+0.001)/2)/Beta;
0367 thm_test(3)=(1-Alpha*Weights(ti(m,1),NeuronIndex)*sin(thm(m)))*...
0368 2*atan(Beta*((tan(Beta*(ti(m,2)-ti(m-1,2)))+c1)/(1-c1*tan(Beta*(ti(m,2)-ti(m-1,2))))));
0369 df=gradient(thm_test,0.001);
0370 disp('Numerical and Analytical For DthpDthpm1 Should Agree');
0371 disp(['Numerical Value: ', num2str(df(2))]);
0372 disp(['Analytical Value: ', num2str(DthpDthpm1(m)*(1-Alpha*Weights(ti(m,1),NeuronIndex)*sin(thm(m))))]);
0373 end
0374
0375 end
0376 DthpDthpm1(m)=DthpDthpm1(m)*(1-Alpha*Weights(ti(m,1),NeuronIndex)*sin(thm(m)));
0377 end
0378
0379
0380
0381
0382
0383 Y=zeros(size(Weights,1), length(ts));
0384 Z=zeros(size(ti,1), length(ts));
0385
0386
0387 for r=1:length(ts)
0388 if isempty(ti) break; end
0389 last_fire_index=find(ti(:,2)<ts(r),1,'last');
0390 yD=(1-cos(thp(last_fire_index)) + Alpha*Io* (1+cos(thp(last_fire_index))));
0391
0392
0393 SpikeCount=ones(max(ti(:,1)),1);
0394 for q=1:last_fire_index
0395 n=ti(q,1);
0396
0397
0398
0399
0400 if NIPS2007Gradient==1
0401 y_temp=((-Alpha*(1+cos(thm(q)))) / ((1-cos(thp(q)))+ Alpha*Io*(1+cos(thp(q)))));
0402 else
0403 y_temp=((-Alpha*(1+cos(thm(q)))) / yD) * prod(DthpDthpm1((q+1):last_fire_index));
0404 end
0405
0406
0407 if Weights(n,NeuronIndex)
0408 Y(n,r)=Y(n,r)+y_temp;
0409 end
0410 SpikeCount(n)=SpikeCount(n)+1;
0411
0412
0413 gamma=(1/(Alpha*(1+cos(thm(q))))) * (-((1-cos(thp(q)))+Alpha*Io*(1+cos(thp(q)))) + ...
0414 ((1-Alpha*Weights(n,NeuronIndex)*sin(thm(q))) * ((1-cos(thm(q)))+Alpha*Io*(1+cos(thm(q))))) );
0415 Z(q,r)=gamma*y_temp;
0416
0417 end
0418 SpikeCount=max(SpikeCount-1,1);
0419
0420
0421
0422
0423 end
0424
0425
0426 if NIPS2007Gradient==1 && min(min(Y))<-1000
0427 Y(find(Y<-1000))=-1000;
0428 end
0429 end
0430
0431
0432 if (Verbose==1)
0433 disp('******** End function "run" for single neurons in a theta neuron network ********');
0434 end
0435 return;