SpaceQuester

Untitled

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