SpaceQuester

Untitled

Jun 28th, 2017
326
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.09 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 Neuron_count 20
  10. #define Neuron_count_half Neuron_count / 2
  11.  
  12. #define Equations_per_neuron 4
  13. #define Equations_count Neuron_count * Equations_per_neuron
  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 I_app = 9;
  28.  
  29. const double sigma_G = 0.3;
  30. const double sigma_GN = 0.5;
  31. const double sigma_N = 1.0;
  32.  
  33. double** A;
  34. double** B;
  35. double* C;
  36. double** sigma;
  37.  
  38. double V(int i)
  39. {
  40. return f[i * 4];
  41. }
  42.  
  43. double m(int i)
  44. {
  45. return f[i * 4 + 1];
  46. }
  47.  
  48. double n(int i)
  49. {
  50. return f[i * 4 + 2];
  51. }
  52.  
  53. double h(int i)
  54. {
  55. return f[i * 4 + 3];
  56. }
  57.  
  58. int RandomI(int min, int max)
  59. {
  60. return ((double)rand() / (RAND_MAX - 1)) * (max - min) + min;
  61. }
  62.  
  63. double RandomD(double min, double max)
  64. {
  65. return ((double)rand() / RAND_MAX) * (max - min) + min;
  66. }
  67.  
  68. double alpha_n(double* f, int i)
  69. {
  70. return 0.01 * (V(i) + 55) / (1 - exp(-(V(i) + 55) / 10));
  71. }
  72.  
  73. double beta_n(double* f, int i)
  74. {
  75. return 0.125 * exp(-(V(i) + 65) / 80);
  76. }
  77.  
  78. double alpha_m(double* f, int i)
  79. {
  80. return 0.1 * (V(i) + 40) / (1 - exp(-(V(i) + 40) / 10));
  81. }
  82.  
  83. double beta_m(double* f, int i)
  84. {
  85. return 4 * exp(-(V(i) + 65) / 18);
  86. }
  87.  
  88. double alpha_h(double* f, int i)
  89. {
  90. return 0.07 * exp(-(V(i) + 65) / 20);
  91. }
  92.  
  93. double beta_h(double* f, int i)
  94. {
  95. return 1 / (exp(-(V(i) + 35) / 10) + 1);
  96. }
  97.  
  98. double HodgkinHuxley(int i, double* f)
  99. {
  100. int in = i / 4;
  101. int il = i % 4;
  102.  
  103. switch (il)
  104. {
  105. case 0:
  106. {
  107. double sum = 0;
  108.  
  109. /*for (int j = 0; j < Neuron_count; j++)
  110. {
  111. sum += sigma[in][j] * A[in][j] * (V(j) - V(in));
  112. }*/
  113.  
  114. for (int j = 0; j < C[in]; j++)
  115. sum += sigma[in][(int)B[in][j]] * (V((int)B[in][j]) - V(in));
  116.  
  117. return (g_Na * m(il) * m(il) * m(il) * h(il) * (E_Na - V(il)) + g_K * n(il) * n(il) * n(il) * n(il) * (E_K - V(il)) + g_L * (E_L - V(il)) + I_app + sum) / C_m;
  118. }
  119.  
  120. case 1:
  121. return alpha_m(f, il) * (1 - m(il)) - beta_m(f, il) * m(il);
  122.  
  123. case 2:
  124. return alpha_n(f, il) * (1 - n(il)) - beta_n(f, il) * n(il);
  125.  
  126. case 3:
  127. return alpha_h(f, il) * (1 - h(il)) - beta_h(f, il) * h(il);
  128. }
  129.  
  130. return 0;
  131. }
  132.  
  133. void RungeKutta(double dt, double* f, double* f_next)
  134. {
  135. double k[Equations_count][4];
  136.  
  137. // k1
  138. for (int i = 0; i < Equations_count; i++)
  139. k[i][0] = HodgkinHuxley(i, f) * dt;
  140.  
  141. double phi_k1[Equations_count];
  142. for (int i = 0; i < Equations_count; i++)
  143. phi_k1[i] = f[i] + k[i][0] / 2;
  144.  
  145. // k2
  146. for (int i = 0; i < Equations_count; i++)
  147. k[i][1] = HodgkinHuxley(i, phi_k1) * dt;
  148.  
  149. double phi_k2[Equations_count];
  150. for (int i = 0; i < Equations_count; i++)
  151. phi_k2[i] = f[i] + k[i][1] / 2;
  152.  
  153. // k3
  154. for (int i = 0; i < Equations_count; i++)
  155. k[i][2] = HodgkinHuxley(i, phi_k2) * dt;
  156.  
  157. double phi_k3[Equations_count];
  158. for (int i = 0; i < Equations_count; i++)
  159. phi_k3[i] = f[i] + k[i][2] / 2;
  160.  
  161. // k4
  162. for (int i = 0; i < Equations_count; i++)
  163. k[i][3] = HodgkinHuxley(i, phi_k3) * dt;
  164.  
  165. for (int i = 0; i < Equations_count; i++)
  166. f_next[i] = f[i] + (k[i][0] + 2 * k[i][1] + 2 * k[i][2] + k[i][3]) / 6;
  167. }
  168.  
  169. void CopyArray(double* source, double* target, int N)
  170. {
  171. for (int i = 0; i < N; i++)
  172. target[i] = source[i];
  173. }
  174.  
  175. bool Approximately(double a, double b)
  176. {
  177. if (a < 0)
  178. a = -a;
  179.  
  180. if (b < 0)
  181. b = -b;
  182.  
  183. return a - b <= 0.000001;
  184. }
  185.  
  186. void FillAMatrixZero()
  187. {
  188. for (int i = 0; i < Neuron_count; i++)
  189. {
  190. for (int j = 0; j < Neuron_count; j++)
  191. {
  192. A[i][j] = 0;
  193. }
  194. }
  195. }
  196.  
  197. void FillBCMatrix()
  198. {
  199. for (int i = 0; i < Neuron_count; i++)
  200. {
  201. int bIndex = 0;
  202. C[i] = 0;
  203. for (int j = 0; j < Neuron_count; j++)
  204. {
  205. if (A[i][j] == 1)
  206. {
  207. B[i][bIndex] = j;
  208. bIndex++;
  209. C[i]++;
  210. }
  211. }
  212. }
  213. }
  214.  
  215. void FillSigmaMatrix()
  216. {
  217. for (int i = 0; i < Neuron_count; i++)
  218. {
  219. for (int j = 0; j < Neuron_count; j++)
  220. {
  221. if ((i >= 0 && i < Neuron_count_half) && (j >= 0 || j < Neuron_count_half))
  222. {
  223. sigma[i][j] = sigma_G;
  224. }
  225. if ((((i >= Neuron_count_half && i < Neuron_count) && (j >= 0 && j < Neuron_count_half)) || ((i >= 0 && i < Neuron_count_half) && (j >= Neuron_count_half && j < Neuron_count))))
  226. {
  227. sigma[i][j] = sigma_GN;
  228. }
  229. if ((i >= Neuron_count_half && i < Neuron_count) && (j >= Neuron_count_half && j < Neuron_count))
  230. {
  231. sigma[i][j] = sigma_N;
  232. }
  233. }
  234. }
  235. }
  236.  
  237. void FillRandomMatrix()
  238. {
  239. for (int k = 0; k < 2 * Neuron_count_half; k++)
  240. {
  241. int i, j;
  242.  
  243. do
  244. {
  245. i = RandomI(Neuron_count_half, Neuron_count);
  246. j = RandomI(Neuron_count_half, Neuron_count);
  247. } while ((i == j) || (A[i][j] == 1));
  248.  
  249. A[i][j] = 1;
  250. A[j][i] = 1;
  251. }
  252. }
  253.  
  254. int main(int argc, char *argv[])
  255. {
  256. FILE *fp0;
  257. srand(time(NULL));
  258.  
  259. A = malloc(Neuron_count * sizeof(double));
  260. for (int i = 0; i < Neuron_count; i++)
  261. A[i] = malloc(Neuron_count * sizeof(double));
  262.  
  263. B = malloc(Neuron_count * sizeof(double));
  264. for (int i = 0; i < Neuron_count; i++)
  265. B[i] = malloc(Neuron_count * sizeof(double));
  266.  
  267. C = malloc(Neuron_count * sizeof(double));
  268.  
  269. sigma = malloc(Neuron_count * sizeof(double));
  270. for (int i = 0; i < Neuron_count; i++)
  271. sigma[i] = malloc(Neuron_count * sizeof(double));
  272.  
  273. FillAMatrixZero();
  274. FillRandomMatrix();
  275. FillBCMatrix();
  276. FillSigmaMatrix();
  277.  
  278. fp0 = fopen("A.txt", "w+");
  279. for (int i = 0; i < Neuron_count; i++)
  280. {
  281. for (int j = 0; j < Neuron_count; j++)
  282. {
  283. fprintf(fp0, "%d\t", (int)A[i][j]);
  284. }
  285. fprintf(fp0, "\n");
  286. }
  287. fclose(fp0);
  288.  
  289. //Пишем в файл число связей у каждого осциллятора в четвертом квадранте
  290. fp0 = fopen("links.txt", "w+");
  291. for (int i = Neuron_count_half; i < Neuron_count; i++)
  292. {
  293. int links_count = 0;
  294. for (int j = Neuron_count_half; j < Neuron_count; j++)
  295. {
  296. if (A[i][j] == 1)
  297. {
  298. links_count++;
  299. }
  300. }
  301. fprintf(fp0, "%d\n", (int)links_count);
  302.  
  303. }
  304. fclose(fp0);
  305.  
  306. fp0 = fopen("B.txt", "w+");
  307.  
  308. for (int i = 0; i < Neuron_count; i++)
  309. {
  310. for (int j = 0; j < C[i]; j++)
  311. {
  312. fprintf(fp0, "%d\t", (int)B[i][j]);
  313. }
  314. fprintf(fp0, "\n");
  315. }
  316.  
  317. fclose(fp0);
  318.  
  319. fp0 = fopen("C.txt", "w+");
  320.  
  321. for (int i = 0; i < Neuron_count; i++)
  322. {
  323. fprintf(fp0, "%d\n", (int)C[i]);
  324. }
  325.  
  326. fclose(fp0);
  327.  
  328. fp0 = fopen("sigma.txt", "w+");
  329. for (int i = 0; i < Neuron_count; i++)
  330. {
  331. for (int j = 0; j < Neuron_count; j++)
  332. {
  333. fprintf(fp0, "%f\t", sigma[i][j]);
  334. }
  335. fprintf(fp0, "\n");
  336. }
  337.  
  338. fclose(fp0);
  339.  
  340. // Initial values
  341. for (int i = 0; i < Equations_count; i++)
  342. f[i] = RandomD(-0.05, 0.05); // 0
  343.  
  344. f[4] = 10; // 0
  345. f[8] = -8;
  346.  
  347.  
  348. const double t_start = 0;
  349. const double t_max = 500;
  350. const double dt = 0.001;
  351.  
  352. double t = t_start;
  353.  
  354. fp0 = fopen("results.txt", "w+");
  355. //setlocale(LC_NUMERIC, "French_Canada.1252");
  356.  
  357. clock_t start_rk4, end_rk4;
  358. start_rk4 = clock();
  359. int lastPercent = -1;
  360.  
  361. while (t < t_max || Approximately(t, t_max))
  362. {
  363. fprintf(fp0, "%f\t", t);
  364.  
  365. for (int i = 0; i < Equations_count; i += 4)
  366. fprintf(fp0, i == Equations_count - 1 ? "%f" : "%f\t", f[i]);
  367.  
  368. fprintf(fp0, "\n");
  369.  
  370. double f_next[Equations_count];
  371.  
  372. RungeKutta(dt, f, f_next);
  373. CopyArray(f_next, f, Equations_count);
  374.  
  375. t += dt;
  376.  
  377. int percent = (int)(100 * (t - t_start) / (t_max - t_start));
  378. if (percent != lastPercent)
  379. {
  380. printf("Progress: %d%%\n", percent);
  381. lastPercent = percent;
  382. }
  383. }
  384.  
  385. end_rk4 = clock();
  386. double extime_rk4 = (double)(end_rk4 - start_rk4) / CLOCKS_PER_SEC;
  387. int minutes = (int)extime_rk4 / 60;
  388. int seconds = (int)extime_rk4 % 60;
  389. printf("\nExecution time is: %d minutes %d seconds\n ", minutes, seconds);
  390.  
  391. fclose(fp0);
  392.  
  393. fp0 = fopen("time_exec.txt", "w+");
  394. fprintf(fp0, "%f\n", extime_rk4);
  395. fclose(fp0);
  396.  
  397. for (int i = 0; i < Neuron_count; i++)
  398. free(A[i]);
  399. free(A);
  400.  
  401. for (int i = 0; i < Neuron_count; i++)
  402. free(B[i]);
  403. free(B);
  404.  
  405. for (int i = 0; i < Neuron_count; i++)
  406. free(sigma[i]);
  407. free(sigma);
  408.  
  409. free(C);
  410. }
Advertisement
Add Comment
Please, Sign In to add comment