SpaceQuester

Untitled

Nov 9th, 2019
395
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 28.45 KB | None | 0 0
  1. #define _CRT_SECURE_NO_WARNINGS
  2.  
  3. #define _USE_MATH_DEFINES
  4. #include "math.h"
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7. #include <locale.h>
  8. #include <time.h>
  9. #include <stdbool.h>
  10.  
  11. #define Node_count 150
  12.  
  13. #define Equations_per_node 8 // !!! Don't change !!!
  14. #define Equations_count Node_count * Equations_per_node
  15.  
  16. int MaxDeep = 3;
  17.  
  18. double f[Equations_count];
  19. double f_diff[Equations_count];
  20.  
  21. bool enable_I_syn_out = false;
  22.  
  23. double c_0 = 2; // uM
  24. double c_1 = 0.185;
  25. double v_1 = 6; // s^-1
  26. double v_2 = 0.11; // s^-1
  27. double v_3 = 2.2; // uM/s
  28. double v_4[Node_count]; // uM/s - Controling parameter // 0.5 //double v_4[Node_count]; // uM/s - Controling parameter //0.495
  29. double v_5 = 0.025; // uM/s
  30. double v_6 = 0.2; // uM/s
  31. double k_1 = 0.5; // s^-1
  32. double k_2 = 1; // uM
  33. double k_3 = 0.1;
  34. double k_4 = 1.1; // uM/s
  35. double a_2 = 0.14; // uM/s
  36. double d_1 = 0.13; // uM
  37. double d_2 = 1.049; // uM
  38. double d_3 = 0.9434; // uM
  39. double d_5 = 0.082; // uM
  40. double alpha = 0.8;
  41. double tau_IP3 = 7.143; // s
  42. double IP3_star = 0.16; // uM
  43. double d_Ca = 0.001; // 0.001
  44. double d_IP3 = 0.2; // 0.12
  45. double alpha_Glu = 2; // 2
  46. double g_astro = 3; // 3
  47.  
  48. // https://neuronaldynamics.epfl.ch/online/Ch2.S2.html
  49. double C_m = 1; // muF/cm^2
  50. double g_K = 35; // mS/cm^2
  51. double g_Na = 40; // mS/cm^2
  52. double g_L = 0.3; // mS/cm^2
  53. double E_K = -77; // mV
  54. double E_Na = 55; // mV
  55. double E_L = -65; // mV
  56.  
  57. double p_rewir;
  58. double p_inhib;
  59.  
  60. double I_app_min;
  61. double I_app_max;
  62.  
  63. double g_syn;// 0.18 // 0.04 // 0.2 // 1.6
  64. double k_syn = 0.2; // 0.2
  65. double E_syn[Node_count];
  66.  
  67. double alpha_G = 25; //s^-1
  68. double beta_G = 500; //s^-1
  69.  
  70. double I_app[Node_count];
  71.  
  72. double** A_A;
  73. double** B_A;
  74. double* C_A;
  75.  
  76. double** A_N;
  77. double** B_N;
  78. double* C_N;
  79.  
  80. FILE *fp_I_syn;
  81.  
  82. double tau[Node_count][Node_count];
  83.  
  84. #define tau_min 2 // ms
  85. #define tau_max 12 // ms
  86.  
  87. #define ms_to_step 40 // (0.001 / dt) !!! Don't forget !!!
  88.  
  89. #define Max_delay tau_max * ms_to_step
  90. double V_old_array[Node_count][Max_delay];
  91.  
  92. const double Freq = 500; // Hz
  93. const double Min_magintude = -0.13; // pA
  94. const double Max_magintude = 8.0; // pA
  95. const double Duration = 0.001; // sec
  96.  
  97. double Meander_start_from_zero[Node_count];
  98. double Meander_width[Node_count];
  99. double Meander_height[Node_count];
  100. double Meander_interval[Node_count];
  101. double last_meander_end[Node_count];
  102.  
  103. double I_stim(int i, double t)
  104. {
  105. if (t < Meander_start_from_zero[i])
  106. return 0;
  107.  
  108. t -= Meander_start_from_zero[i];
  109. t = fmod(t, Meander_width[i] + Meander_interval[i]);
  110.  
  111. return t < Meander_width[i] ? Meander_height[i] : 0;
  112. }
  113.  
  114. double Ca(int i)
  115. {
  116. return f[i * Equations_per_node];
  117. }
  118.  
  119. void SetCa(int i, double value)
  120. {
  121. f[i * Equations_per_node] = value;
  122. }
  123.  
  124. double IP3(int i)
  125. {
  126. return f[i * Equations_per_node + 1];
  127. }
  128.  
  129. void SetIP3(int i, double value)
  130. {
  131. f[i * Equations_per_node + 1] = value;
  132. }
  133.  
  134. double z(int i)
  135. {
  136. return f[i * Equations_per_node + 2];
  137. }
  138.  
  139. void Setz(int i, double value)
  140. {
  141. f[i * Equations_per_node + 2] = value;
  142. }
  143.  
  144. double G(int i)
  145. {
  146. return f[i * Equations_per_node + 3];
  147. }
  148.  
  149. void SetG(int i, double value)
  150. {
  151. f[i * Equations_per_node + 3] = value;
  152. }
  153.  
  154. double V(int i)
  155. {
  156. return f[i * Equations_per_node + 4];
  157. }
  158.  
  159. void SetV(int i, double value)
  160. {
  161. f[i * Equations_per_node + 4] = value;
  162. }
  163.  
  164. double m(int i)
  165. {
  166. return f[i * Equations_per_node + 5];
  167. }
  168.  
  169. void Setm(int i, double value)
  170. {
  171. f[i * Equations_per_node + 5] = value;
  172. }
  173.  
  174. double n(int i)
  175. {
  176. return f[i * Equations_per_node + 6];
  177. }
  178.  
  179. void Setn(int i, double value)
  180. {
  181. f[i * Equations_per_node + 6] = value;
  182. }
  183.  
  184. double h(int i)
  185. {
  186. return f[i * Equations_per_node + 7];
  187. }
  188.  
  189. void Seth(int i, double value)
  190. {
  191. f[i * Equations_per_node + 7] = value;
  192. }
  193.  
  194. double V_old(int i, int delay)
  195. {
  196. return V_old_array[i][Max_delay - 1 - delay];
  197. }
  198.  
  199. int RandomI(int min, int max)
  200. {
  201. return ((double)rand() / (RAND_MAX - 1)) * (max - min) + min;
  202. }
  203.  
  204. double RandomD(double min, double max)
  205. {
  206. return ((double)rand() / RAND_MAX) * (max - min) + min;
  207. }
  208.  
  209. double J_channel(double* f, int i)
  210. {
  211. return c_1 * v_1 * pow(IP3(i), 3) * pow(Ca(i), 3) * pow(z(i), 3) * (c_0 / c_1 - (1 + 1 / c_1) * Ca(i)) / pow((IP3(i) + d_1) * (Ca(i) + d_5), 3);
  212. }
  213.  
  214. double J_PLC(double* f, int i)
  215. {
  216. return v_4[i] * (Ca(i) + (1 - alpha) * k_4) / (Ca(i) + k_4);
  217. }
  218.  
  219. double J_leak(double* f, int i)
  220. {
  221. return c_1 * v_2 * (c_0 / c_1 - (1 + 1 / c_1) * Ca(i));
  222. }
  223.  
  224. double J_pump(double* f, int i)
  225. {
  226. return v_3 * pow(Ca(i), 2) / (pow(k_3, 2) + pow(Ca(i), 2));
  227. }
  228.  
  229. double J_in(double* f, int i)
  230. {
  231. return v_5 + v_6 * pow(IP3(i), 2) / (pow(k_2, 2) + pow(IP3(i), 2));
  232. }
  233.  
  234. double J_out(double* f, int i)
  235. {
  236. return k_1 * Ca(i);
  237. }
  238.  
  239. double J_Glu(double* f, int i)
  240. {
  241. if (E_syn[i] == 0)
  242. {
  243. /*printf("J_Glu = %f\n", alpha_Glu / (1 + exp(-(G(i) - 0.4) / 0.01)));*/
  244. return alpha_Glu / (1 + exp(-(G(i) - 0.25) / 0.01));
  245. }
  246.  
  247. return 0;
  248. //return alpha_Glu / (1 + exp(-(G(i) - 0.25) / 0.01));
  249. }
  250.  
  251. double alpha_m(double* f, int i)
  252. {
  253. return 0.182 * (V(i) + 35) / (1 - exp(-(V(i) + 35) / 9));
  254. }
  255.  
  256. double beta_m(double* f, int i)
  257. {
  258. return -0.124 * (V(i) + 35) / (1 - exp((V(i) + 35) / 9));
  259. }
  260.  
  261. double alpha_n(double* f, int i)
  262. {
  263. return 0.02 * (V(i) - 25) / (1 - exp(-(V(i) - 25) / 9));
  264. }
  265.  
  266. double beta_n(double* f, int i)
  267. {
  268. return -0.002 * (V(i) - 25) / (1 - exp((V(i) - 25) / 9));
  269. }
  270.  
  271. double alpha_h(double* f, int i)
  272. {
  273. return 0.25 * exp(-(V(i) + 90) / 12);
  274. }
  275.  
  276. double beta_h(double* f, int i)
  277. {
  278. return 0.25 * exp((V(i) + 62) / 6) / exp((V(i) + 90) / 12);
  279. }
  280.  
  281. double UllahJung_HodgkinHuxley(int i, double* f, double t)
  282. {
  283. int in = i / Equations_per_node;
  284. int il = i % Equations_per_node;
  285.  
  286. switch (il)
  287. {
  288. case 0: // Ca
  289. {
  290. double sum_1 = 0;
  291.  
  292. /*for (int j = 0; j < Node_count; j++)
  293. {
  294. sum_1 += d_Ca * (Ca(j) - Ca(in));
  295. }*/
  296.  
  297. for (int j = 0; j < C_A[in]; j++)
  298. {
  299. sum_1 += d_Ca * (Ca((int)B_A[in][j]) - Ca(in));
  300. }
  301.  
  302. return J_channel(f, in) - J_pump(f, in) + J_leak(f, in) + J_in(f, in) - J_out(f, in) + sum_1;
  303. }
  304.  
  305. case 1: // IP3
  306. {
  307. double sum_2 = 0;
  308.  
  309. /*for (int j = 0; j < Node_count; j++)
  310. {
  311. sum_2 += d_IP3 * (IP3(j) - IP3(in));
  312. }*/
  313.  
  314. for (int j = 0; j < C_A[in]; j++)
  315. {
  316. sum_2 += d_IP3 * (IP3((int)B_A[in][j]) - IP3(in));
  317. }
  318.  
  319. return (IP3_star - IP3(in)) / tau_IP3 + J_PLC(f, in) + sum_2 + J_Glu(f, in);
  320. }
  321.  
  322. case 2: // z
  323. {
  324. return a_2 * (d_2 * (IP3(in) + d_1) / (IP3(in) + d_3) * (1 - z(in)) - Ca(in) * z(in));
  325. }
  326.  
  327. case 3: // G
  328. {
  329. return -alpha_G * G(in) + beta_G * (1 / (1 + exp(-V(in) / 0.5)));
  330. }
  331.  
  332. case 4: // V
  333. {
  334. double I_syn = 0;
  335.  
  336. /*for (int j = 0; j < Node_count; j++)
  337. {
  338. //sum += A[in][j] * g_syn * (V(in) - V_old(j, tau[in][j]));
  339. //sum += A[in][j] * g_syn * (V(j) - V(in));
  340. //sum += A[in][j] * g_syn * (V(in) - E_syn[in]) / (1 + exp(-V_old(j, tau[in][j]) / k_syn));
  341. //sum += 1 / (0.2 * Node_count_half) * A[in][j] * g_syn * (V(in) - E_syn[in]) / (1 + exp(-V(j) / k_syn)); // i up, j down
  342. //sum += 1 / (0.2 * Node_count_half) * A[in][j] * g_syn * (V(j) - E_syn[j]) / (1 + exp(-V(in) / k_syn)); // j up, i down
  343. I_syn += A_N[in][j] * g_syn * (E_syn[in] - V(in)) / (1 + exp(-(V(j) / k_syn)));
  344. //printf("in = %d\t Node_count = %d\t A[in][j] = %f\t V(in) = %f\t E_syn[in] = %f\t sum = %f\n", in, j, A[in][j], V(in), E_syn[in], sum);
  345. }*/
  346.  
  347. /*for (int j = 0; j < C[in]; j++)
  348. {
  349. sum += sigma[in][(int)B[in][j]] * (V((int)B[in][j]) - V(in));
  350. }*/
  351.  
  352. for (int j = 0; j < C_N[in]; j++)
  353. {
  354. if (Ca(in) >= 0.3)
  355. {
  356. I_syn += g_syn * (1 + g_astro * Ca(in)) * (E_syn[(int)B_N[in][j]] - V(in)) / (1 + exp(-(V((int)B_N[in][j]) / k_syn))); // версия с V (без V_old)
  357. }
  358. //I_syn += g_syn * (1 + g_astro * Ca(in)) * (E_syn[in] - V(in)) / (1 + exp(-(V_old((int)B_N[in][j], tau[in][(int)B_N[in][j]]) / k_syn)); // версия с V_old
  359. //I_syn += g_syn * (1 + g_astro * Ca(in)) * (E_syn[in] - V(in)) / (1 + exp(-(V(j) / k_syn))); // версия без с V (без V_old)
  360. //I_syn += g_syn * (E_syn[in] - V(in)) / (1 + exp(-(V(j) / k_syn))); // версия без с V (без V_old), упрощенная версия
  361. // sum_3 += g_syn * (1 + g_astro * Ca(in)) * (E_syn[i] - V(i)) / (1 + exp(-(V(j) / k_syn))); // образец из старой версии
  362. else
  363. {
  364. I_syn += g_syn * (E_syn[(int)B_N[in][j]] - V(in)) / (1 + exp(-(V((int)B_N[in][j]) / k_syn))); // версия с V (без V_old)
  365. }
  366. //I_syn += g_syn * (E_syn[in] - V(in)) / (1 + exp(-(V_old((int)B_N[in][j], tau[in][(int)B_N[in][j]])) / k_syn));*/
  367. //I_syn += g_syn * (E_syn[(int)B_N[in][j]] - V(in)) / (1 + exp(-(V(j) / k_syn))); // версия с V (без V_old)
  368. //I_syn += g_syn * (E_syn[(int)B_N[in][j]] - V(in)) / (1 + exp(-(V((int)B_N[in][j]) / k_syn))); // версия с V (без V_old), упрощенная версия !!!
  369. //I_syn += g_syn * (E_syn[(int)B_N[in][j]] - V(in)) / (1 + exp(-(V_old((int)B_N[in][j], tau[in][(int)B_N[in][j]]) / k_syn))); // версия с V (без V_old), упрощенная версия !!!
  370. //sum += g_syn * (V((int)B[in][j]) - V(in)); // устаревшая часть, нужна для проверки разностной схемы
  371. //sum += A[in][j] * g_syn * (V(in) - E_syn[in]) / (1 + exp(-V_old((int)B[in][j]) / k_syn)); // устаревшая часть
  372. //sum += A[in][(int)B[in][j]] * g_syn * (V(in) - E_syn[in]) / (1 + exp(-V_old((int)B[in][j], tau[in][(int)B[in][j]]) / k_syn));
  373. //sum += A[in][(int)B[in][j]] * g_syn * (V((int)B[in][j]) - E_syn[(int)B[in][j]]) / (1 + exp(-V_old(in, tau[in][(int)B[in][j]]) / k_syn));
  374. //sum += 1 / (0.2 * Node_count_half) * A[in][(int)B[in][j]] * g_syn * (V((int)B[in][j]) - E_syn[(int)B[in][j]]) / (1 + exp(-V(in) / k_syn)); // j up, i down
  375. //sum += 1 / (0.2 * Node_count) * /*(int)A_N[in][(int)B_N[in][j]] * */ g_syn * (1 + g_astro * Ca(in)) * (V(in) - E_syn[in]) / (1 + exp(-V((int)B_N[in][j]) / k_syn)); // i up, j down
  376. // i up, j down
  377. /*printf("i = %d\t j = %d\t A[i, j] = %d\n", in, (int)B_N[in][j], (int)A_N[in][(int)B_N[in][j]]);*/
  378. /*printf("i = %d\t V_old = %f\t exp = %f\n", in, Vold, ee);*/
  379. }
  380. /*printf("i = %d\t sum = %f\n", in, sum);*/
  381.  
  382. if (enable_I_syn_out)
  383. fprintf(fp_I_syn, i == Equations_count - 1 ? "%f" : "%f\t", I_syn);
  384.  
  385. return 1000 * ((g_Na * pow(m(in), 3) * h(in) * (E_Na - V(in)) + g_K * n(in) * (E_K - V(in)) + g_L * (E_L - V(in)) + I_app[in] /*+ I_stim(35, t)*/ + I_syn) / C_m); // V
  386. }
  387.  
  388. case 5: // m
  389. {
  390. return 1000 * (alpha_m(f, in) * (1 - m(in)) - beta_m(f, in) * m(in)); // m
  391. }
  392.  
  393. case 6: // n
  394. {
  395. return 1000 * (alpha_n(f, in) * (1 - n(in)) - beta_n(f, in) * n(in)); // n
  396. }
  397.  
  398. case 7: // h
  399. {
  400. return 1000 * (alpha_h(f, in) * (1 - h(in)) - beta_h(f, in) * h(in)); // h
  401. }
  402. }
  403.  
  404. return 0;
  405. }
  406.  
  407. void RungeKutta(double t, double dt, double* f, double* f_next)
  408. {
  409. double k[Equations_count][4];
  410.  
  411. // k1
  412. for (int i = 0; i < Equations_count; i++)
  413. k[i][0] = UllahJung_HodgkinHuxley(i, f, t) * dt;
  414.  
  415. double phi_k1[Equations_count];
  416. for (int i = 0; i < Equations_count; i++)
  417. phi_k1[i] = f[i] + k[i][0] / 2;
  418.  
  419. // k2
  420. for (int i = 0; i < Equations_count; i++)
  421. k[i][1] = UllahJung_HodgkinHuxley(i, phi_k1, t) * dt;
  422.  
  423. double phi_k2[Equations_count];
  424. for (int i = 0; i < Equations_count; i++)
  425. phi_k2[i] = f[i] + k[i][1] / 2;
  426.  
  427. // k3
  428. for (int i = 0; i < Equations_count; i++)
  429. k[i][2] = UllahJung_HodgkinHuxley(i, phi_k2, t) * dt;
  430.  
  431. double phi_k3[Equations_count];
  432. for (int i = 0; i < Equations_count; i++)
  433. phi_k3[i] = f[i] + k[i][2] / 2;
  434.  
  435. enable_I_syn_out = true;
  436. // k4
  437. for (int i = 0; i < Equations_count; i++)
  438. k[i][3] = UllahJung_HodgkinHuxley(i, phi_k3, t) * dt;
  439. enable_I_syn_out = false;
  440.  
  441. for (int i = 0; i < Equations_count; i++)
  442. f_next[i] = f[i] + (k[i][0] + 2 * k[i][1] + 2 * k[i][2] + k[i][3]) / 6;
  443. }
  444.  
  445. void CopyArray(double* source, double* target, int N)
  446. {
  447. for (int i = 0; i < N; i++)
  448. target[i] = source[i];
  449. }
  450.  
  451. bool Approximately(double a, double b)
  452. {
  453. if (a < 0)
  454. a = -a;
  455.  
  456. if (b < 0)
  457. b = -b;
  458.  
  459. return a - b <= 0.000001;
  460. }
  461.  
  462. //bool CheckSameLine(int i, int j)
  463. //{
  464. // return i / Node_wire_width == j / Node_wire_width;
  465. //}
  466. //
  467. //bool IsWireNeighbors(int i, int j)
  468. //{
  469. // if (CheckSameLine(i, j) && (i == j - 1 || i == j + 1))
  470. // return true;
  471. //
  472. // if (i == j - Node_wire_width || i == j + Node_wire_width)
  473. // return true;
  474. //
  475. // return false;
  476. //}
  477.  
  478. // http://preshing.com/20111007/how-to-generate-random-timings-for-a-poisson-process/
  479. double nextTime(double rateParameter)
  480. {
  481. return -log(1.0 - (double)rand() / (RAND_MAX)) / rateParameter;
  482. }
  483.  
  484. void GenerateRandomMeander(int i, double min_start_time)
  485. {
  486. double offset = nextTime(Freq);
  487.  
  488. if (offset < 0)
  489. {
  490. int a = 0;
  491. }
  492.  
  493. Meander_start_from_zero[i] = min_start_time + offset;
  494. Meander_width[i] = Duration;
  495. Meander_height[i] = RandomD(Min_magintude, Max_magintude);
  496. }
  497.  
  498. void FillAMatrixZero()
  499. {
  500. for (int i = 0; i < Node_count; i++)
  501. {
  502. for (int j = 0; j < Node_count; j++)
  503. {
  504. A_A[i][j] = 0;
  505. A_N[i][j] = 0;
  506. }
  507. }
  508. }
  509.  
  510. void FillAstrociteMatrix()
  511. {
  512. for (int i = 0; i < Node_count; i++)
  513. {
  514. for (int j = 0; j < Node_count; j++)
  515. {
  516. if (i == j)
  517. {
  518. A_A[i][j] = 0;
  519. continue;
  520. }
  521.  
  522. if (i > j)
  523. {
  524. A_A[i][j] = A_A[j][i];
  525. continue;
  526. }
  527.  
  528. if (i == 0 && j == Node_count - 1)
  529. {
  530. A_A[i][j] = 1;
  531. continue;
  532. }
  533.  
  534. if (i == Node_count - 1 && j == 0)
  535. {
  536. A_A[i][j] = 1;
  537. continue;
  538. }
  539.  
  540. if (i == j - 1 || i == j + 1)
  541. {
  542. A_A[i][j] = 1;
  543. continue;
  544. }
  545. }
  546. }
  547. //A_A[0][1] = 0; // only for debug. diffusion Ca test
  548. //A_A[1][0] = 0; // only for debug. diffusion Ca test
  549. //A_A[1][3] = 0;
  550. //A_A[3][1] = 0;
  551. //A_A[0][2] = 0;
  552. //A_A[2][0] = 0;
  553. }
  554.  
  555. void FillBCMatrix_A()
  556. {
  557. for (int i = 0; i < Node_count; i++)
  558. {
  559. int bIndex = 0;
  560. C_A[i] = 0;
  561. for (int j = 0; j < Node_count; j++)
  562. {
  563. if (A_A[i][j] == 1)
  564. {
  565. B_A[i][bIndex] = j;
  566. bIndex++;
  567. C_A[i]++;
  568. }
  569. }
  570. }
  571. }
  572.  
  573. void FillBCMatrix_N()
  574. {
  575. for (int i = 0; i < Node_count; i++)
  576. {
  577. int bIndex = 0;
  578. C_N[i] = 0;
  579. for (int j = 0; j < Node_count; j++)
  580. {
  581. if (A_N[i][j] == 1)
  582. {
  583. B_N[i][bIndex] = j;
  584. bIndex++;
  585. C_N[i]++;
  586. }
  587. }
  588. }
  589. }
  590.  
  591. bool IsWireNeighbors(int i, int j, int deep)
  592. {
  593. int j_border_left = j - deep < 0 ? j + Node_count : j;
  594. int j_border_right = j + deep >= Node_count ? j - Node_count : j;
  595.  
  596. if (i == j_border_left - deep || i == j_border_right + deep)
  597. {
  598. return true;
  599. }
  600.  
  601. return false;
  602. }
  603.  
  604. void FillNeuronMatrix()
  605. {
  606. for (int i = 0; i < Node_count; i++)
  607. {
  608. for (int j = 0; j < Node_count; j++)
  609. {
  610. if (i == j)
  611. {
  612. A_N[i][j] = 0;
  613. continue;
  614. }
  615.  
  616. if (i > j)
  617. {
  618. A_N[i][j] = A_N[j][i];
  619. continue;
  620. }
  621.  
  622. for (int deep = 1; deep <= MaxDeep; deep++)
  623. {
  624. if (IsWireNeighbors(i, j, deep))
  625. A_N[i][j] = 1;
  626. }
  627. }
  628. }
  629. }
  630.  
  631. void RandomizeNeuronMatrix()
  632. {
  633. srand(time(NULL));
  634.  
  635. for (int i = 0; i < Node_count; i++)
  636. {
  637. //if (i == Node_count / 2)
  638. // srand(time(NULL));
  639.  
  640. for (int link = 0; link < MaxDeep * 2; link++)
  641. {
  642. double x = RandomD(0, 1);
  643.  
  644. if (x > p_rewir)
  645. continue;
  646.  
  647. int rndJ;
  648.  
  649. do
  650. {
  651. rndJ = RandomI(0, Node_count);
  652. } while (i == rndJ || A_N[i][rndJ] == 1);
  653.  
  654. int rndJ_last;
  655.  
  656. do
  657. {
  658. rndJ_last = RandomI(i - MaxDeep - 1, i + MaxDeep + 1);
  659.  
  660. if (rndJ_last < 0)
  661. rndJ_last += Node_count;
  662. else if (rndJ_last >= Node_count)
  663. rndJ_last -= Node_count;
  664.  
  665. } while (i == rndJ_last || A_N[i][rndJ_last] == 0);
  666.  
  667. A_N[i][rndJ_last] = 0;
  668.  
  669. A_N[i][rndJ] = 1;
  670. }
  671. }
  672. }
  673.  
  674. void FillVOldFromCurrent()
  675. {
  676. for (int i = 0; i < Node_count; i++)
  677. for (int j = 0; j < Max_delay; j++)
  678. V_old_array[i][j] = V(i);
  679. }
  680.  
  681. void UpdateVOld()
  682. {
  683. for (int i = 0; i < Node_count; i++)
  684. {
  685. for (int j = 1; j < Max_delay; j++)
  686. V_old_array[i][j - 1] = V_old_array[i][j];
  687.  
  688. V_old_array[i][Max_delay - 1] = V(i);
  689. }
  690. }
  691.  
  692. //void FillFullTauMatrix()
  693. //{
  694. // for (int i = 0; i < Node_count; i++)
  695. // {
  696. // for (int j = 0; j < Node_count; j++)
  697. // {
  698. // if (i < Node_count || j < Node_count)
  699. // {
  700. // tau[i][j] = 0;
  701. // continue;
  702. // }
  703. //
  704. // int i_neuron = i - Node_count;
  705. // int j_neuron = j - Node_count;
  706. //
  707. // int i_wire_x = i_neuron / Node_wire_width;
  708. // int i_wire_y = i_neuron % Node_wire_width;
  709. //
  710. // int j_wire_x = j_neuron / Node_wire_width;
  711. // int j_wire_y = j_neuron % Node_wire_width;
  712. //
  713. // double distance_max = sqrt(2.) * (Node_wire_width - 1);
  714. // double distance = sqrt((i_wire_x - j_wire_x) * (i_wire_x - j_wire_x) + (i_wire_y - j_wire_y) * (i_wire_y - j_wire_y));
  715. //
  716. // tau[i][j] = (tau_min + distance / (distance_max) * (tau_max - tau_min)) * ms_to_step;
  717. // }
  718. // }
  719. //}
  720. //
  721. //void FillTauMatrix()
  722. //{
  723. // for (int i = 0; i < Node_count; i++)
  724. // {
  725. // for (int j = 0; j < Node_count; j++)
  726. // {
  727. // if (i == j || A_N[i][j] == 0)
  728. // {
  729. // tau[i][j] = 0;
  730. // continue;
  731. // }
  732. //
  733. // int i_neuron = i;
  734. // int j_neuron = j;
  735. //
  736. // int i_wire_x = i_neuron / Node_wire_width;
  737. // int i_wire_y = i_neuron % Node_wire_width;
  738. //
  739. // int j_wire_x = j_neuron / Node_wire_width;
  740. // int j_wire_y = j_neuron % Node_wire_width;
  741. //
  742. // double distance_max = sqrt(2.) * (Node_wire_width - 1);
  743. // double distance = sqrt((i_wire_x - j_wire_x) * (i_wire_x - j_wire_x) + (i_wire_y - j_wire_y) * (i_wire_y - j_wire_y));
  744. //
  745. // double t = (distance - 1) / (distance_max - 1);
  746. // tau[i][j] = (tau_min + t * (tau_max - tau_min)) * ms_to_step;
  747. // }
  748. // }
  749. //}
  750.  
  751. int main(int argc, char *argv[])
  752. {
  753. sscanf(argv[1], "%lf", &p_rewir);
  754. FILE *fp_p_rewir;
  755. fp_p_rewir = fopen("p_rewir.txt", "w");
  756. fprintf(fp_p_rewir, "%f\t", p_rewir);
  757. fclose(fp_p_rewir);
  758. printf("p_rewir = %f\n", p_rewir);
  759.  
  760. sscanf(argv[2], "%lf", &p_inhib);
  761. FILE *fp_p_inhib;
  762. fp_p_inhib = fopen("p_inhib.txt", "w");
  763. fprintf(fp_p_inhib, "%f\t", p_inhib);
  764. fclose(fp_p_inhib);
  765. printf("p_inhib = %f\n", p_inhib);
  766.  
  767. sscanf(argv[3], "%lf", &g_syn);
  768. FILE *fp_g_syn;
  769. fp_g_syn = fopen("g_syn.txt", "w");
  770. fprintf(fp_g_syn, "%f\t", g_syn);
  771. fclose(fp_g_syn);
  772.  
  773. double g_syn_real;
  774. g_syn_real = /*1 / (0.2 * Node_count) */ g_syn;
  775. printf("g_syn_real = %f\n", g_syn_real);
  776.  
  777. sscanf(argv[4], "%lf", &I_app_min);
  778. sscanf(argv[5], "%lf", &I_app_max);
  779.  
  780. FILE *fp0;
  781. FILE *fp_I_stim;
  782. FILE *fp_Ca;
  783. FILE *fp_IP3;
  784. //FILE *fp_z;
  785. FILE *fp_G;
  786. FILE *fp_V;
  787. //FILE *fp_m;
  788. //FILE *fp_n;
  789. //FILE *fp_h;
  790. //FILE *fp_V_spikes;
  791.  
  792. FILE *fp_Esyn;
  793. srand(time(NULL));
  794.  
  795. //for (int i = 0; i < Node_count; i++)
  796. // V_old_length[i] = 0;
  797.  
  798. A_A = malloc(Node_count * sizeof(double));
  799. for (int i = 0; i < Node_count; i++)
  800. A_A[i] = malloc(Node_count * sizeof(double));
  801.  
  802. B_A = malloc(Node_count * sizeof(double));
  803. for (int i = 0; i < Node_count; i++)
  804. B_A[i] = malloc(Node_count * sizeof(double));
  805.  
  806. C_A = malloc(Node_count * sizeof(double));
  807.  
  808. A_N = malloc(Node_count * sizeof(double));
  809. for (int i = 0; i < Node_count; i++)
  810. A_N[i] = malloc(Node_count * sizeof(double));
  811.  
  812. B_N = malloc(Node_count * sizeof(double));
  813. for (int i = 0; i < Node_count; i++)
  814. B_N[i] = malloc(Node_count * sizeof(double));
  815.  
  816. C_N = malloc(Node_count * sizeof(double));
  817.  
  818. FillAMatrixZero();
  819. FillAstrociteMatrix();
  820. FillNeuronMatrix();
  821. RandomizeNeuronMatrix();
  822. FillBCMatrix_A();
  823. FillBCMatrix_N();
  824. //FillTauMatrix();
  825.  
  826. fp0 = fopen("A_A.txt", "w+");
  827. for (int i = 0; i < Node_count; i++)
  828. {
  829. for (int j = 0; j < Node_count; j++)
  830. {
  831. fprintf(fp0, "%d\t", (int)A_A[i][j]);
  832. }
  833. fprintf(fp0, "\n");
  834. }
  835. fclose(fp0);
  836.  
  837. fp0 = fopen("A_N.txt", "w+");
  838. for (int i = 0; i < Node_count; i++)
  839. {
  840. for (int j = 0; j < Node_count; j++)
  841. {
  842. fprintf(fp0, "%d\t", (int)A_N[i][j]);
  843. }
  844. fprintf(fp0, "\n");
  845. }
  846. fclose(fp0);
  847.  
  848. fp0 = fopen("tau.txt", "w+");
  849. for (int i = 0; i < Node_count; i++)
  850. {
  851. for (int j = 0; j < Node_count; j++)
  852. {
  853. fprintf(fp0, "%f\t", tau[i][j] / ms_to_step);
  854. }
  855. fprintf(fp0, "\n");
  856. }
  857. fclose(fp0);
  858.  
  859. //Пишем в файл число связей у каждого нейрона
  860. fp0 = fopen("links.txt", "w+");
  861. for (int i = 0; i < Node_count; i++)
  862. {
  863. int links_count = 0;
  864. for (int j = 0; j < Node_count; j++)
  865. {
  866. if (A_N[i][j] == 1)
  867. {
  868. links_count++;
  869. }
  870. }
  871. fprintf(fp0, "%d\n", (int)links_count);
  872. }
  873. fclose(fp0);
  874.  
  875. //setlocale(LC_NUMERIC, "French_Canada.1252");
  876. fp0 = fopen("test_Poisson.txt", "w+");
  877. for (int i = 0; i < 1000; i++)
  878. fprintf(fp0, "%f\n", nextTime(Freq));
  879. fclose(fp0);
  880.  
  881. fp0 = fopen("B_A.txt", "w+");
  882. for (int i = 0; i < Node_count; i++)
  883. {
  884. for (int j = 0; j < C_A[i]; j++)
  885. {
  886. fprintf(fp0, "%d\t", (int)B_A[i][j]);
  887. }
  888. fprintf(fp0, "\n");
  889. }
  890. fclose(fp0);
  891.  
  892. fp0 = fopen("B_N.txt", "w+");
  893. for (int i = 0; i < Node_count; i++)
  894. {
  895. for (int j = 0; j < C_N[i]; j++)
  896. {
  897. fprintf(fp0, "%d\t", (int)B_N[i][j]);
  898. }
  899. fprintf(fp0, "\n");
  900. }
  901. fclose(fp0);
  902.  
  903. fp0 = fopen("C_A.txt", "w+");
  904. for (int i = 0; i < Node_count; i++)
  905. {
  906. fprintf(fp0, "%d\n", (int)C_A[i]);
  907. }
  908. fclose(fp0);
  909.  
  910. fp0 = fopen("C_N.txt", "w+");
  911. for (int i = 0; i < Node_count; i++)
  912. {
  913. fprintf(fp0, "%d\n", (int)C_N[i]);
  914. }
  915. fclose(fp0);
  916.  
  917. /*for (int i = 0; i < 6; i++)
  918. {
  919. v_4[i] = 0.6;
  920. }*/
  921. for (int i = 0; i < Node_count; i++)
  922. {
  923. v_4[i] = 0.4; // 0.4
  924. }
  925.  
  926. // Initial values
  927. /*for (int i = 0; i < Equations_count; i++)
  928. {
  929. f[i] = 0;
  930. }*/
  931.  
  932. FILE *fp_I_app;
  933. fp_I_app = fopen("I_app.txt", "w");
  934. for (int i = 0; i < Node_count; i++)
  935. {
  936. I_app[i] = RandomD(I_app_min, I_app_max);
  937. fprintf(fp_I_app, "%f\n", I_app[i]);
  938. }
  939. fclose(fp_I_app);
  940.  
  941. for (int i = 0; i < Node_count; i++) // init array for all nodes
  942. {
  943. SetG(i, 0); // G
  944. }
  945.  
  946. double percent_stable_state = 0.4; // 0.40
  947. double eps_persent = 0.05; //0.05
  948.  
  949. double Ca0 = 0.07;
  950. double IP30 = 0.16;
  951. double z0 = 0.67;
  952.  
  953. // Initial values at t = 0
  954. /*for (int i = 0; i < Node_count; i++)
  955. {
  956. SetCa(i, Ca0); // Ca
  957. SetIP3(i, IP30); // IP3
  958. Setz(i, z0); // z
  959. }*/
  960. for (int i = 0; i < Node_count; i++)
  961. {
  962. /*SetCa(i, Ca0 + RandomD(-Ca0 * eps_persent, Ca0 * eps_persent)); // Ca
  963. SetIP3(i, IP30 + RandomD(-IP30 * eps_persent, IP30 * eps_persent)); // IP3
  964. Setz(i, z0 + RandomD(-z0 * eps_persent, z0 * eps_persent)); // z */
  965. SetCa(i, Ca0); // Ca
  966. SetIP3(i, IP30); // IP3
  967. Setz(i, z0); // z
  968. }
  969.  
  970. /*for (int i = 0; i < Node_count; i++) // init array for all nodes
  971. {
  972. SetV(i, V1); // V
  973. Setm(i, m1); // m
  974. Setn(i, n1); // n
  975. Seth(i, h1); // h
  976. }*/
  977.  
  978. double V0 = -58.7085;
  979. double m0 = 0.0953;
  980. double n0 = 0.000913;
  981. double h0 = 0.3662;
  982.  
  983. double V1 = 14.8409;
  984. double m1 = 0.9174;
  985. double n1 = 0.0140;
  986. double h1 = 0.0539;
  987.  
  988. /*for (int i = 0; i < Node_count; i++) // init only for neurons
  989. {
  990. double random = RandomD(0, 1);
  991.  
  992. SetV(i, random < percent_stable_state ? V0 + RandomD(-V0 * eps_persent, V0 * eps_persent) : V1 + RandomD(-V1 * eps_persent, V1 * eps_persent)); // V
  993. Setm(i, random < percent_stable_state ? m0 + RandomD(-m0 * eps_persent, m0 * eps_persent) : m1 + RandomD(-m1 * eps_persent, m1 * eps_persent)); // m
  994. Setn(i, random < percent_stable_state ? n0 + RandomD(-n0 * eps_persent, n0 * eps_persent) : n1 + RandomD(-n1 * eps_persent, n1 * eps_persent)); // n
  995. Seth(i, random < percent_stable_state ? h0 + RandomD(-h0 * eps_persent, h0 * eps_persent) : h1 + RandomD(-h1 * eps_persent, h1 * eps_persent)); // h
  996. }*/
  997.  
  998. for (int i = 0; i < Node_count; i++) // init only for neurons
  999. {
  1000. /*SetV(i, RandomD(-80, 20)); // V
  1001. Setm(i, RandomD(0, 1)); // m
  1002. Setn(i, RandomD(0, 1)); // n
  1003. Seth(i, RandomD(0, 1)); // h*/
  1004. SetV(i, V0); // V
  1005. Setm(i, m0); // m
  1006. Setn(i, n0); // n
  1007. Seth(i, h0); // h
  1008. }
  1009.  
  1010. double E_syn0 = 0; // Excitatory neuron
  1011. double E_syn1 = -90; // Inhibitory neuron
  1012.  
  1013. fp_Esyn = fopen("results_E_syn.txt", "w+");
  1014. for (int i = 0; i < Node_count; i++)
  1015. {
  1016. E_syn[i] = E_syn0;
  1017.  
  1018. double x = RandomD(0, 1);
  1019.  
  1020. if (x > p_inhib)
  1021. {
  1022. fprintf(fp_Esyn, "%f\n", E_syn[i]);
  1023. continue;
  1024. }
  1025.  
  1026. E_syn[i] = E_syn1;
  1027.  
  1028. fprintf(fp_Esyn, "%f\n", E_syn[i]);
  1029. }
  1030. fclose(fp_Esyn);
  1031.  
  1032. for (int i = 0; i < Node_count; i++)
  1033. {
  1034. GenerateRandomMeander(i, 0);
  1035. last_meander_end[i] = Meander_start_from_zero[i] + Duration;
  1036. }
  1037.  
  1038. const double t_start = 0;
  1039. const double t_max = 40.0; // 100 msec = 0.1 sec // 240 // 270
  1040. const double dt = 0.00005; // 0.01 msec = 0.00001 sec; 0.1 msec = 0.0001 sec; 1 msec = 0.001 sec // 0.000025
  1041.  
  1042. double t = t_start;
  1043.  
  1044. //fp0 = fopen("results.txt", "w+");
  1045. //setlocale(LC_NUMERIC, "French_Canada.1252");
  1046.  
  1047. clock_t start_rk4, end_rk4;
  1048. start_rk4 = clock();
  1049. int lastPercent = -1;
  1050.  
  1051. FillVOldFromCurrent();
  1052.  
  1053. fp_I_stim = fopen("results_I_stim.txt", "w+");
  1054. fp_I_syn = fopen("results_I_syn.txt", "w+");
  1055. fp_Ca = fopen("results_Ca.txt", "w+");
  1056. fp_IP3 = fopen("results_IP3.txt", "w+");
  1057. //fp_z = fopen("results_z.txt", "w+");
  1058. fp_G = fopen("results_G.txt", "w+");
  1059. fp_V = fopen("results_V.txt", "w+");
  1060. //fp_m = fopen("results_m.txt", "w+");
  1061. //fp_n = fopen("results_n.txt", "w+");
  1062. //fp_h = fopen("results_h.txt", "w+");
  1063. //fp_V_spikes = fopen("results_V_spikes.txt", "w+");
  1064.  
  1065. while (t < t_max || Approximately(t, t_max))
  1066. {
  1067. fprintf(fp_I_stim, "%f\t", t);
  1068. fprintf(fp_Ca, "%f\t", t);
  1069. fprintf(fp_IP3, "%f\t", t);
  1070. //fprintf(fp_z, "%f\t", t);
  1071. fprintf(fp_G, "%f\t", t);
  1072. fprintf(fp_V, "%f\t", t);
  1073. //fprintf(fp_m, "%f\t", t);
  1074. //fprintf(fp_n, "%f\t", t);
  1075. //fprintf(fp_h, "%f\t", t);
  1076. //fprintf(fp_V_spikes, "%f\t", t);
  1077.  
  1078. for (int i = 0; i < Node_count; i++)
  1079. {
  1080. if (t > last_meander_end[i])
  1081. {
  1082. GenerateRandomMeander(i, t);
  1083. last_meander_end[i] = Meander_start_from_zero[i] + Duration;
  1084. }
  1085.  
  1086. fprintf(fp_I_stim, "%f\t", I_stim(i, t));
  1087. }
  1088. fprintf(fp_I_stim, "\n");
  1089.  
  1090. for (int i = 0; i < Equations_count; i += Equations_per_node)
  1091. fprintf(fp_Ca, i == Equations_count - 1 ? "%f" : "%f\t", f[i]); // Ca
  1092.  
  1093. for (int i = 1; i < Equations_count; i += Equations_per_node)
  1094. fprintf(fp_IP3, i == Equations_count - 1 ? "%f" : "%f\t", f[i]); // IP3
  1095.  
  1096. //for (int i = 2; i < Equations_count; i += Equations_per_node)
  1097. // fprintf(fp_z, i == Equations_count - 1 ? "%f" : "%f\t", f[i]); // z
  1098.  
  1099. for (int i = 3; i < Equations_count; i += Equations_per_node)
  1100. fprintf(fp_G, i == Equations_count - 1 ? "%f" : "%f\t", f[i]); // G
  1101.  
  1102. for (int i = 4; i < Equations_count; i += Equations_per_node)
  1103. fprintf(fp_V, i == Equations_count - 1 ? "%f" : "%f\t", f[i]); // V
  1104.  
  1105. //for (int i = 5; i < Equations_count; i += Equations_per_node)
  1106. // fprintf(fp_m, i == Equations_count - 1 ? "%f" : "%f\t", f[i]); // m
  1107.  
  1108. //for (int i = 6; i < Equations_count; i += Equations_per_node)
  1109. // fprintf(fp_n, i == Equations_count - 1 ? "%f" : "%f\t", f[i]); // n
  1110.  
  1111. //for (int i = 7; i < Equations_count; i += Equations_per_node)
  1112. // fprintf(fp_h, i == Equations_count - 1 ? "%f" : "%f\t", f[i]); // h
  1113.  
  1114. fprintf(fp_Ca, "\n");
  1115. fprintf(fp_IP3, "\n");
  1116. //fprintf(fp_z, "\n");
  1117. fprintf(fp_G, "\n");
  1118. fprintf(fp_V, "\n");
  1119. //fprintf(fp_m, "\n");
  1120. //fprintf(fp_n, "\n");
  1121. //fprintf(fp_h, "\n");
  1122.  
  1123.  
  1124. double f_next[Equations_count];
  1125.  
  1126. RungeKutta(t, dt, f, f_next);
  1127.  
  1128. /*for (int i = 0; i < Equations_count; i += Equations_per_node)
  1129. {
  1130. double diff = f_next[i] - f[i];
  1131.  
  1132. fprintf(fp_V_spikes, i == Equations_count - 1 ? "%d" : "%d\t", diff < 0 && f_diff[i] > 0 && f[i] > -10 ? 1 : 0);
  1133.  
  1134. f_diff[i] = diff;
  1135. }*/
  1136.  
  1137. //fprintf(fp_V_spikes, "\n");
  1138.  
  1139. CopyArray(f_next, f, Equations_count);
  1140.  
  1141. t += dt;
  1142.  
  1143. int percent = (int)(100 * (t - t_start) / (t_max - t_start));
  1144. if (percent != lastPercent)
  1145. {
  1146. printf("Progress: %d%%\n", percent);
  1147. lastPercent = percent;
  1148. }
  1149.  
  1150. //printf("V(24) = %f\t V_old(24) = %f\n", f[24*4], V_old(24));
  1151. UpdateVOld();
  1152.  
  1153. fprintf(fp_I_syn, "\n");
  1154. }
  1155.  
  1156. fclose(fp_I_stim);
  1157. fclose(fp_I_syn);
  1158. fclose(fp_Ca);
  1159. fclose(fp_IP3);
  1160. //fclose(fp_z);
  1161. fclose(fp_G);
  1162. fclose(fp_V);
  1163. //fclose(fp_m);
  1164. //fclose(fp_n);
  1165. //fclose(fp_h);
  1166. //fclose(fp_V_spikes);
  1167.  
  1168. end_rk4 = clock();
  1169. double extime_rk4 = (double)(end_rk4 - start_rk4) / CLOCKS_PER_SEC;
  1170. int minutes = (int)extime_rk4 / 60;
  1171. int seconds = (int)extime_rk4 % 60;
  1172. printf("\nExecution time is: %d minutes %d seconds\n ", minutes, seconds);
  1173.  
  1174. fp0 = fopen("time_exec.txt", "w+");
  1175. fprintf(fp0, "%f\n", extime_rk4);
  1176. fclose(fp0);
  1177.  
  1178. for (int i = 0; i < Node_count; i++)
  1179. free(A_A[i]);
  1180. free(A_A);
  1181.  
  1182. for (int i = 0; i < Node_count; i++)
  1183. free(B_A[i]);
  1184. free(B_A);
  1185.  
  1186. free(C_A);
  1187.  
  1188. for (int i = 0; i < Node_count; i++)
  1189. free(A_N[i]);
  1190. free(A_N);
  1191.  
  1192. for (int i = 0; i < Node_count; i++)
  1193. free(B_N[i]);
  1194. free(B_N);
  1195.  
  1196. free(C_N);
  1197. }
Advertisement
Add Comment
Please, Sign In to add comment