poly_spnet.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077
  1. // poly_spnet.cpp
  2. // This source code was downloaded from the authors website: https://www.izhikevich.org/publications/spnet.htm
  3. // Modifications are marked with --GT, ++GT
  4. // #include <iostream.h> // --GT
  5. #include <iostream> // ++GT
  6. #include <math.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <malloc.h>
  10. #include <time.h>
  11. using namespace std; // ++GT
  12. #define rand01 (0.9999999*double(rand())/RAND_MAX)
  13. #define getrandom(max1) (((rand())%(max1))) // random integer between 0 and max-1
  14. //There are two implementations of polychronous group search algorithm here.
  15. // The old one is event-trigered (very fast).
  16. // The new one is activity-trigered (slow, but more precise).
  17. // By default, the new definition is used. Uncomment the line below to use the old one.
  18. //#define old_definition_of_polychronous
  19. //M=100; % the number of synapses per neuron
  20. const int M = 100;
  21. //D=10; % maximal axonal conduction delay
  22. const int D=20;
  23. //% excitatory neurons inhibitory neurons total number
  24. //Ne=800; Ni=200; N=Ne+Ni;
  25. const int Ne =800;
  26. const int Ni =200;
  27. const int N = Ne+Ni;
  28. double C_max=10;
  29. #if( ODE_SOLVER_REFINEMENT ) // ++GT (precise threshold detection)
  30. int spike[N]; // spike count in simulation step
  31. #endif
  32. const int W=3; // initial width of polychronous groups
  33. int min_group_path = 7; // minimal length of a group
  34. int min_group_time = 40; // minimal duration of a group (ms)
  35. double a[N], d[N]; //
  36. int post[N][M]; //
  37. double s[N][M], sd[N][M]; //
  38. short delays[N][D][M]; //
  39. short delays_length[N][D]; //
  40. int N_pre[N], I_pre[N][3*M], D_pre[N][3*M]; //
  41. double *s_pre[N][3*M], *sd_pre[N][3*M];
  42. double LTP[N][1001+D], LTD[N]; //
  43. double v[N], u[N]; //
  44. int N_firings;
  45. const int N_firings_max=100000;
  46. int firings[N_firings_max][2];
  47. void initialize()
  48. { int i,j,k,jj,dd, exists, r;
  49. // a=[0.02*ones(Ne,1); 0.1*ones(Ni,1)];
  50. for (i=0;i<Ne;i++) a[i]=0.02;
  51. for (i=Ne;i<N;i++) a[i]=0.1;
  52. // d=[ 8*ones(Ne,1); 2*ones(Ni,1)];
  53. for (i=0;i<Ne;i++) d[i]=8;
  54. for (i=Ne;i<N;i++) d[i]=2;
  55. // post=ceil([Ne+Ni*rand(Ne,M*Ni/N),Ne*rand(Ne,M*Ne/N);Ne*rand(Ni,M)]);
  56. for (i=0;i<Ne;i++)
  57. {
  58. for (j=0;j<M;j++)
  59. {
  60. do
  61. {
  62. exists = 0;
  63. r = int(floor(N*rand01));
  64. if (r == i) exists=1;
  65. for (k=0;k<j;k++) if (post[i][k] == r) exists = 1;
  66. }
  67. while (exists == 1);
  68. post[i][j]=r;
  69. }
  70. }
  71. for (i=Ne;i<N;i++)
  72. {
  73. for (j=0;j<M;j++)
  74. {
  75. do
  76. {
  77. exists = 0;
  78. r = int(floor(Ne*rand01));
  79. for (k=0;k<j;k++) if (post[i][k] == r) exists = 1;
  80. }
  81. while (exists == 1);
  82. post[i][j]=r;
  83. }
  84. }
  85. // s=[6*ones(Ne,M);-5*ones(Ni,M)]; % initial synaptic weights
  86. for (i=0;i<Ne;i++) for (j=0;j<M;j++) s[i][j]=6;
  87. for (i=Ne;i<N;i++) for (j=0;j<M;j++) s[i][j]=-5;
  88. // sd=zeros(N,M); % derivatives of synaptic weights
  89. for (i=0;i<N;i++)for (j=0;j<M;j++) sd[i][j]=0;
  90. // for i=1:N
  91. for (i=0;i<N;i++)
  92. {
  93. short ind=0;
  94. // if i<=Ne
  95. if (i<Ne)
  96. {
  97. // for j=1:D
  98. // delays{i,j}=M/D*(j-1)+(1:M/D);
  99. // end;
  100. for (j=0;j<D;j++)
  101. { delays_length[i][j]=M/D;
  102. for (k=0;k<delays_length[i][j];k++)
  103. delays[i][j][k]=ind++;
  104. }
  105. }
  106. // else
  107. // delays{i,1}=1:M;
  108. // end;
  109. else
  110. {
  111. for (j=0;j<D;j++) delays_length[i][j]=0;
  112. delays_length[i][0]=M;
  113. for (k=0;k<delays_length[i][0];k++)
  114. delays[i][0][k]=ind++;
  115. }
  116. }
  117. // pre{i} = find(post==i & s>0); % Indeces of pre excitatory neurons
  118. // aux{i} = N*(D-1-ceil(ceil(pre{i}/N)/(M/D))) + 1+mod(pre{i}-1,N);
  119. for (i=0;i<N;i++)
  120. {
  121. N_pre[i]=0;
  122. for (j=0;j<Ne;j++)
  123. for (k=0;k<M;k++)
  124. if (post[j][k] == i)
  125. {
  126. I_pre[i][N_pre[i]]=j;
  127. for (dd=0;dd<D;dd++)
  128. for (jj=0;jj<delays_length[j][dd];jj++)
  129. if (post[j][delays[j][dd][jj]]==i) D_pre[i][N_pre[i]]=dd;
  130. s_pre[i][N_pre[i]]=&s[j][k];
  131. sd_pre[i][N_pre[i]++]=&sd[j][k];
  132. }
  133. // end;
  134. }
  135. // LTP = zeros(N,1001+D);
  136. for (i=0;i<N;i++)
  137. for (j=0;j<1+D;j++)
  138. LTP[i][j]=0;
  139. // LTD = zeros(N,1);
  140. for (i=0;i<N;i++) LTD[i]=0;
  141. // v = -65+10*rand(N,1); % initial values for v
  142. // for (i=0;i<N;i++) v[i]=-65+10*rand01; // --GT
  143. for (i=0;i<N;i++) v[i]=-65; // ++GT
  144. // u = 0.2.*v; % initial values for u
  145. for (i=0;i<N;i++) u[i]=0.2*v[i];
  146. // firings=[-D 0]; % spike timings
  147. N_firings=1;
  148. firings[0][0]=-D;
  149. firings[0][1]=0;
  150. }
  151. // ----------------------------------------------------------------------------------
  152. void save_all(char fname[30])
  153. {
  154. int i,j,k;
  155. FILE *fce;
  156. fce = fopen(fname,"w");
  157. cout << "\nsaving data \n";
  158. for (i=0; i < N; ++i)
  159. {
  160. fprintf(fce, "%5.3f %5.3f \n", v[i], u[i]);
  161. for (j=0; j < M; ++j)
  162. fprintf(fce, "%d %5.3f %6.5f \n", post[i][j], s[i][j], sd[i][j]);
  163. for (k=0; k < D; ++k)
  164. {
  165. fprintf(fce, "%d ", delays_length[i][k]);
  166. for (j=0; j < delays_length[i][k]; ++j)
  167. fprintf(fce, "%d ", delays[i][k][j]);
  168. fprintf(fce, "\n");
  169. }
  170. fprintf(fce, "%d ", N_pre[i]);
  171. for (j=0; j < N_pre[i]; ++j)
  172. fprintf(fce, "%d %d ", I_pre[i][j], D_pre[i][j]);
  173. fprintf(fce, "\n %5.4f ", LTD[i]);
  174. for (j=0; j < D+1; ++j)
  175. fprintf(fce, "%5.4f ", LTP[i][j]);
  176. fprintf(fce, "\n");
  177. }
  178. fprintf(fce, " %d", N_firings);
  179. for (i=0; i < N_firings; ++i)
  180. fprintf(fce, "%d %d ", firings[i][0],firings[i][1]);
  181. fclose(fce);
  182. }
  183. // ----------------------------------------------------------------------------------
  184. void load_all(char fname[30])
  185. {
  186. // cout << "\nloading data \n";
  187. int i,j, k, Np;
  188. float x;
  189. int dd;
  190. FILE *stream;
  191. stream = fopen( fname, "r" );
  192. if( stream == NULL )
  193. cout << " \n Error: The file " << fname << " cannot be opened \n";
  194. else
  195. {
  196. /* Set pointer to beginning of file: */
  197. fseek( stream, 0L, SEEK_SET );
  198. for (i=0; i < N; ++i)
  199. {
  200. fscanf( stream, "%f", &x);
  201. v[i]=x;
  202. fscanf( stream, "%f", &x);
  203. u[i]=x;
  204. for (j=0; j < M; ++j)
  205. {
  206. fscanf( stream, "%d", &dd);
  207. post[i][j]=dd;
  208. fscanf( stream, "%f", &x);
  209. s[i][j]=x;
  210. fscanf( stream, "%f", &x);
  211. sd[i][j]=x;
  212. }
  213. for (k=0; k < D; ++k)
  214. {
  215. fscanf( stream, "%d", &dd);
  216. delays_length[i][k]=dd;
  217. for (j=0; j < delays_length[i][k]; ++j)
  218. {
  219. fscanf( stream, "%d", &dd);
  220. delays[i][k][j]=dd;
  221. }
  222. }
  223. fscanf( stream, "%d", &dd);
  224. N_pre[i] = dd;
  225. for (j=0; j < N_pre[i]; ++j)
  226. {
  227. fscanf( stream, "%d", &dd);
  228. I_pre[i][j]=dd;
  229. fscanf( stream, "%d", &dd);
  230. D_pre[i][j]=dd;
  231. }
  232. fscanf( stream, "%f", &x);
  233. LTD[i]=x;
  234. for (j=0; j < D+1; ++j)
  235. {
  236. fscanf( stream, "%f", &x);
  237. LTP[i][j]=x;
  238. }
  239. }
  240. fscanf( stream, "%d", &dd);
  241. N_firings=dd;
  242. for (i=0; i < N_firings; ++i)
  243. {
  244. fscanf( stream, "%d", &dd);
  245. firings[i][0]=dd;
  246. fscanf( stream, "%d", &dd);
  247. firings[i][1]=dd;
  248. }
  249. fclose( stream );
  250. for (i=0; i < N; ++i)
  251. {
  252. for (Np=0;Np<N_pre[i];Np++)
  253. {
  254. j = I_pre[i][Np];
  255. for (k=0;k<M;k++)
  256. if (post[j][k] == i)
  257. {
  258. s_pre[i][Np]=&s[j][k];
  259. sd_pre[i][Np++]=&sd[j][k];
  260. }
  261. }
  262. }
  263. }
  264. }
  265. //--------------------------------------------------------------
  266. int N_polychronous;
  267. double C_rel = 0.95*C_max;
  268. const int polylenmax = N;
  269. int N_postspikes[polylenmax], I_postspikes[polylenmax][N], J_postspikes[polylenmax][N], D_postspikes[polylenmax][N], L_postspikes[polylenmax][N];
  270. double C_postspikes[polylenmax][N];
  271. int N_links, links[2*W*polylenmax][4];
  272. int group[polylenmax], t_fired[polylenmax], layer[polylenmax];
  273. int gr3[W], tf3[W];
  274. int I_my_pre[3*M], D_my_pre[3*M], N_my_pre;
  275. int N_fired;
  276. FILE *fpoly;
  277. #ifdef old_definition_of_polychronous
  278. //This is the old definition of polychronous groups
  279. //--------------------------------------------------------------
  280. const int V=2; // number of spikes needed to fire a cell
  281. int latency = 4; // latency from the moment spikes arrive to the moment the neuron fires
  282. int tf_final=2;
  283. int inh_span=5;
  284. int slacke = 0;
  285. int slacki = 0;
  286. int pre_list[3*M], del_list[3*M];
  287. int inh_list[3*Ni*M],t_inh_list[3*Ni*M], N_inh_list;
  288. //--------------------------------------------------------------
  289. void polychronous(int nnum)
  290. {
  291. int i,j, t, tf, p, k;
  292. int npre[W];
  293. int d, exc, NL, NL_max;
  294. int t_fire, t_last, timing;
  295. int N_fired, Dmax, already;
  296. int first, last;
  297. int used[W], discard;
  298. N_my_pre = 0;
  299. for (i=0;i<N_pre[nnum];i++)
  300. if (*s_pre[nnum][i] > C_rel)
  301. {
  302. I_my_pre[N_my_pre]=I_pre[nnum][i];
  303. D_my_pre[N_my_pre]=D_pre[nnum][i];
  304. N_my_pre++;
  305. }
  306. if (N_my_pre<W) return;
  307. for (i=0;i<W;i++) npre[i]=i;
  308. while (0==0)
  309. {
  310. Dmax=0;
  311. for (i=0;i<W;i++) if (Dmax < D_my_pre[npre[i]]) Dmax=D_my_pre[npre[i]];
  312. for (i=0;i<W;i++)
  313. {
  314. group[i]=I_my_pre[npre[i]];
  315. t_fired[i]= Dmax-D_my_pre[npre[i]];
  316. for (d=0; d<D; d++)
  317. for (j=0; j<delays_length[group[i]][d]; j++)
  318. {
  319. p = post[group[i]][delays[group[i]][d][j]];
  320. if (((s[group[i]][delays[group[i]][d][j]] > C_rel) & (d>=D_my_pre[npre[i]])) | (p >=Ne))
  321. {
  322. timing = t_fired[i]+d+1;
  323. J_postspikes[timing][N_postspikes[timing]]=group[i]; // presynaptic
  324. D_postspikes[timing][N_postspikes[timing]]=d; // delay
  325. L_postspikes[timing][N_postspikes[timing]]=1; // layer
  326. I_postspikes[timing][N_postspikes[timing]++]=p;// index of post target
  327. }
  328. }
  329. }
  330. N_inh_list=0;
  331. NL_max = 1;
  332. N_links = 0;
  333. N_fired=W;
  334. t_last = D+D+latency+1;
  335. for (t=0;t<t_last;t++)
  336. while (N_postspikes[t] >0)
  337. {
  338. N_postspikes[t]--;
  339. already = 0;
  340. if (I_postspikes[t][N_postspikes[t]] <Ne)
  341. {
  342. for (j=0;j<N_fired;j++)
  343. if ((I_postspikes[t][N_postspikes[t]] == group[j]) & (t_fired[j] > t-20)) already = 2;
  344. for (j=0;j<N_inh_list;j++)
  345. if ((inh_list[j]==I_postspikes[t][N_postspikes[t]]) & (t_inh_list[j]<=t)&(t_inh_list[j]+inh_span>=t)) already++;
  346. }
  347. else
  348. {
  349. for (j=0;j<N_fired;j++)
  350. if ((I_postspikes[t][N_postspikes[t]] == group[j]) & (t_fired[j] > t-20)) already = 2;
  351. }
  352. if ((already<=0) & (N_fired < polylenmax))
  353. {
  354. NL = 0;
  355. exc=0;
  356. first = -1;
  357. t_fire = t+4;
  358. for (tf=0;tf<=tf_final;tf++)
  359. for (j=0;j<=N_postspikes[t+tf]-0.5*tf;j++)
  360. if (I_postspikes[t+tf][j]==I_postspikes[t][N_postspikes[t]])
  361. {
  362. if (first < 0) first = tf;
  363. last = tf;
  364. pre_list[exc]=J_postspikes[t+tf][j];
  365. del_list[exc]=D_postspikes[t+tf][j];
  366. exc++;
  367. t_fire = t+tf;
  368. if (NL <L_postspikes[t+tf][j]) NL=L_postspikes[t+tf][j];
  369. }
  370. if (((first+1>=last) & (exc>=V-slacke)) | (((I_postspikes[t][N_postspikes[t]]<Ne)&(exc>=V)) | ((I_postspikes[t][N_postspikes[t]]>=Ne)&(first+2>=last)&(exc>=V-slacki))))
  371. {
  372. i = N_fired++;
  373. group[i]= I_postspikes[t][N_postspikes[t]];
  374. t_fired[i]= t_fire+latency;
  375. if (exc==2) t_fired[i]=t_fired[i]+latency; // longer latencies for weaker inputs
  376. for (j=0;j<exc;j++)
  377. {
  378. links[N_links][0]=pre_list[j];
  379. links[N_links][1]=group[i];
  380. links[N_links][2]=del_list[j];
  381. links[N_links++][3]=NL;
  382. }
  383. if (group[i] <Ne)
  384. {
  385. for (d=0; d<D; d++)
  386. for (j=0; j<delays_length[group[i]][d]; j++)
  387. if (s[group[i]][delays[group[i]][d][j]] > C_rel)
  388. {
  389. timing = t_fired[i]+d+1;
  390. J_postspikes[timing][N_postspikes[timing]]=group[i]; // presynaptic
  391. D_postspikes[timing][N_postspikes[timing]]=d; // delay
  392. L_postspikes[timing][N_postspikes[timing]]=NL+1; // layer
  393. I_postspikes[timing][N_postspikes[timing]++]=post[group[i]][delays[group[i]][d][j]];// index of post target
  394. }
  395. }
  396. else
  397. {
  398. for (d=0; d<D; d++)
  399. for (j=0; j<delays_length[group[i]][d]; j++)
  400. {
  401. inh_list[N_inh_list]= post[group[i]][delays[group[i]][d][j]];
  402. t_inh_list[N_inh_list++]= t_fired[i]+d;
  403. }
  404. j=0;
  405. while (t_inh_list[j]+inh_span<t) j++;
  406. if (j>10) // needs cleaning
  407. {
  408. for (k=j;k<N_inh_list;k++)
  409. {
  410. inh_list[k-j]= inh_list[k];
  411. t_inh_list[k-j]= t_inh_list[k];
  412. }
  413. N_inh_list=N_inh_list-j;
  414. }
  415. }
  416. if (NL > NL_max) NL_max = NL;
  417. if (t_last < timing+1)
  418. {
  419. t_last = timing+1;
  420. if (t_last > polylenmax-D-latency-tf_final-1) t_last = polylenmax-D-latency-tf_final-1;
  421. }
  422. }
  423. }
  424. }
  425. if (t_last == polylenmax-D) for (d=t_last;d<polylenmax;d++) N_postspikes[d]=0;
  426. if ((NL_max>=min_group_path))
  427. {
  428. discard = 0;
  429. for (i=0;i<W;i++)
  430. {
  431. used[i]=0;
  432. for (j=0;j<N_links;j++) if ((links[j][0] == group[i]) & (links[j][1] < Ne)) used[i]++;
  433. if (used[i] == 1) discard = 1;
  434. }
  435. if (discard == 0)
  436. {
  437. N_polychronous++;
  438. cout << "\ni= " << nnum << ", N_polychronous= " << N_polychronous << ", N_fired = " << N_fired << ", NL = " << NL_max << ", T=" << t_fired[N_fired-1];
  439. fprintf(fpoly, " %d %d, ", N_fired, NL_max);
  440. for (j=0; j<N_fired; j++)
  441. fprintf(fpoly, " %d %d, ", group[j], t_fired[j]);
  442. fprintf(fpoly, " ");
  443. for (j=0; j<N_links; j++)
  444. fprintf(fpoly, " %d %d %d %d, ", links[j][0], links[j][1], links[j][2]+1, links[j][3]);
  445. fprintf(fpoly, "\n");
  446. }
  447. }
  448. i=1;
  449. while (++npre[W-i] > N_my_pre-i) if (++i > W) return;
  450. while (i>1) {npre[W-i+1]=npre[W-i]+1; i--;}
  451. }
  452. }
  453. #else
  454. // The new (default) algorithm to find polychronous groups
  455. const int latency = D; // maximum latency
  456. //--------------------------------------------------------------
  457. void polychronous(int nnum)
  458. {
  459. int i,j, t, p, k;
  460. int npre[W];
  461. int dd;
  462. int t_last, timing;
  463. int Dmax, L_max;
  464. int used[W], discard;
  465. double v[N],u[N],I[N];
  466. #if( ODE_SOLVER_REFINEMENT ) // ++GT
  467. printf("\nFIND POLYCHRONOUS GROUPS: nnum = %d\n", nnum);
  468. for( int i = 0; i < N; ++i) spike[i] = 0;
  469. #endif
  470. N_my_pre = 0;
  471. for (i=0;i<N_pre[nnum];i++)
  472. if (*s_pre[nnum][i] > C_rel)
  473. {
  474. I_my_pre[N_my_pre]=I_pre[nnum][i];
  475. D_my_pre[N_my_pre]=D_pre[nnum][i];
  476. N_my_pre++;
  477. }
  478. if (N_my_pre<W) return;
  479. for (i=0;i<W;i++) npre[i]=i;
  480. while (0==0)
  481. {
  482. Dmax=0;
  483. for (i=0;i<W;i++) if (Dmax < D_my_pre[npre[i]]) Dmax=D_my_pre[npre[i]];
  484. for (i=0;i<W;i++)
  485. {
  486. group[i]=I_my_pre[npre[i]];
  487. t_fired[i]= Dmax-D_my_pre[npre[i]];
  488. layer[i]=1;
  489. for (dd=0; dd<D; dd++)
  490. for (j=0; j<delays_length[group[i]][dd]; j++)
  491. {
  492. p = post[group[i]][delays[group[i]][dd][j]];
  493. if ((s[group[i]][delays[group[i]][dd][j]] > C_rel) & (dd>=D_my_pre[npre[i]]))
  494. {
  495. timing = t_fired[i]+dd+1;
  496. J_postspikes[timing][N_postspikes[timing]]=group[i]; // presynaptic
  497. D_postspikes[timing][N_postspikes[timing]]=dd; // delay
  498. C_postspikes[timing][N_postspikes[timing]]=s[group[i]][delays[group[i]][dd][j]]; // syn weight
  499. I_postspikes[timing][N_postspikes[timing]++]=p; // index of post target
  500. }
  501. }
  502. }
  503. for (i=0;i<N;i++) {v[i]=-70; u[i]=0.2*v[i]; I[i]=0;};
  504. N_links = 0;
  505. N_fired=W;
  506. t_last = D+D+latency+1;
  507. t=-1;
  508. while ((++t<t_last) & (N_fired < polylenmax))
  509. {
  510. for (p=0;p<N_postspikes[t];p++)
  511. I[I_postspikes[t][p]]+=C_postspikes[t][p];
  512. #if( ODE_SOLVER_REFINEMENT ) // ++GT
  513. for (i=0;i<N;i++) {
  514. for( int intCycles = 0; intCycles < ODE_SOLVER_STEPS; ++intCycles ) {
  515. v[i] += (1.0 / ODE_SOLVER_STEPS) * ((0.04 * v[i] + 5) * v[i] + 140 - u[i] + I[i]);
  516. u[i] += (1.0 / ODE_SOLVER_STEPS) * (a[i] * (0.2 * v[i] - u[i]));
  517. if (v[i] >= 30.0) { // precise threshold detection
  518. v[i] = -65.0;
  519. u[i] += d[i];
  520. spike[i]++;
  521. }
  522. }
  523. I[i]=0;
  524. }
  525. #else
  526. for (i=0;i<N;i++)
  527. {
  528. v[i]+=0.5*((0.04*v[i]+5)*v[i]+140-u[i]+I[i]);
  529. v[i]+=0.5*((0.04*v[i]+5)*v[i]+140-u[i]+I[i]);
  530. u[i]+=a[i]*(0.2*v[i]-u[i]);
  531. I[i]=0;
  532. }
  533. #endif
  534. for (i=0;i<N;i++)
  535. #if( ODE_SOLVER_REFINEMENT ) // ++GT (precise threshold detection)
  536. if (spike[i]>0)
  537. {
  538. if(spike[i]>1) printf("FIND POLYCHRONOUS GROUPS: more than one spike\n");
  539. spike[i]=0;
  540. #else
  541. if (v[i]>=30)
  542. {
  543. v[i] = -65;
  544. u[i]+=d[i];
  545. #endif
  546. if (N_fired < polylenmax)
  547. {
  548. t_fired[N_fired]= t;
  549. group[N_fired++]=i;
  550. for (dd=0; dd<D; dd++)
  551. for (j=0; j<delays_length[i][dd]; j++)
  552. if ((s[i][delays[i][dd][j]] > C_rel) | (i>=Ne))
  553. {
  554. timing = t+dd+1;
  555. J_postspikes[timing][N_postspikes[timing]]=i; // presynaptic
  556. D_postspikes[timing][N_postspikes[timing]]=dd; // delay
  557. // L_postspikes[timing][N_postspikes[timing]]=NL+1; // layer
  558. C_postspikes[timing][N_postspikes[timing]]=s[i][delays[i][dd][j]]; // syn weight
  559. I_postspikes[timing][N_postspikes[timing]++]=post[i][delays[i][dd][j]];// index of post target
  560. }
  561. if (t_last < timing+1)
  562. {
  563. t_last = timing+1;
  564. if (t_last > polylenmax-D-1) t_last = polylenmax-D-1;
  565. }
  566. }
  567. }
  568. }
  569. if (N_fired>2*W)
  570. {
  571. N_links=0;
  572. L_max=0;
  573. for (i=W;i<N_fired;i++)
  574. {
  575. layer[i]=0;
  576. for (p=t_fired[i]; (p>t_fired[i]-latency) & (p>=0); p--)
  577. for (j=0;j<N_postspikes[p];j++)
  578. if ((I_postspikes[p][j]==group[i]) & (J_postspikes[p][j]<Ne))
  579. {
  580. for (k=0;k<i;k++)
  581. if ((group[k]==J_postspikes[p][j]) & (layer[k]+1>layer[i])) layer[i]=layer[k]+1;
  582. {
  583. links[N_links][0]=J_postspikes[p][j];
  584. links[N_links][1]=I_postspikes[p][j];
  585. links[N_links][2]=D_postspikes[p][j];
  586. links[N_links++][3]=layer[i];
  587. if (L_max < layer[i]) L_max = layer[i];
  588. }
  589. }
  590. }
  591. discard = 0;
  592. for (i=0;i<W;i++)
  593. {
  594. used[i]=0;
  595. for (j=0;j<N_links;j++) if ((links[j][0] == group[i]) & (links[j][1] < Ne)) used[i]++;
  596. if (used[i] == 1) discard = 1;
  597. }
  598. // if ((discard == 0) & (t_fired[N_fired-1] > min_group_time) ) // (L_max >= min_group_path))
  599. if ((discard == 0) & (L_max >= min_group_path))
  600. {
  601. for (i=0;i<W;i++) {gr3[i]=group[i]; tf3[i]=t_fired[i];};
  602. N_polychronous++;
  603. cout << "\ni= " << nnum << ", N_polychronous= " << N_polychronous << ", N_fired = " << N_fired << ", L_max = " << L_max << ", T=" << t_fired[N_fired-1];
  604. // fprintf(fpoly, " %d %d, ", N_fired, L_max);
  605. // for (i=0; i<N_fired; i++)
  606. // fprintf(fpoly, " %d %d, ", group[i], t_fired[i]);
  607. // fprintf(fpoly, " ");
  608. // for (j=0;j<N_links;j++)
  609. // fprintf(fpoly, " %d %d %d %d, ", links[j][0], links[j][1], links[j][2], links[j][3]);
  610. // fprintf(fpoly, "\n");
  611. }
  612. }
  613. for (dd=Dmax;dd<t_last;dd++) N_postspikes[dd]=0;
  614. if (t_last == polylenmax-D) for (dd=t_last;dd<polylenmax;dd++) N_postspikes[dd]=0;
  615. i=1;
  616. while (++npre[W-i] > N_my_pre-i) if (++i > W) return;
  617. while (i>1) {npre[W-i+1]=npre[W-i]+1; i--;}
  618. }
  619. }
  620. #endif
  621. //--------------------------------------------------------------
  622. void all_polychronous()
  623. {
  624. int i;
  625. N_polychronous=0;
  626. fpoly = fopen("..//polyall.dat","w");
  627. for (i=0;i<polylenmax;i++) N_postspikes[i]=0;
  628. for (i=0;i<Ne;i++) polychronous(i);
  629. cout << "\nN_polychronous=" << N_polychronous << "\n";
  630. fclose(fpoly);
  631. }
  632. void shuffle()
  633. {
  634. int i, j, ri, rj;
  635. double x,y;
  636. cout << "***** scrambling ****";
  637. for (i=0;i<Ne;i++)
  638. for (j=0;j<M;j++)
  639. if (post[i][j] < Ne)
  640. {
  641. ri = int(floor(rand01*Ne));
  642. do
  643. {
  644. rj = int(floor(rand01*M));
  645. }
  646. while (post[ri][rj] >= Ne);
  647. x=s[ri][rj];
  648. y=sd[ri][rj];
  649. s[i][j]=s[ri][rj];
  650. sd[i][j]=sd[ri][rj];
  651. s[ri][rj]=x;
  652. sd[ri][rj]=y;
  653. }
  654. }
  655. // --------------------------------------------------------------------------
  656. // void main() // --GT
  657. int main() // ++GT
  658. {
  659. int i,j,k;
  660. int sec, t;
  661. double I[N];
  662. FILE *fs, *fx, *fd;
  663. #if( ODE_SOLVER_REFINEMENT ) // ++GT
  664. for( int i = 0; i < N; ++i ) {
  665. spike[i] = 0;
  666. }
  667. #endif
  668. srand(0);
  669. initialize();
  670. // for sec=1:60*60*5
  671. // for (sec=0; sec<60*60*5; sec++) // --GT
  672. for (sec=0; sec<60*60*1; sec++) // ++GT (set to 1 hour: determine the number of polychronous groups with
  673. // the refined ODE solver )
  674. {
  675. // for t=1:1000 % simulation of 1 sec
  676. for (t=0;t<1000;t++)
  677. {
  678. for (i=0;i<N;i++) I[i] = 0;
  679. I[int(floor(N*rand01))]=20;
  680. #if( ODE_SOLVER_REFINEMENT ) // ++GT
  681. for (i=0;i<N;i++)
  682. if (spike[i]>0) {
  683. if(spike[i] > 1 ) printf("more than 1 spike in interval\n");
  684. spike[i] = 0;
  685. LTP[i][t+D] = 0.1;
  686. LTD[i] = 0.12;
  687. for (j = 0; j<N_pre[i]; j++) *sd_pre[i][j] += LTP[I_pre[i][j]][t+D-D_pre[i][j]-1];
  688. firings[N_firings ][0] = t;
  689. firings[N_firings++][1] = i;
  690. if (N_firings == N_firings_max) {
  691. cout << "*** Two many spikes, t=" << t << "*** (ignoring)";
  692. N_firings = 1;
  693. }
  694. }
  695. #else
  696. for (i=0;i<N;i++)
  697. // fired = find(v>=30); % indices of fired neurons
  698. if (v[i]>=30)
  699. {
  700. // v(fired)=-65;
  701. v[i] = -65;
  702. // u(fired)=u(fired)+d(fired);
  703. u[i]+=d[i];
  704. // LTP(fired,t+D)=0.1;
  705. LTP[i][t+D]= 0.1;
  706. // LTD(fired)=0.12;
  707. LTD[i]=0.12;
  708. // for k=1:length(fired)
  709. // sd(pre{fired(k)}) = sd(pre{fired(k)})+LTP(N*t+aux{fired(k)});
  710. // end;
  711. for (j=0;j<N_pre[i];j++) *sd_pre[i][j]+=LTP[I_pre[i][j]][t+D-D_pre[i][j]-1];
  712. // firings=[firings; t+zeros(length(fired),1), fired];
  713. firings[N_firings ][0]=t;
  714. firings[N_firings++][1]=i;
  715. if (N_firings == N_firings_max)
  716. {
  717. cout << "*** Two many spikes, t=" << t << "*** (ignoring)";
  718. N_firings=1;
  719. }
  720. }
  721. #endif
  722. // k=size(firings,1);
  723. k=N_firings-1;
  724. // while t-firings(k,1)<D
  725. while (t-firings[k][0] <D)
  726. {
  727. // del=delays{firings(k,2),t-firings(k,1)+1};
  728. for (j=0; j< delays_length[firings[k][1]][t-firings[k][0]]; j++)
  729. {
  730. // ind = post(firings(k,2),del);
  731. i=post[firings[k][1]][delays[firings[k][1]][t-firings[k][0]][j]];
  732. // I(ind)=I(ind)+s(firings(k,2), del)';
  733. I[i]+=s[firings[k][1]][delays[firings[k][1]][t-firings[k][0]][j]];
  734. // if firings(k,2) <=Ne
  735. if (firings[k][1] <Ne)
  736. // sd(firings(k,2),del)=sd(firings(k,2),del)-LTD(ind)';
  737. sd[firings[k][1]][delays[firings[k][1]][t-firings[k][0]][j]]-=LTD[i];
  738. // end;
  739. }
  740. // k=k-1;
  741. k--;
  742. // end;
  743. }
  744. for (i=0;i<N;i++)
  745. {
  746. // v = v + 0.5*((0.04*v+5).*v+140-u+I); % for numerical stability
  747. // v = v + 0.5*((0.04*v+5).*v+140-u+I); % time step is 0.5 ms
  748. #if( ODE_SOLVER_REFINEMENT ) // ++GT
  749. for( int intCycles = 0; intCycles < ODE_SOLVER_STEPS; ++intCycles ) {
  750. v[i]+=(1.0/ODE_SOLVER_STEPS) * ((0.04*v[i]+5)*v[i]+140-u[i]+I[i]);
  751. u[i]+=(1.0/ODE_SOLVER_STEPS) * (a[i]*(0.2*v[i]-u[i]));
  752. if(v[i] >= 30.0 ) {
  753. v[i] = -65.0;
  754. u[i] += d[i];
  755. spike[i]++;
  756. }
  757. }
  758. #else
  759. v[i]+=0.5*((0.04*v[i]+5)*v[i]+140-u[i]+I[i]);
  760. v[i]+=0.5*((0.04*v[i]+5)*v[i]+140-u[i]+I[i]);
  761. // u = u + a.*(0.2*v-u);
  762. u[i]+=a[i]*(0.2*v[i]-u[i]);
  763. #endif
  764. // LTP(:,t+D+1)=0.95*LTP(:,t+D); % tau = 20 ms
  765. LTP[i][t+D+1]=0.95*LTP[i][t+D];
  766. // LTD=0.95*LTD; % tau = 20 ms
  767. LTD[i]*=0.95;
  768. }
  769. // end;
  770. }
  771. // frate(end+1)=sum(firings(:,2)<=Ne)/Ne;
  772. double frate=0;
  773. for (i=1;i<N_firings;i++)
  774. if ((firings[i][0] >=0) && (firings[i][1] <Ne)) frate++;
  775. frate = frate/Ne;
  776. // str(end+1) = sum(sum(s(find(post<=Ne)) > 6.3))/Ne;
  777. double str=0;
  778. for (i=0;i<Ne;i++)
  779. for (j=0;j<M;j++)
  780. if ((s[i][j] > 0.9*C_max) && (post[i][j] <Ne)) str++;
  781. str=100*str/Ne/M;
  782. // sec, [frate(end), str(end), sum(firings(:,2)>Ne)/Ni]
  783. double ifrate=0;
  784. for (i=1;i<N_firings;i++)
  785. if ((firings[i][0] >=0) && (firings[i][1] >=Ne)) ifrate++;
  786. ifrate = ifrate/Ni;
  787. cout << "sec=" << sec << ", exc. frate=" << frate << ", exc->exc str=" << str << ", inh. frate=" << ifrate << ".\n";
  788. fx = fopen("..//dat.dat","a");
  789. fprintf(fx, "%d %2.2f %2.2f %2.2f\n", sec, frate, str, ifrate);
  790. fclose(fx);
  791. // plot(firings(:,1),firings(:,2),'.');
  792. // axis([0 1000 0 N]); drawnow;
  793. #if(0) // --GT
  794. fs = fopen("..//spikest.dat","w");
  795. for (i=1;i<N_firings;i++)
  796. if (firings[i][0] >=0)
  797. fprintf(fs, "%d %d\n", sec*000+firings[i][0], firings[i][1]);
  798. fclose(fs);
  799. remove("..//spikes.dat");
  800. rename( "..//spikest.dat", "..//spikes.dat" );
  801. #endif
  802. #if(1) // ++GT (record spike times in same format as in the refactored version)
  803. FILE* pFile = fopen( "origImpl_firings.dat","a+" );
  804. // skip negative times
  805. int idx = 0;
  806. while( firings[idx][0] < 0 ) {
  807. idx++;
  808. }
  809. for( ; idx < N_firings; ++idx ) {
  810. fprintf( pFile, "%06d %03d %03d\n", sec, firings[idx][0], firings[idx][1]);
  811. }
  812. fclose(pFile);
  813. #endif
  814. // LTP(:,1:D+1)=LTP(:,1001:1001+D);
  815. for (i=0;i<N;i++)
  816. for (j=0;j<D+1;j++)
  817. LTP[i][j]=LTP[i][1000+j];
  818. // ind = find(1001-firings(:,1) < D);
  819. k=N_firings-1;
  820. while (1000-firings[k][0]<D) k--;
  821. // firings=[-D 0; firings(ind,1)-1000, firings(ind,2)];
  822. for (i=1;i<N_firings-k;i++)
  823. {
  824. firings[i][0]=firings[k+i][0]-1000;
  825. firings[i][1]=firings[k+i][1];
  826. }
  827. N_firings = N_firings-k;
  828. // sd=0.9*sd; % tau = 250 ms
  829. // s(1:Ne,:)=max(0,min(7, 0.01+s(1:Ne,:)+sd(1:Ne,:)));
  830. for (i=0;i<Ne;i++)
  831. for (j=0;j<M;j++)
  832. {
  833. sd[i][j]*=0.9;
  834. s[i][j]+=0.01+sd[i][j];
  835. if (s[i][j]>C_max) s[i][j]=C_max;
  836. if (s[i][j]<0) s[i][j]=0;
  837. }
  838. // if mod(sec,10)==0,
  839. // save all;
  840. // end;
  841. if ( (sec%100==0) & (sec > 0))
  842. {
  843. save_all("..//all.dat");
  844. fs = fopen("..//s.dat", "w");
  845. for (i=0; i<Ne; i++)
  846. for (j=0;j<M; j++)
  847. fprintf(fs, "%d %3.3f\n", post[i][j], s[i][j]);
  848. fclose(fs);
  849. }
  850. // end;
  851. }
  852. fpoly = fopen("..//polyall.dat","w");
  853. all_polychronous(); k=N_polychronous;
  854. fclose(fpoly);
  855. shuffle();
  856. all_polychronous();
  857. cout << "ratio (true/shuffled) = " << double(k)/(N_polychronous+1) << " ";
  858. }