00001
00002
00003
00004
00005 #include "stdafx.h"
00006 #include "thetaNeuron.h"
00007
00008 using namespace std;
00009
00010
00011 void thetaNeuron::displayThetaNeuron(void) {
00012 cout << endl;
00013 cout << "Neuron Properties: " << endl;
00014 cout << "\tBeta: " << beta << endl;
00015 cout << "\tIo: " << io << endl;
00016 cout << "\tPositive Fixed Point: " << positive_fixed_point << endl;
00017 cout << "\tPhase: " << phase << endl;
00018 cout << "\tNumber of Inputs: " << num_inputs << endl;
00019 cout << "\tWeights: ";
00020 showArray<double>(weights,num_inputs);
00021 cout << endl << endl;
00022 }
00023
00024
00025 int thetaNeuron::runThetaNeuron(double ti[], double ts[], int max_num_ts=MAX_NUM_OUTPUT_SPIKES) {
00026 double thm;
00027 double thp;
00028 double t_bl=(1/beta)*atanh(beta/tan((positive_fixed_point+OFFSET)/2));
00029 int num_output_spikes=0;
00030 int* indices = NULL;
00031 indices = new int[num_inputs];
00032
00033
00034 double* ti_copy = NULL;
00035 ti_copy = new double[num_inputs];
00036 for (int j=0;j<num_inputs;j++) {
00037 ti_copy[j]=ti[j];
00038 }
00039
00040
00041 sortArray(ti_copy,indices,num_inputs);
00042
00043 if (verbose==true) {
00044 cout << "Input Spike Times: ";
00045 showArray<double>(ti_copy,num_inputs);
00046 cout << "Input Spike Indices: ";
00047 showArray<int>(indices,num_inputs);
00048 cout << "Baseline Firing Time: " << t_bl << endl;
00049 }
00050
00051 if (method==EventDriven) {
00052
00053 double prev_time=0;
00054 double prev_thp=phase;
00055 double c1, c2;
00056
00057 for (int j=0; j<num_inputs; j++) {
00058 c1=(1/beta)*tan(prev_thp/2);
00059 if (j==0) {
00060 c2=beta*(c1+tanh(-beta*ti_copy[j]))/(1+c1*tanh(-beta*ti_copy[j]));
00061 }
00062 else {
00063 c2=beta*(c1+tanh(-beta*(ti_copy[j]-ti_copy[j-1])))/(1+c1*tanh(-beta*(ti_copy[j]-ti_copy[j-1])));
00064 }
00065 thm=2*atan(c2);
00066 thp=2*atan(ALPHA*weights[indices[j]]+c2);
00067 if (verbose==true) {
00068 cout << "--->Input Spike Time " << j << " (Neuron " << indices[j] << "): " << ti_copy[j] << endl;
00069 cout << "--->Pre -Spike Phase: " << thm << endl;
00070 cout << "--->Post-Spike Phase: " << thp << endl;
00071 cout << "--->Weight: " << weights[indices[j]] << endl;
00072 if (thp<positive_fixed_point && thp>-positive_fixed_point) {
00073 cout << "--->Operating Below Positive Fixed Point (" << positive_fixed_point << ") - Neuron may not fire again" << endl;
00074 }
00075 }
00076
00077
00078 if (thp>PI && 2*atan(c2)<=PI) {
00079 ts[num_output_spikes]=ti_copy[j];
00080 num_output_spikes++;
00081 thp=thp-2*PI;
00082 if (verbose==true) {
00083 cout << "---> Neuron Output Spike Time " << num_output_spikes << ": " << ts[num_output_spikes-1] << endl;
00084 }
00085 }
00086
00087
00088
00089
00090
00091 else if (prev_thp<PI && prev_thp>positive_fixed_point && 2*atan(c2)>-PI && 2*atan(c2)<=(-positive_fixed_point+10*EPS)) {
00092 ts[num_output_spikes]=prev_time+(1/beta)*atanh(1/c1);
00093 num_output_spikes++;
00094 if (verbose==true) {
00095 cout << "---> Neuron Output Spike Time " << num_output_spikes << ": " << ts[num_output_spikes-1] << endl;
00096 }
00097 }
00098 prev_time=ti_copy[j];
00099 prev_thp=thp;
00100
00101 if (num_output_spikes==max_num_ts) {
00102 return num_output_spikes;
00103 }
00104 }
00105
00106
00107 if (num_inputs>0)
00108 c1=tan(thp/2)/beta;
00109 else
00110 c1=tan(phase/2)/beta;
00111
00112
00113
00114 if (num_inputs>0 && (thp>(positive_fixed_point+1e-5))) {
00115 ts[num_output_spikes]=ti_copy[num_inputs-1]+(1/beta)*atanh(1/c1);
00116 num_output_spikes++;
00117 if (verbose==true) {
00118 cout << "---> Neuron Output Spike Time " << num_output_spikes << ": " << ts[num_output_spikes-1] << endl;
00119 }
00120 }
00121 else if (num_inputs==0 && (phase>(positive_fixed_point+1e-5))) {
00122 ts[num_output_spikes]=(1/beta)*atanh(1/c1);
00123 num_output_spikes++;
00124 if (verbose==true) {
00125 cout << "---> Neuron Output Spike Time " << num_output_spikes << ": " << ts[num_output_spikes-1] << endl;
00126 }
00127 }
00128 }
00129
00130 else if (method==Numerical) {
00131 int f_count=0;
00132 double theta_now=phase;
00133 double theta_past=phase;
00134 double int_limit;
00135
00136
00137 if (num_inputs>0) {int_limit=(ti_copy[num_inputs-1]+1.5*t_bl)/TIMESTEP;}
00138 else {int_limit=1.1*t_bl/TIMESTEP;}
00139
00140 for (int j=0;j<int_limit;j++) {
00141 theta_now=theta_past + TIMESTEP * ((1-cos(theta_past))+ALPHA*io*(1+cos(theta_past)));
00142 for (int k=f_count;k<num_inputs;k++) {
00143 if ((ti_copy[k]>=j*TIMESTEP) && (ti_copy[k]<((j+1)*TIMESTEP))) {
00144 if (verbose==true) {
00145 cout << "--->Input Spike Time " << k << " (Neuron " << indices[k] << "): " << ti_copy[k] << endl;
00146 }
00147 thm=theta_now;
00148 if (verbose==true) {
00149 cout << "--->Pre -Spike Phase: " << thm << endl;
00150 }
00151 theta_now=2*atan(ALPHA*weights[indices[k]]+tan(theta_now/2));
00152 thp=theta_now;
00153 if (verbose==true) {
00154 cout << "--->Post-Spike Phase: " << thp << endl;
00155 cout << "--->Weight: " << weights[indices[k]] << endl;
00156 }
00157 f_count++;
00158 }
00159 else
00160 break;
00161 }
00162
00163
00164 if (f_count==num_inputs && theta_now<positive_fixed_point) {
00165 break;
00166 }
00167
00168
00169 if (theta_now>PI && theta_past<=PI) {
00170 num_output_spikes++;
00171 ts[num_output_spikes-1]=j*TIMESTEP;
00172 if (verbose==true) {
00173 cout << "---> Neuron Output Spike Time " << num_output_spikes << ": " << ts[num_output_spikes-1] << endl;
00174 }
00175 theta_now=theta_now-2*PI;
00176 if (num_output_spikes==max_num_ts) {
00177 return num_output_spikes;
00178 }
00179 }
00180
00181
00182 if (theta_now>-PI && theta_past<=-PI) {
00183 theta_now=theta_now+2*PI;
00184 }
00185
00186
00187 theta_past=theta_now;
00188 }
00189 }
00190
00191 if (verbose==true) {
00192 cout << endl;
00193 }
00194
00195
00196 delete [] indices;
00197 indices = NULL;
00198 delete [] ti_copy;
00199 ti_copy = NULL;
00200
00201 return num_output_spikes;
00202
00203
00204 }
00205