SpaceQuester

Untitled

Oct 2nd, 2017
373
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.67 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.  
  19. double g_K = 36;
  20. double g_Na = 120;
  21. double g_L = 0.3;
  22.  
  23. double E_K = -77;
  24. double E_Na = 55;
  25. double E_L = -54.4;
  26.  
  27. double g_syn = 0.02; // 0.1
  28. double k_syn = 0.2;
  29.  
  30. double I_app[Equations_count];
  31.  
  32. const double sigma_G = 0.0;
  33. const double sigma_GN = 0.0;
  34. const double sigma_N = 1.0;
  35.  
  36. double** A;
  37. double** B;
  38. double* C;
  39. double** sigma;
  40.  
  41. #define V_old_length 350
  42. double** V_old_array;
  43.  
  44. int V_old_offset = 0;
  45.  
  46. double V(int i)
  47. {
  48. return f[i * 4];
  49. }
  50.  
  51. void SetV(int i, double value)
  52. {
  53. f[i * 4] = value;
  54. }
  55.  
  56. double m(int i)
  57. {
  58. return f[i * 4 + 1];
  59. }
  60.  
  61. void Setm(int i, double value)
  62. {
  63. f[i * 4 + 1] = value;
  64. }
  65.  
  66. double n(int i)
  67. {
  68. return f[i * 4 + 2];
  69. }
  70.  
  71. void Setn(int i, double value)
  72. {
  73. f[i * 4 + 2] = value;
  74. }
  75.  
  76. double h(int i)
  77. {
  78. return f[i * 4 + 3];
  79. }
  80.  
  81. void Seth(int i, double value)
  82. {
  83. f[i * 4 + 3] = value;
  84. }
  85.  
  86. double V_old(int i)
  87. {
  88. if (V_old_offset == 0)
  89. return V_old_array[0][i];
  90.  
  91. if (V_old_offset < V_old_length)
  92. return V_old_array[V_old_length - V_old_offset][i];
  93.  
  94. return V_old_array[0][i];
  95. }
  96.  
  97. int RandomI(int min, int max)
  98. {
  99. return ((double)rand() / (RAND_MAX - 1)) * (max - min) + min;
  100. }
  101.  
  102. double RandomD(double min, double max)
  103. {
  104. return ((double)rand() / RAND_MAX) * (max - min) + min;
  105. }
  106.  
  107. double alpha_n(double* f, int i)
  108. {
  109. return 0.01 * (V(i) + 55) / (1 - exp(-(V(i) + 55) / 10));
  110. }
  111.  
  112. double beta_n(double* f, int i)
  113. {
  114. return 0.125 * exp(-(V(i) + 65) / 80);
  115. }
  116.  
  117. double alpha_m(double* f, int i)
  118. {
  119. return 0.1 * (V(i) + 40) / (1 - exp(-(V(i) + 40) / 10));
  120. }
  121.  
  122. double beta_m(double* f, int i)
  123. {
  124. return 4 * exp(-(V(i) + 65) / 18);
  125. }
  126.  
  127. double alpha_h(double* f, int i)
  128. {
  129. return 0.07 * exp(-(V(i) + 65) / 20);
  130. }
  131.  
  132. double beta_h(double* f, int i)
  133. {
  134. return 1 / (exp(-(V(i) + 35) / 10) + 1);
  135. }
  136.  
  137. double HodgkinHuxley(int i, double* f)
  138. {
  139. int in = i / 4;
  140. int il = i % 4;
  141.  
  142. switch (il)
  143. {
  144. case 0:
  145. {
  146. double sum = 0;
  147.  
  148. //for (int j = 0; j < Node_count; j++)
  149. //{
  150. //sum += sigma[in][j] * A[in][j] * (V(j) - V(in));
  151. //sum += sigma[in][j] * g_syn * V(j) / (1 + exp(-V(in) / k_syn));
  152. //}
  153.  
  154. /*for (int j = 0; j < C[in]; j++)
  155. {
  156. sum += sigma[in][(int)B[in][j]] * (V((int)B[in][j]) - V(in));
  157. }*/
  158.  
  159. for (int j = 0; j < C[in]; j++)
  160. {
  161. // только тут подставил V_old
  162. sum += sigma[in][(int)B[in][j]] * g_syn * V((int)B[in][j]) / (1 + exp(-V(in) / k_syn));
  163. }
  164. printf("sum = %f%%\n", 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 = 0.2;
  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 ? V0 : V1); // V
  450. Setm(i, random < percent ? m0 : m1); // m
  451. Setn(i, random < percent ? n0 : n1); // n
  452. Seth(i, random < percent ? 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.26, 5.28); // init for neurons; Bufurcation point: I_app = 5.27
  462. //I_app[i] = RandomD(8.4, 8.6); // init for neurons; Bufurcation point: I_app = 5.27
  463. }
  464.  
  465. const double t_start = 0;
  466. const double t_max = 5; // 100 msec = 0.1 sec
  467. const double dt = 0.00001; // 0.01 msec = 0.00001 sec
  468.  
  469. double t = t_start;
  470.  
  471. fp0 = fopen("results.txt", "w+");
  472. //setlocale(LC_NUMERIC, "French_Canada.1252");
  473.  
  474. clock_t start_rk4, end_rk4;
  475. start_rk4 = clock();
  476. int lastPercent = -1;
  477.  
  478. FillVOldFromCurrent();
  479.  
  480. while (t < t_max || Approximately(t, t_max))
  481. {
  482. fprintf(fp0, "%f\t", t);
  483.  
  484. for (int i = 0; i < Equations_count; i += 4)
  485. fprintf(fp0, i == Equations_count - 1 ? "%f" : "%f\t", f[i]);
  486.  
  487. fprintf(fp0, "\n");
  488.  
  489. double f_next[Equations_count];
  490.  
  491. RungeKutta(dt, f, f_next);
  492. CopyArray(f_next, f, Equations_count);
  493.  
  494. t += dt;
  495.  
  496. int percent = (int)(100 * (t - t_start) / (t_max - t_start));
  497. if (percent != lastPercent)
  498. {
  499. printf("Progress: %d%%\n", percent);
  500. lastPercent = percent;
  501. }
  502.  
  503. UpdateVOld();
  504. }
  505.  
  506. fclose(fp0);
  507.  
  508. end_rk4 = clock();
  509. double extime_rk4 = (double)(end_rk4 - start_rk4) / CLOCKS_PER_SEC;
  510. int minutes = (int)extime_rk4 / 60;
  511. int seconds = (int)extime_rk4 % 60;
  512. printf("\nExecution time is: %d minutes %d seconds\n ", minutes, seconds);
  513.  
  514. fp0 = fopen("time_exec.txt", "w+");
  515. fprintf(fp0, "%f\n", extime_rk4);
  516. fclose(fp0);
  517.  
  518. for (int i = 0; i < V_old_length; i++)
  519. free(V_old_array[i]);
  520. free(V_old_array);
  521.  
  522. for (int i = 0; i < Node_count; i++)
  523. free(A[i]);
  524. free(A);
  525.  
  526. for (int i = 0; i < Node_count; i++)
  527. free(B[i]);
  528. free(B);
  529.  
  530. for (int i = 0; i < Node_count; i++)
  531. free(sigma[i]);
  532. free(sigma);
  533.  
  534. free(C);
  535. }
Advertisement
Add Comment
Please, Sign In to add comment