SpaceQuester

Untitled

Jun 24th, 2017
332
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.50 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 N 4
  10.  
  11. #define V f[0]
  12. #define m f[1]
  13. #define n f[2]
  14. #define h f[3]
  15.  
  16. double f[N];
  17.  
  18. double C = 1;
  19.  
  20. double g_K = 36;
  21. double g_Na = 120;
  22. double g_L = 0.3;
  23.  
  24. double E_K = -77; // -77 // -12
  25. double E_Na = 55; // 55 // 115
  26. double E_L = -54.4; // -54.4 // 10
  27.  
  28. const double Meander_start_from_zero = 10;
  29. const double Meander_width = 90;
  30. const double Meander_height = 5.2;
  31. const double Meander_interval = 10;
  32.  
  33. int RandomI(int min, int max)
  34. {
  35. return ((double)rand() / (RAND_MAX - 1)) * (max - min) + min;
  36. }
  37.  
  38. double RandomD(double min, double max)
  39. {
  40. return ((double)rand() / RAND_MAX) * (max - min) + min;
  41. }
  42.  
  43. double alpha_n(double f[N])
  44. {
  45. return 0.01 * (V + 55) / (1 - exp(-(V + 55) / 10));
  46. //return (10 - V) / (100*(exp((10-V)/10)) - 1);
  47. }
  48.  
  49. double beta_n(double f[N])
  50. {
  51. return 0.125 * exp(-(V + 65) / 80);
  52. //return 0.125 * exp(-V/80);
  53. }
  54.  
  55. double alpha_m(double f[N])
  56. {
  57. return 0.1 * (V + 40) / (1 - exp(-(V + 40) / 10));
  58. //return (25 - V) / (10*(exp((25-V)/10) - 1));
  59. }
  60.  
  61. double beta_m(double f[N])
  62. {
  63. return 4 * exp(-(V + 65) / 18);
  64. //return 4 * exp(-V/18);
  65. }
  66.  
  67. double alpha_h(double f[N])
  68. {
  69. return 0.07 * exp(-(V + 65) / 20);
  70. //return 0.07 * exp(-V/20);
  71. }
  72.  
  73. double beta_h(double f[N])
  74. {
  75. return 1 / (exp(-(V + 35) / 10) + 1);
  76. //return 1 / (exp((30-V)/10) + 1);
  77. }
  78.  
  79. double I_stim(double t)
  80. {
  81. if (t < Meander_start_from_zero)
  82. return 0;
  83.  
  84. t -= Meander_start_from_zero;
  85. t = fmod(t, Meander_width + Meander_interval);
  86.  
  87. return t < Meander_width ? Meander_height : 0;
  88. }
  89.  
  90. double HodgkinHuxley(int i, double f[N], double t)
  91. {
  92. switch (i)
  93. {
  94. case 0:
  95. return (g_Na * m * m * m * h * (E_Na - V) + g_K * n * n * n * n * (E_K - V) + g_L * (E_L - V) + I_stim(t)) / C;
  96.  
  97. case 1:
  98. return alpha_m(f) * (1 - m) - beta_m(f) * m;
  99.  
  100. case 2:
  101. return alpha_n(f) * (1 - n) - beta_n(f) * n;
  102.  
  103. case 3:
  104. return alpha_h(f) * (1 - h) - beta_h(f) * h;
  105. }
  106. return 0;
  107. }
  108.  
  109. void RungeKutta(double t, double dt, double f[N], double f_next[N])
  110. {
  111. double k[N][4];
  112.  
  113. // k1
  114. for (int i = 0; i < N; i++)
  115. k[i][0] = HodgkinHuxley(i, f, t) * dt;
  116.  
  117. double phi_k1[N];
  118. for (int i = 0; i < N; i++)
  119. phi_k1[i] = f[i] + k[i][0] / 2;
  120.  
  121. // k2
  122. for (int i = 0; i < N; i++)
  123. k[i][1] = HodgkinHuxley(i, phi_k1, t) * dt;
  124.  
  125. double phi_k2[N];
  126. for (int i = 0; i < N; i++)
  127. phi_k2[i] = f[i] + k[i][1] / 2;
  128.  
  129. // k3
  130. for (int i = 0; i < N; i++)
  131. k[i][2] = HodgkinHuxley(i, phi_k2, t) * dt;
  132.  
  133. double phi_k3[N];
  134. for (int i = 0; i < N; i++)
  135. phi_k3[i] = f[i] + k[i][2] / 2;
  136.  
  137. // k4
  138. for (int i = 0; i < N; i++)
  139. k[i][3] = HodgkinHuxley(i, phi_k3, t) * dt;
  140.  
  141. for (int i = 0; i < N; i++)
  142. f_next[i] = f[i] + (k[i][0] + 2 * k[i][1] + 2 * k[i][2] + k[i][3]) / 6;
  143. }
  144.  
  145. void CopyArray(double source[N], double target[N])
  146. {
  147. for (int i = 0; i < N; i++)
  148. target[i] = source[i];
  149. }
  150.  
  151. bool Approximately(double a, double b)
  152. {
  153. if (a < 0)
  154. a = -a;
  155.  
  156. if (b < 0)
  157. b = -b;
  158.  
  159. return a - b <= 0.000001;
  160. }
  161.  
  162. int main(int argc, char *argv[])
  163. {
  164. //sscanf(argv[1], "%lf", &Meander_height);
  165.  
  166. FILE *fp0;
  167. srand(time(NULL));
  168.  
  169. for (int i = 0; i < N; i++)
  170. f[i] = 0;
  171.  
  172. const double t_start = 0;
  173. const double t_max = 100;
  174. const double dt = 0.0001;
  175.  
  176. double t = t_start;
  177.  
  178. fp0 = fopen("I_stim_height.txt", "a");
  179. fprintf(fp0, "%f\t", Meander_height);
  180. fclose(fp0);
  181.  
  182. fp0 = fopen("results.txt", "w+");
  183. //setlocale(LC_NUMERIC, "French_Canada.1252");
  184.  
  185. clock_t start_rk4, end_rk4;
  186. start_rk4 = clock();
  187. int lastPercent = -1;
  188.  
  189. while (t < t_max || Approximately(t, t_max))
  190. {
  191. fprintf(fp0, "%f\t", t);
  192. fprintf(fp0, "%f\t", I_stim(t));
  193. for (int i = 0; i < N; i++)
  194. {
  195. fprintf(fp0, i == N - 1 ? "%f" : "%f\t", f[i]);
  196. }
  197. fprintf(fp0, "\n");
  198.  
  199. double phi_next[N];
  200.  
  201. RungeKutta(t, dt, f, phi_next);
  202. CopyArray(phi_next, f);
  203.  
  204. t += dt;
  205.  
  206. int percent = (int)(100 * (t - t_start) / (t_max - t_start));
  207. if (percent != lastPercent)
  208. {
  209. printf("Progress: %d%%\n", percent);
  210. lastPercent = percent;
  211. }
  212. }
  213.  
  214. end_rk4 = clock();
  215. double extime_rk4 = (double)(end_rk4 - start_rk4) / CLOCKS_PER_SEC;
  216. int minutes = (int)extime_rk4 / 60;
  217. int seconds = (int)extime_rk4 % 60;
  218. printf("\nExecution time is: %d minutes %d seconds\n ", minutes, seconds);
  219.  
  220. fclose(fp0);
  221.  
  222. fp0 = fopen("time_exec.txt", "w+");
  223. fprintf(fp0, "%f\n", extime_rk4);
  224. fclose(fp0);
  225. }
Advertisement
Add Comment
Please, Sign In to add comment