SpaceQuester

Untitled

Oct 9th, 2017
449
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.18 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.1; // 0.1
  26. double k_syn = 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. #define V_old_length 700
  41. double** V_old_array;
  42.  
  43. int V_old_offset = 0;
  44.  
  45. double V(int i)
  46. {
  47. return f[i * 4];
  48. }
  49.  
  50. void SetV(int i, double value)
  51. {
  52. f[i * 4] = value;
  53. }
  54.  
  55. double m(int i)
  56. {
  57. return f[i * 4 + 1];
  58. }
  59.  
  60. void Setm(int i, double value)
  61. {
  62. f[i * 4 + 1] = value;
  63. }
  64.  
  65. double n(int i)
  66. {
  67. return f[i * 4 + 2];
  68. }
  69.  
  70. void Setn(int i, double value)
  71. {
  72. f[i * 4 + 2] = value;
  73. }
  74.  
  75. double h(int i)
  76. {
  77. return f[i * 4 + 3];
  78. }
  79.  
  80. void Seth(int i, double value)
  81. {
  82. f[i * 4 + 3] = value;
  83. }
  84.  
  85. double V_old(int i)
  86. {
  87. if (V_old_offset == 0)
  88. return V_old_array[0][i];
  89.  
  90. if (V_old_offset < V_old_length)
  91. return V_old_array[V_old_length - V_old_offset][i];
  92.  
  93. return V_old_array[0][i];
  94. }
  95.  
  96. int RandomI(int min, int max)
  97. {
  98. return ((double)rand() / (RAND_MAX - 1)) * (max - min) + min;
  99. }
  100.  
  101. double RandomD(double min, double max)
  102. {
  103. return ((double)rand() / RAND_MAX) * (max - min) + min;
  104. }
  105.  
  106. double alpha_n(double* f, int i)
  107. {
  108. return 0.01 * (V(i) + 55) / (1 - exp(-(V(i) + 55) / 10));
  109. }
  110.  
  111. double beta_n(double* f, int i)
  112. {
  113. return 0.125 * exp(-(V(i) + 65) / 80);
  114. }
  115.  
  116. double alpha_m(double* f, int i)
  117. {
  118. return 0.1 * (V(i) + 40) / (1 - exp(-(V(i) + 40) / 10));
  119. }
  120.  
  121. double beta_m(double* f, int i)
  122. {
  123. return 4 * exp(-(V(i) + 65) / 18);
  124. }
  125.  
  126. double alpha_h(double* f, int i)
  127. {
  128. return 0.07 * exp(-(V(i) + 65) / 20);
  129. }
  130.  
  131. double beta_h(double* f, int i)
  132. {
  133. return 1 / (exp(-(V(i) + 35) / 10) + 1);
  134. }
  135.  
  136. double HodgkinHuxley(int i, double* f)
  137. {
  138. int in = i / 4;
  139. int il = i % 4;
  140.  
  141. switch (il)
  142. {
  143. case 0:
  144. {
  145. double sum = 0;
  146.  
  147. for (int j = 0; j < Node_count; j++)
  148. {
  149. //sum += /*sigma[in][j] * */A[in][j] * g_syn * (V(j) - V(in));
  150. sum += /*sigma[in][j] * */A[in][j] * g_syn * (V(in) - E_syn[in]) / (1 + exp(-V(j) / k_syn));
  151. }
  152.  
  153. /*for (int j = 0; j < C[in]; j++)
  154. {
  155. sum += sigma[in][(int)B[in][j]] * (V((int)B[in][j]) - V(in));
  156. }*/
  157.  
  158. //for (int j = 0; j < C[in]; j++)
  159. //{
  160. // только тут подставил V_old
  161. //sum += /*sigma[in][(int)B[in][j]] * */ g_syn * (V(in) - E_syn[in]) / (1 + exp(-V((int)B[in][j]) / k_syn));
  162. //sum += g_syn * (V((int)B[in][j]) - V(in));
  163. //}
  164. //printf("i = %d\t sum = %f\n", in, sum);
  165.  
  166. 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] + sum) / C_m); // V
  167. }
  168.  
  169. case 1:
  170. {
  171. return 1000 * (alpha_m(f, in) * (1 - m(in)) - beta_m(f, in) * m(in));
  172. }
  173.  
  174. case 2:
  175. {
  176. return 1000 * (alpha_n(f, in) * (1 - n(in)) - beta_n(f, in) * n(in));
  177. }
  178.  
  179. case 3:
  180. {
  181. return 1000 * (alpha_h(f, in) * (1 - h(in)) - beta_h(f, in) * h(in));
  182. }
  183. }
  184.  
  185. return 0;
  186. }
  187.  
  188. void RungeKutta(double dt, double* f, double* f_next)
  189. {
  190. double k[Equations_count][4];
  191.  
  192. // k1
  193. for (int i = 0; i < Equations_count; i++)
  194. k[i][0] = HodgkinHuxley(i, f) * dt;
  195.  
  196. double phi_k1[Equations_count];
  197. for (int i = 0; i < Equations_count; i++)
  198. phi_k1[i] = f[i] + k[i][0] / 2;
  199.  
  200. // k2
  201. for (int i = 0; i < Equations_count; i++)
  202. k[i][1] = HodgkinHuxley(i, phi_k1) * dt;
  203.  
  204. double phi_k2[Equations_count];
  205. for (int i = 0; i < Equations_count; i++)
  206. phi_k2[i] = f[i] + k[i][1] / 2;
  207.  
  208. // k3
  209. for (int i = 0; i < Equations_count; i++)
  210. k[i][2] = HodgkinHuxley(i, phi_k2) * dt;
  211.  
  212. double phi_k3[Equations_count];
  213. for (int i = 0; i < Equations_count; i++)
  214. phi_k3[i] = f[i] + k[i][2] / 2;
  215.  
  216. // k4
  217. for (int i = 0; i < Equations_count; i++)
  218. k[i][3] = HodgkinHuxley(i, phi_k3) * dt;
  219.  
  220. for (int i = 0; i < Equations_count; i++)
  221. f_next[i] = f[i] + (k[i][0] + 2 * k[i][1] + 2 * k[i][2] + k[i][3]) / 6;
  222. }
  223.  
  224. void CopyArray(double* source, double* target, int N)
  225. {
  226. for (int i = 0; i < N; i++)
  227. target[i] = source[i];
  228. }
  229.  
  230. bool Approximately(double a, double b)
  231. {
  232. if (a < 0)
  233. a = -a;
  234.  
  235. if (b < 0)
  236. b = -b;
  237.  
  238. return a - b <= 0.000001;
  239. }
  240.  
  241. void FillAMatrixZero()
  242. {
  243. for (int i = 0; i < Node_count; i++)
  244. {
  245. for (int j = 0; j < Node_count; j++)
  246. {
  247. A[i][j] = 0;
  248. }
  249. }
  250. }
  251.  
  252. void FillBCMatrix()
  253. {
  254. for (int i = 0; i < Node_count; i++)
  255. {
  256. int bIndex = 0;
  257. C[i] = 0;
  258. for (int j = 0; j < Node_count; j++)
  259. {
  260. if (A[i][j] == 1)
  261. {
  262. B[i][bIndex] = j;
  263. bIndex++;
  264. C[i]++;
  265. }
  266. }
  267. }
  268. }
  269.  
  270. void FillSigmaMatrix()
  271. {
  272. for (int i = 0; i < Node_count; i++)
  273. {
  274. for (int j = 0; j < Node_count; j++)
  275. {
  276. if ((i >= 0 && i < Node_count_half) && (j >= 0 || j < Node_count_half))
  277. {
  278. sigma[i][j] = sigma_G;
  279. }
  280. 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))))
  281. {
  282. sigma[i][j] = sigma_GN;
  283. }
  284. if ((i >= Node_count_half && i < Node_count) && (j >= Node_count_half && j < Node_count))
  285. {
  286. sigma[i][j] = sigma_N;
  287. }
  288. }
  289. }
  290. }
  291.  
  292. void FillRandomMatrix()
  293. {
  294. for (int k = 0; k < 2 * Node_count_half; k++)
  295. {
  296. int i, j;
  297.  
  298. do
  299. {
  300. i = RandomI(Node_count_half, Node_count);
  301. j = RandomI(Node_count_half, Node_count);
  302. } while ((i == j) || (A[i][j] == 1));
  303.  
  304. A[i][j] = 1;
  305. A[j][i] = 1;
  306. }
  307. }
  308.  
  309. void FillVOldFromCurrent()
  310. {
  311. for (int i = 0; i < V_old_length; i++)
  312. for (int j = 0; j < Node_count; j++)
  313. V_old_array[i][j] = V(j);
  314. }
  315.  
  316. void UpdateVOld()
  317. {
  318. double* tmp = V_old_array[0];
  319.  
  320. for (int i = 1; i < V_old_length; i++)
  321. V_old_array[i - 1] = V_old_array[i];
  322.  
  323. for (int i = 0; i < Node_count; i++)
  324. tmp[i] = V(i);
  325.  
  326. V_old_array[V_old_length - 1] = tmp;
  327.  
  328. V_old_offset++;
  329. }
  330.  
  331. int main(int argc, char *argv[])
  332. {
  333. FILE *fp0;
  334. srand(time(NULL));
  335.  
  336. V_old_array = malloc(V_old_length * sizeof(double*));
  337. for (int i = 0; i < V_old_length; i++)
  338. V_old_array[i] = malloc(Node_count * sizeof(double));
  339.  
  340. A = malloc(Node_count * sizeof(double));
  341. for (int i = 0; i < Node_count; i++)
  342. A[i] = malloc(Node_count * sizeof(double));
  343.  
  344. B = malloc(Node_count * sizeof(double));
  345. for (int i = 0; i < Node_count; i++)
  346. B[i] = malloc(Node_count * sizeof(double));
  347.  
  348. C = malloc(Node_count * sizeof(double));
  349.  
  350. sigma = malloc(Node_count * sizeof(double));
  351. for (int i = 0; i < Node_count; i++)
  352. sigma[i] = malloc(Node_count * sizeof(double));
  353.  
  354. FillAMatrixZero();
  355. FillRandomMatrix();
  356. FillBCMatrix();
  357. FillSigmaMatrix();
  358.  
  359. fp0 = fopen("A.txt", "w+");
  360. for (int i = 0; i < Node_count; i++)
  361. {
  362. for (int j = 0; j < Node_count; j++)
  363. {
  364. fprintf(fp0, "%d\t", (int)A[i][j]);
  365. }
  366. fprintf(fp0, "\n");
  367. }
  368. fclose(fp0);
  369.  
  370. //Пишем в файл число связей у каждого осциллятора в четвертом квадранте
  371. fp0 = fopen("links.txt", "w+");
  372. for (int i = Node_count_half; i < Node_count; i++)
  373. {
  374. int links_count = 0;
  375. for (int j = Node_count_half; j < Node_count; j++)
  376. {
  377. if (A[i][j] == 1)
  378. {
  379. links_count++;
  380. }
  381. }
  382. fprintf(fp0, "%d\n", (int)links_count);
  383.  
  384. }
  385. fclose(fp0);
  386.  
  387. fp0 = fopen("B.txt", "w+");
  388. for (int i = 0; i < Node_count; i++)
  389. {
  390. for (int j = 0; j < C[i]; j++)
  391. {
  392. fprintf(fp0, "%d\t", (int)B[i][j]);
  393. }
  394. fprintf(fp0, "\n");
  395. }
  396. fclose(fp0);
  397.  
  398. fp0 = fopen("C.txt", "w+");
  399. for (int i = 0; i < Node_count; i++)
  400. {
  401. fprintf(fp0, "%d\n", (int)C[i]);
  402. }
  403. fclose(fp0);
  404.  
  405. fp0 = fopen("sigma.txt", "w+");
  406. for (int i = 0; i < Node_count; i++)
  407. {
  408. for (int j = 0; j < Node_count; j++)
  409. {
  410. fprintf(fp0, "%f\t", sigma[i][j]);
  411. }
  412. fprintf(fp0, "\n");
  413. }
  414. fclose(fp0);
  415.  
  416. // Initial values
  417. /*for (int i = 0; i < Equations_count; i++)
  418. {
  419. f[i] = 0;
  420. }
  421.  
  422. for (int i = 0; i < Equations_count; i++)
  423. {
  424. I_app[i] = RandomD(9, 40);
  425. }*/
  426.  
  427. double percent_stable_state = 0.45;
  428.  
  429. double V0 = -61.5364;
  430. double V1 = 34.3334;
  431. double m0 = 0.0789;
  432. double m1 = 0.9165;
  433. double n0 = 0.3718;
  434. double n1 = 0.5626;
  435. double h0 = 0.4723;
  436. double h1 = 0.2440;
  437.  
  438. for (int i = 0; i < Node_count; i++) // init array for all neurons
  439. {
  440. SetV(i, 0); // V
  441. Setm(i, 0); // m
  442. Setn(i, 0); // n
  443. Seth(i, 0); // h
  444. }
  445. for (int i = Node_count_half; i < Node_count; i++) // init only neuron nodes
  446. {
  447. double random = RandomD(0, 1);
  448.  
  449. SetV(i, random < percent_stable_state ? V0 : V1); // V
  450. Setm(i, random < percent_stable_state ? m0 : m1); // m
  451. Setn(i, random < percent_stable_state ? n0 : n1); // n
  452. Seth(i, random < percent_stable_state ? h0 : h1); // h
  453. }
  454.  
  455. for (int i = 0; i < Node_count; i++)
  456. {
  457. I_app[i] = 0; // init for neurons all array
  458. }
  459. for (int i = Node_count_half; i < Node_count; i++)
  460. {
  461. I_app[i] = RandomD(5.25, 5.29); // init for neurons; Bifurcation point: I_app = 5.27
  462. }
  463.  
  464. double percent_excitable = 0.8;
  465. double E_syn0 = 0;
  466. double E_syn1 = -90;
  467.  
  468. for (int i = 0; i < Node_count; i++)
  469. {
  470. E_syn[i] = 0; // init for neurons all array
  471. }
  472. for (int i = Node_count_half; i < Node_count; i++)
  473. {
  474. double random = RandomD(0, 1);
  475. E_syn[i] = random < percent_excitable ? E_syn0 : E_syn1;
  476. //printf("i = %d\t E_syn = %f\n", i, E_syn[i]);
  477. }
  478.  
  479. const double t_start = 0;
  480. const double t_max = 5; // 100 msec = 0.1 sec
  481. const double dt = 0.00001; // 0.01 msec = 0.00001 sec; 1 msec = 0.001 sec
  482.  
  483. double t = t_start;
  484.  
  485. fp0 = fopen("results.txt", "w+");
  486. //setlocale(LC_NUMERIC, "French_Canada.1252");
  487.  
  488. clock_t start_rk4, end_rk4;
  489. start_rk4 = clock();
  490. int lastPercent = -1;
  491.  
  492. FillVOldFromCurrent();
  493.  
  494. while (t < t_max || Approximately(t, t_max))
  495. {
  496. fprintf(fp0, "%f\t", t);
  497.  
  498. for (int i = 0; i < Equations_count; i += 4)
  499. fprintf(fp0, i == Equations_count - 1 ? "%f" : "%f\t", f[i]);
  500.  
  501. fprintf(fp0, "\n");
  502.  
  503. double f_next[Equations_count];
  504.  
  505. RungeKutta(dt, f, f_next);
  506. CopyArray(f_next, f, Equations_count);
  507.  
  508. t += dt;
  509.  
  510. int percent = (int)(100 * (t - t_start) / (t_max - t_start));
  511. if (percent != lastPercent)
  512. {
  513. printf("Progress: %d%%\n", percent);
  514. lastPercent = percent;
  515. }
  516.  
  517. UpdateVOld();
  518. }
  519.  
  520. fclose(fp0);
  521.  
  522. end_rk4 = clock();
  523. double extime_rk4 = (double)(end_rk4 - start_rk4) / CLOCKS_PER_SEC;
  524. int minutes = (int)extime_rk4 / 60;
  525. int seconds = (int)extime_rk4 % 60;
  526. printf("\nExecution time is: %d minutes %d seconds\n ", minutes, seconds);
  527.  
  528. fp0 = fopen("time_exec.txt", "w+");
  529. fprintf(fp0, "%f\n", extime_rk4);
  530. fclose(fp0);
  531.  
  532. for (int i = 0; i < V_old_length; i++)
  533. free(V_old_array[i]);
  534. free(V_old_array);
  535.  
  536. for (int i = 0; i < Node_count; i++)
  537. free(A[i]);
  538. free(A);
  539.  
  540. for (int i = 0; i < Node_count; i++)
  541. free(B[i]);
  542. free(B);
  543.  
  544. for (int i = 0; i < Node_count; i++)
  545. free(sigma[i]);
  546. free(sigma);
  547.  
  548. free(C);
  549. }
Advertisement
Add Comment
Please, Sign In to add comment