SpaceQuester

Untitled

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