SpaceQuester

Untitled

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