SpaceQuester

Untitled

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