SpaceQuester

Untitled

Nov 7th, 2017
351
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.88 KB | None | 0 0
  1. #define _USE_MATH_DEFINES
  2. #include "math.h"
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <locale.h>
  6. #include <time.h>
  7. #include <stdbool.h>
  8.  
  9. #define Node_count 5*5*2 // должно быть таким, что бы из этого числа, разделенного на два, извлекался корень
  10. #define Node_count_half Node_count / 2
  11.  
  12. #define Equations_per_node 4
  13. #define Equations_count Node_count * Equations_per_node
  14.  
  15. double f[Equations_count];
  16.  
  17. double C_m = 1;
  18. double g_K = 36;
  19. double g_Na = 120;
  20. double g_L = 0.3;
  21. double E_K = -77;
  22. double E_Na = 55;
  23. double E_L = -54.4;
  24.  
  25. double g_syn = 0.03; // 0.1
  26. double k_syn = 0.2; // 0.2
  27. double E_syn[Node_count];
  28.  
  29. double I_app[Node_count];
  30.  
  31. const double sigma_G = 0.0;
  32. const double sigma_GN = 0.0;
  33. const double sigma_N = 1.0;
  34.  
  35. double** A;
  36. double** B;
  37. double* C;
  38. double** sigma;
  39.  
  40. int V_old_min = 400;
  41. int V_old_max = 1000; // 700 steps = 7 ms delay;
  42.  
  43. int V_old_length[Node_count];
  44. double** V_old_array;
  45.  
  46. int V_old_offset = 0;
  47.  
  48. const double Min_freq = 650; // Hz
  49. const double Max_freq = 650; // 500 Hz
  50. const double Min_magintude = -1.5;
  51. const double Max_magintude = 1.5;
  52. const double Duration = 0.001;
  53.  
  54. double Meander_start_from_zero[Node_count];
  55. double Meander_width[Node_count];
  56. double Meander_height[Node_count];
  57. double Meander_interval[Node_count];
  58. double last_meander_end[Node_count];
  59.  
  60. double I_stim(int i, double t)
  61. {
  62. if (t < Meander_start_from_zero[i])
  63. return 0;
  64.  
  65. t -= Meander_start_from_zero[i];
  66. t = fmod(t, Meander_width[i] + Meander_interval[i]);
  67.  
  68. return t < Meander_width[i] ? Meander_height[i] : 0;
  69. }
  70.  
  71. double V(int i)
  72. {
  73. return f[i * 4];
  74. }
  75.  
  76. void SetV(int i, double value)
  77. {
  78. f[i * 4] = value;
  79. }
  80.  
  81. double m(int i)
  82. {
  83. return f[i * 4 + 1];
  84. }
  85.  
  86. void Setm(int i, double value)
  87. {
  88. f[i * 4 + 1] = value;
  89. }
  90.  
  91. double n(int i)
  92. {
  93. return f[i * 4 + 2];
  94. }
  95.  
  96. void Setn(int i, double value)
  97. {
  98. f[i * 4 + 2] = value;
  99. }
  100.  
  101. double h(int i)
  102. {
  103. return f[i * 4 + 3];
  104. }
  105.  
  106. void Seth(int i, double value)
  107. {
  108. f[i * 4 + 3] = value;
  109. }
  110.  
  111. double V_old(int i)
  112. {
  113. if (V_old_offset < V_old_length[i])
  114. return V(i);
  115.  
  116. return V_old_array[i][0];
  117. }
  118.  
  119. int RandomI(int min, int max)
  120. {
  121. return ((double)rand() / (RAND_MAX - 1)) * (max - min) + min;
  122. }
  123.  
  124. double RandomD(double min, double max)
  125. {
  126. return ((double)rand() / RAND_MAX) * (max - min) + min;
  127. }
  128.  
  129. double alpha_m(double* f, int i)
  130. {
  131. return 0.1 * (V(i) + 40) / (1 - exp(-(V(i) + 40) / 10));
  132. }
  133.  
  134. double beta_m(double* f, int i)
  135. {
  136. return 4 * exp(-(V(i) + 65) / 18);
  137. }
  138.  
  139. double alpha_n(double* f, int i)
  140. {
  141. return 0.01 * (V(i) + 55) / (1 - exp(-(V(i) + 55) / 10));
  142. }
  143.  
  144. double beta_n(double* f, int i)
  145. {
  146. return 0.125 * exp(-(V(i) + 65) / 80);
  147. }
  148.  
  149. double alpha_h(double* f, int i)
  150. {
  151. return 0.07 * exp(-(V(i) + 65) / 20);
  152. }
  153.  
  154. double beta_h(double* f, int i)
  155. {
  156. return 1 / (exp(-(V(i) + 35) / 10) + 1);
  157. }
  158.  
  159. double HodgkinHuxley(int i, double* f, double t)
  160. {
  161. int in = i / 4;
  162. int il = i % 4;
  163.  
  164. switch (il)
  165. {
  166. case 0:
  167. {
  168. double sum = 0;
  169.  
  170. //for (int j = 0; j < Node_count; j++)
  171. //{
  172. //sum += /*sigma[in][j] * */A[in][j] * g_syn * (V(in) - V(j));
  173. //sum += /*sigma[in][j] * */A[in][j] * g_syn * (V(in) - E_syn[in]) / (1 + exp(-V_old(j) / k_syn));
  174. //}
  175.  
  176. /*for (int j = 0; j < C[in]; j++)
  177. {
  178. sum += sigma[in][(int)B[in][j]] * (V((int)B[in][j]) - V(in));
  179. }*/
  180.  
  181. for (int j = 0; j < C[in]; j++)
  182. {
  183. // только тут подставил V_old
  184. sum += /*sigma[in][(int)B[in][j]] * */ g_syn * (V(in) - E_syn[in]) / (1 + exp(-V_old((int)B[in][j]) / k_syn));
  185. //sum += g_syn * (V((int)B[in][j]) - V(in));
  186. }
  187. //printf("i = %d\t sum = %f\n", in, sum);
  188.  
  189. return 1000 * ((g_Na * pow(m(in), 3) * h(in) * (E_Na - V(in)) + g_K * pow(n(in), 4) * (E_K - V(in)) + g_L * (E_L - V(in)) + I_app[in] + I_stim(in, t) + sum) / C_m); // V
  190. }
  191.  
  192. case 1:
  193. {
  194. return 1000 * (alpha_m(f, in) * (1 - m(in)) - beta_m(f, in) * m(in));
  195. }
  196.  
  197. case 2:
  198. {
  199. return 1000 * (alpha_n(f, in) * (1 - n(in)) - beta_n(f, in) * n(in));
  200. }
  201.  
  202. case 3:
  203. {
  204. return 1000 * (alpha_h(f, in) * (1 - h(in)) - beta_h(f, in) * h(in));
  205. }
  206. }
  207.  
  208. return 0;
  209. }
  210.  
  211. void RungeKutta(double t, double dt, double* f, double* f_next)
  212. {
  213. double k[Equations_count][4];
  214.  
  215. // k1
  216. for (int i = 0; i < Equations_count; i++)
  217. k[i][0] = HodgkinHuxley(i, f, t) * dt;
  218.  
  219. double phi_k1[Equations_count];
  220. for (int i = 0; i < Equations_count; i++)
  221. phi_k1[i] = f[i] + k[i][0] / 2;
  222.  
  223. // k2
  224. for (int i = 0; i < Equations_count; i++)
  225. k[i][1] = HodgkinHuxley(i, phi_k1, t) * dt;
  226.  
  227. double phi_k2[Equations_count];
  228. for (int i = 0; i < Equations_count; i++)
  229. phi_k2[i] = f[i] + k[i][1] / 2;
  230.  
  231. // k3
  232. for (int i = 0; i < Equations_count; i++)
  233. k[i][2] = HodgkinHuxley(i, phi_k2, t) * dt;
  234.  
  235. double phi_k3[Equations_count];
  236. for (int i = 0; i < Equations_count; i++)
  237. phi_k3[i] = f[i] + k[i][2] / 2;
  238.  
  239. // k4
  240. for (int i = 0; i < Equations_count; i++)
  241. k[i][3] = HodgkinHuxley(i, phi_k3, t) * dt;
  242.  
  243. for (int i = 0; i < Equations_count; i++)
  244. f_next[i] = f[i] + (k[i][0] + 2 * k[i][1] + 2 * k[i][2] + k[i][3]) / 6;
  245. }
  246.  
  247. void CopyArray(double* source, double* target, int N)
  248. {
  249. for (int i = 0; i < N; i++)
  250. target[i] = source[i];
  251. }
  252.  
  253. bool Approximately(double a, double b)
  254. {
  255. if (a < 0)
  256. a = -a;
  257.  
  258. if (b < 0)
  259. b = -b;
  260.  
  261. return a - b <= 0.000001;
  262. }
  263.  
  264. void GenerateRandomMeander(int i, double min_start_time)
  265. {
  266. Meander_start_from_zero[i] = min_start_time + RandomD(1. / Max_freq, 1. / Min_freq);
  267. Meander_width[i] = Duration;
  268. Meander_height[i] = RandomD(Min_magintude, Max_magintude);
  269. }
  270.  
  271. void FillAMatrixZero()
  272. {
  273. for (int i = 0; i < Node_count; i++)
  274. {
  275. for (int j = 0; j < Node_count; j++)
  276. {
  277. A[i][j] = 0;
  278. }
  279. }
  280. }
  281.  
  282. void FillBCMatrix()
  283. {
  284. for (int i = 0; i < Node_count; i++)
  285. {
  286. int bIndex = 0;
  287. C[i] = 0;
  288. for (int j = 0; j < Node_count; j++)
  289. {
  290. if (A[i][j] == 1)
  291. {
  292. B[i][bIndex] = j;
  293. bIndex++;
  294. C[i]++;
  295. }
  296. }
  297. }
  298. }
  299.  
  300. void FillSigmaMatrix()
  301. {
  302. for (int i = 0; i < Node_count; i++)
  303. {
  304. for (int j = 0; j < Node_count; j++)
  305. {
  306. if ((i >= 0 && i < Node_count_half) && (j >= 0 || j < Node_count_half))
  307. {
  308. sigma[i][j] = sigma_G;
  309. }
  310. if ((((i >= Node_count_half && i < Node_count) && (j >= 0 && j < Node_count_half)) || ((i >= 0 && i < Node_count_half) && (j >= Node_count_half && j < Node_count))))
  311. {
  312. sigma[i][j] = sigma_GN;
  313. }
  314. if ((i >= Node_count_half && i < Node_count) && (j >= Node_count_half && j < Node_count))
  315. {
  316. sigma[i][j] = sigma_N;
  317. }
  318. }
  319. }
  320. }
  321.  
  322. void FillRandomMatrix()
  323. {
  324. for (int k = 0; k < 2 * Node_count_half; k++)
  325. {
  326. int i, j;
  327.  
  328. do
  329. {
  330. i = RandomI(Node_count_half, Node_count);
  331. j = RandomI(Node_count_half, Node_count);
  332. } while ((i == j) || (A[i][j] == 1));
  333.  
  334. A[i][j] = 1;
  335. A[j][i] = 1;
  336. }
  337. }
  338.  
  339. void FillVOldFromCurrent()
  340. {
  341. for (int i = 0; i < Node_count; i++)
  342. for (int j = 0; j < V_old_length[i]; j++)
  343. V_old_array[i][j] = V(i);
  344. }
  345.  
  346. void UpdateVOld()
  347. {
  348. for (int i = 0; i < Node_count; i++)
  349. {
  350. for (int j = 1; j < V_old_length[i]; j++)
  351. V_old_array[i][j - 1] = V_old_array[i][j];
  352.  
  353. V_old_array[i][V_old_length[i] - 1] = V(i);
  354. }
  355.  
  356. V_old_offset++;
  357. }
  358.  
  359. int main(int argc, char *argv[])
  360. {
  361. FILE *fp0;
  362. //FILE *fp_Ca;
  363. //FILE *fp_IP3;
  364. //FILE *fp_z;
  365. //FILE *fp_G;
  366. FILE *fp_I_stim;
  367. FILE *fp_V;
  368. FILE *fp_m;
  369. FILE *fp_n;
  370. FILE *fp_h;
  371. srand(time(NULL));
  372.  
  373. //for (int i = 0; i < Node_count; i++)
  374. // V_old_length[i] = 0;
  375.  
  376. for (int i = 0; i < Node_count; i++)
  377. V_old_length[i] = RandomI(V_old_min, V_old_max);
  378.  
  379. V_old_array = malloc(Node_count * sizeof(double*));
  380. for (int i = 0; i < Node_count; i++)
  381. V_old_array[i] = malloc(V_old_length[i] * sizeof(double));
  382.  
  383. A = malloc(Node_count * sizeof(double));
  384. for (int i = 0; i < Node_count; i++)
  385. A[i] = malloc(Node_count * sizeof(double));
  386.  
  387. B = malloc(Node_count * sizeof(double));
  388. for (int i = 0; i < Node_count; i++)
  389. B[i] = malloc(Node_count * sizeof(double));
  390.  
  391. C = malloc(Node_count * sizeof(double));
  392.  
  393. sigma = malloc(Node_count * sizeof(double));
  394. for (int i = 0; i < Node_count; i++)
  395. sigma[i] = malloc(Node_count * sizeof(double));
  396.  
  397. FillAMatrixZero();
  398. FillRandomMatrix();
  399. FillBCMatrix();
  400. FillSigmaMatrix();
  401.  
  402. fp0 = fopen("A.txt", "w+");
  403. for (int i = 0; i < Node_count; i++)
  404. {
  405. for (int j = 0; j < Node_count; j++)
  406. {
  407. fprintf(fp0, "%d\t", (int)A[i][j]);
  408. }
  409. fprintf(fp0, "\n");
  410. }
  411. fclose(fp0);
  412.  
  413. //Пишем в файл число связей у каждого осциллятора в четвертом квадранте
  414. fp0 = fopen("links.txt", "w+");
  415. for (int i = Node_count_half; i < Node_count; i++)
  416. {
  417. int links_count = 0;
  418. for (int j = Node_count_half; j < Node_count; j++)
  419. {
  420. if (A[i][j] == 1)
  421. {
  422. links_count++;
  423. }
  424. }
  425. fprintf(fp0, "%d\n", (int)links_count);
  426.  
  427. }
  428. fclose(fp0);
  429.  
  430. fp0 = fopen("B.txt", "w+");
  431. for (int i = 0; i < Node_count; i++)
  432. {
  433. for (int j = 0; j < C[i]; j++)
  434. {
  435. fprintf(fp0, "%d\t", (int)B[i][j]);
  436. }
  437. fprintf(fp0, "\n");
  438. }
  439. fclose(fp0);
  440.  
  441. fp0 = fopen("C.txt", "w+");
  442. for (int i = 0; i < Node_count; i++)
  443. {
  444. fprintf(fp0, "%d\n", (int)C[i]);
  445. }
  446. fclose(fp0);
  447.  
  448. fp0 = fopen("sigma.txt", "w+");
  449. for (int i = 0; i < Node_count; i++)
  450. {
  451. for (int j = 0; j < Node_count; j++)
  452. {
  453. fprintf(fp0, "%f\t", sigma[i][j]);
  454. }
  455. fprintf(fp0, "\n");
  456. }
  457. fclose(fp0);
  458.  
  459. // Initial values
  460. /*for (int i = 0; i < Equations_count; i++)
  461. {
  462. f[i] = 0;
  463. }
  464.  
  465. for (int i = 0; i < Equations_count; i++)
  466. {
  467. I_app[i] = RandomD(9, 40);
  468. }*/
  469.  
  470. double percent_stable_state = 0.40;
  471.  
  472. double V0 = -61.5364;
  473. double m0 = 0.0789;
  474. double n0 = 0.3718;
  475. double h0 = 0.4723;
  476.  
  477. double V1 = 34.3334;
  478. double m1 = 0.9165;
  479. double n1 = 0.5626;
  480. double h1 = 0.2440;
  481.  
  482. for (int i = 0; i < Node_count; i++) // init array for all neurons
  483. {
  484. SetV(i, 0); // V
  485. Setm(i, 0); // m
  486. Setn(i, 0); // n
  487. Seth(i, 0); // h
  488. }
  489. for (int i = Node_count_half; i < Node_count; i++) // init only neuron nodes
  490. {
  491. double random = RandomD(0, 1);
  492.  
  493. SetV(i, random < percent_stable_state ? V0 : V1); // V
  494. Setm(i, random < percent_stable_state ? m0 : m1); // m
  495. Setn(i, random < percent_stable_state ? n0 : n1); // n
  496. Seth(i, random < percent_stable_state ? h0 : h1); // h
  497. }
  498.  
  499. for (int i = 0; i < Node_count; i++)
  500. {
  501. I_app[i] = 0; // init for neurons all array
  502. }
  503.  
  504. for (int i = Node_count_half; i < Node_count; i++)
  505. {
  506. I_app[i] = 5.27; //RandomD(5.20, 5.34); // init for neurons; Bifurcation point: I_app = 5.27
  507. }
  508.  
  509. double percent_excitable = 0.8; // 0.8
  510. double E_syn0 = 0;
  511. double E_syn1 = -90;
  512.  
  513. for (int i = 0; i < Node_count; i++)
  514. {
  515. E_syn[i] = 0; // init for neurons all array
  516. }
  517.  
  518. for (int i = Node_count_half; i < Node_count; i++)
  519. {
  520. double random = RandomD(0, 1);
  521. E_syn[i] = random < percent_excitable ? E_syn0 : E_syn1;
  522. //printf("i = %d\t E_syn = %f\n", i, E_syn[i]);
  523. }
  524.  
  525. for (int i = 0; i < Node_count; i++)
  526. {
  527. GenerateRandomMeander(i, 0);
  528. last_meander_end[i] = Meander_start_from_zero[i] + Duration;
  529. }
  530.  
  531. const double t_start = 0;
  532. const double t_max = 10; // 100 msec = 0.1 sec
  533. const double dt = 0.00001; // 0.01 msec = 0.00001 sec; 1 msec = 0.001 sec
  534.  
  535. double t = t_start;
  536.  
  537. //fp0 = fopen("results.txt", "w+");
  538. //setlocale(LC_NUMERIC, "French_Canada.1252");
  539.  
  540. clock_t start_rk4, end_rk4;
  541. start_rk4 = clock();
  542. int lastPercent = -1;
  543.  
  544. FillVOldFromCurrent();
  545.  
  546. //fp_Ca = fopen("results_Ca.txt", "w+");
  547. //fp_IP3 = fopen("results_IP3.txt", "w+");
  548. //fp_z = fopen("results_z.txt", "w+");
  549. //fp_G = fopen("results_G.txt", "w+");
  550. fp_I_stim = fopen("results_I_stim.txt", "w+");
  551. fp_V = fopen("results_V.txt", "w+");
  552. fp_m = fopen("results_m.txt", "w+");
  553. fp_n = fopen("results_n.txt", "w+");
  554. fp_h = fopen("results_h.txt", "w+");
  555.  
  556. while (t < t_max || Approximately(t, t_max))
  557. {
  558. //fprintf(fp_Ca, "%f\t", t);
  559. //fprintf(fp_IP3, "%f\t", t);
  560. //fprintf(fp_z, "%f\t", t);
  561. //fprintf(fp_G, "%f\t", t);
  562. fprintf(fp_I_stim, "%f\t", t);
  563. fprintf(fp_V, "%f\t", t);
  564. fprintf(fp_m, "%f\t", t);
  565. fprintf(fp_n, "%f\t", t);
  566. fprintf(fp_h, "%f\t", t);
  567.  
  568. for (int i = 0; i < Node_count; i++)
  569. {
  570. if (t > last_meander_end[i])
  571. {
  572. GenerateRandomMeander(i, t);
  573. last_meander_end[i] = Meander_start_from_zero[i] + Duration;
  574. }
  575.  
  576. fprintf(fp_I_stim, "%f\t", I_stim(i, t));
  577. }
  578. fprintf(fp_I_stim, "\n");
  579.  
  580. //for (int i = 0; i < Equations_count; i += 8)
  581. // fprintf(fp_Ca, i == Equations_count - 1 ? "%f" : "%f\t", f[i]); // Ca
  582.  
  583. //for (int i = 1; i < Equations_count; i += 8)
  584. // fprintf(fp_IP3, i == Equations_count - 1 ? "%f" : "%f\t", f[i]); // IP3
  585.  
  586. //for (int i = 2; i < Equations_count; i += 8)
  587. // fprintf(fp_z, i == Equations_count - 1 ? "%f" : "%f\t", f[i]); // z
  588.  
  589. //for (int i = 3; i < Equations_count; i += 8)
  590. // fprintf(fp_G, i == Equations_count - 1 ? "%f" : "%f\t", f[i]); // G
  591.  
  592. for (int i = 0; i < Equations_count; i += 4)
  593. fprintf(fp_V, i == Equations_count - 1 ? "%f" : "%f\t", f[i]); // V
  594.  
  595. for (int i = 1; i < Equations_count; i += 4)
  596. fprintf(fp_m, i == Equations_count - 1 ? "%f" : "%f\t", f[i]); // m
  597.  
  598. for (int i = 2; i < Equations_count; i += 4)
  599. fprintf(fp_n, i == Equations_count - 1 ? "%f" : "%f\t", f[i]); // n
  600.  
  601. for (int i = 3; i < Equations_count; i += 4)
  602. fprintf(fp_h, i == Equations_count - 1 ? "%f" : "%f\t", f[i]); // h
  603.  
  604. //fprintf(fp_Ca, "\n");
  605. //fprintf(fp_IP3, "\n");
  606. //fprintf(fp_z, "\n");
  607. //fprintf(fp_G, "\n");
  608. fprintf(fp_V, "\n");
  609. fprintf(fp_m, "\n");
  610. fprintf(fp_n, "\n");
  611. fprintf(fp_h, "\n");
  612.  
  613. double f_next[Equations_count];
  614.  
  615. RungeKutta(t, dt, f, f_next);
  616. CopyArray(f_next, f, Equations_count);
  617.  
  618. t += dt;
  619.  
  620. int percent = (int)(100 * (t - t_start) / (t_max - t_start));
  621. if (percent != lastPercent)
  622. {
  623. printf("Progress: %d%%\n", percent);
  624. lastPercent = percent;
  625. }
  626.  
  627. //printf("V(24) = %f\t V_old(24) = %f\n", f[24*4], V_old(24));
  628. UpdateVOld();
  629. }
  630.  
  631. //fclose(fp_Ca);
  632. //fclose(fp_IP3);
  633. //fclose(fp_z);
  634. //fclose(fp_G);
  635. fclose(fp_I_stim);
  636. fclose(fp_V);
  637. fclose(fp_m);
  638. fclose(fp_n);
  639. fclose(fp_h);
  640.  
  641. end_rk4 = clock();
  642. double extime_rk4 = (double)(end_rk4 - start_rk4) / CLOCKS_PER_SEC;
  643. int minutes = (int)extime_rk4 / 60;
  644. int seconds = (int)extime_rk4 % 60;
  645. printf("\nExecution time is: %d minutes %d seconds\n ", minutes, seconds);
  646.  
  647. fp0 = fopen("time_exec.txt", "w+");
  648. fprintf(fp0, "%f\n", extime_rk4);
  649. fclose(fp0);
  650.  
  651. for (int i = 0; i < Node_count; i++)
  652. free(V_old_array[i]);
  653. free(V_old_array);
  654.  
  655. for (int i = 0; i < Node_count; i++)
  656. free(A[i]);
  657. free(A);
  658.  
  659. for (int i = 0; i < Node_count; i++)
  660. free(B[i]);
  661. free(B);
  662.  
  663. for (int i = 0; i < Node_count; i++)
  664. free(sigma[i]);
  665. free(sigma);
  666.  
  667. free(C);
  668. }
Advertisement
Add Comment
Please, Sign In to add comment