SpaceQuester

Untitled

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