SpaceQuester

Untitled

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