fork download
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4.  
  5. // ベクトル領域を確保する関数
  6. // i: 開始インデックス, j: 終了インデックス
  7. double *dvector(long i, long j) {
  8. double *a;
  9. if ((a = malloc(((j - i + 1) * sizeof(double)))) == NULL) { // メモリ確保
  10. printf("メモリが確保できません\n");
  11. exit(1);
  12. }
  13. return (a - i); // インデックスを 1 ベースで使えるように調整
  14. }
  15.  
  16. // 確保したベクトル領域を解放する関数
  17. void free_dvector(double *a, long i) {
  18. free((void *)(a + i));
  19. }
  20.  
  21. // 連立微分方程式の右辺を定義する関数
  22. // x: 現在の x 値, y: 現在の y ベクトル, f: 微分方程式の結果を格納
  23. void FUNC(double x, double *y, double *f) {
  24. f[1] = y[2] - 3 * y[1];
  25. f[2] = -y[2] + cos(x);
  26. }
  27.  
  28. // 4次のルンゲ=クッタ法
  29. // y: 解ベクトル, f: 傾きベクトル, N: ベクトルの次元, a: 開始点, b: 終了点, n: 分割数, F: 右辺関数
  30. void rk4m(double *y, double *f, int N, double a, double b, int n, void (*F)()) {
  31. double *k1, *k2, *k3, *k4, *tmp, x, h;
  32. int i, j;
  33.  
  34. // ベクトル領域の確保
  35. k1 = dvector(1, N);
  36. k2 = dvector(1, N);
  37. k3 = dvector(1, N);
  38. k4 = dvector(1, N);
  39. tmp = dvector(1, N);
  40.  
  41. h = (b - a) / n; // ステップ幅
  42. x = a; // x の初期値
  43. printf("%.3lf\t %.3lf\t %.10lf\n", x, y[1], y[2]); // 初期条件を出力
  44.  
  45. // ループで数値解を計算
  46. for (i = 0; i < n; i++) {
  47. // k1 の計算
  48. (*F)(x, y, f); // f = F(x, y)
  49. for (j = 1; j <= N; j++) k1[j] = f[j];
  50.  
  51. // k2 の計算
  52. for (j = 1; j <= N; j++) tmp[j] = y[j] + h * k1[j] / 2.0;
  53. (*F)(x + h / 2.0, tmp, f);
  54. for (j = 1; j <= N; j++) k2[j] = f[j];
  55.  
  56. // k3 の計算
  57. for (j = 1; j <= N; j++) tmp[j] = y[j] + h * k2[j] / 2.0;
  58. (*F)(x + h / 2.0, tmp, f);
  59. for (j = 1; j <= N; j++) k3[j] = f[j];
  60.  
  61. // k4 の計算
  62. for (j = 1; j <= N; j++) tmp[j] = y[j] + h * k3[j];
  63. (*F)(x + h, tmp, f);
  64. for (j = 1; j <= N; j++) k4[j] = f[j];
  65.  
  66. // 次の y の計算
  67. for (j = 1; j <= N; j++) {
  68. y[j] = y[j] + h * (k1[j] + 2 * k2[j] + 2 * k3[j] + k4[j]) / 6.0;
  69. }
  70.  
  71. x += h; // 次の x 値
  72. printf("%.3lf\t %.10lf\t %.10lf\n", x, y[1], y[2]); // 結果を出力
  73. }
  74.  
  75. // ベクトル領域の解放
  76. free_dvector(k1, 1);
  77. free_dvector(k2, 1);
  78. free_dvector(k3, 1);
  79. free_dvector(k4, 1);
  80. free_dvector(tmp, 1);
  81. }
  82.  
  83. // メイン関数
  84. int main(void) {
  85. int n, N = 2; // n: 分割数, N: 連立方程式の次元
  86. double *y, *f, a = 0.0, b = 5.0; // a: 開始点, b: 終了点
  87.  
  88. y = dvector(1, N); // 解ベクトルの確保
  89. f = dvector(1, N); // 傾きベクトルの確保
  90.  
  91. // 初期条件
  92. y[1] = 0.1; // y1(初期値)
  93. y[2] = 0.0; // y2(初期値)
  94.  
  95. printf("分割数を入力してください\n");
  96. scanf("%d", &n); // 分割数の入力
  97.  
  98. // ルンゲ=クッタ法を実行
  99. rk4m(y, f, N, a, b, n, FUNC);
  100.  
  101. // メモリ解放
  102. free_dvector(y, 1);
  103. free_dvector(f, 1);
  104.  
  105. return 0;
  106. }
  107.  
Success #stdin #stdout 0.01s 5284KB
stdin
50
stdout
分割数を入力してください
0.000	 0.100	 0.0000000000
0.100	 0.0784675008	 0.0949999818
0.200	 0.0702685471	 0.1800023885
0.300	 0.0710843503	 0.2550189693
0.400	 0.0777171554	 0.3200793076
0.500	 0.0878015997	 0.3752383225
0.600	 0.0995914795	 0.4205827764
0.700	 0.1118022949	 0.4562367919
0.800	 0.1234950347	 0.4823663886
0.900	 0.1339904266	 0.4991830510
1.000	 0.1428056760	 0.5069463453
1.100	 0.1496077829	 0.5059656048
1.200	 0.1541790624	 0.4966007123
1.300	 0.1563916280	 0.4792620069
1.400	 0.1561884420	 0.4544093554
1.500	 0.1535691597	 0.4225504253
1.600	 0.1485794596	 0.3842382085
1.700	 0.1413028915	 0.3400678442
1.800	 0.1318545342	 0.2906727981
1.900	 0.1203759393	 0.2367204554
2.000	 0.1070309805	 0.1789071929
2.100	 0.0920023320	 0.1179529947
2.200	 0.0754883762	 0.0545956837
2.300	 0.0577003998	 -0.0104151621
2.400	 0.0388599795	 -0.0763245326
2.500	 0.0191964908	 -0.1423784743
2.600	 -0.0010553020	 -0.2078306684
2.700	 -0.0216576018	 -0.2719490240
2.800	 -0.0423718908	 -0.3340222111
2.900	 -0.0629612022	 -0.3933660602
3.000	 -0.0831923476	 -0.4493297588
3.100	 -0.1028380906	 -0.5013017746
3.200	 -0.1216792535	 -0.5487154416
3.300	 -0.1395067432	 -0.5910541481
3.400	 -0.1561234802	 -0.6278560695
3.500	 -0.1713462136	 -0.6587183939
3.600	 -0.1850072060	 -0.6833009964
3.700	 -0.1969557727	 -0.7013295191
3.800	 -0.2070596597	 -0.7125978249
3.900	 -0.2152062471	 -0.7169697971
4.000	 -0.2213035658	 -0.7143804637
4.100	 -0.2252811161	 -0.7048364337
4.200	 -0.2270904809	 -0.6884156383
4.300	 -0.2267057259	 -0.6652663776
4.400	 -0.2241235822	 -0.6356056812
4.500	 -0.2193634101	 -0.5997169967
4.600	 -0.2124669418	 -0.5579472285
4.700	 -0.2034978079	 -0.5107031547
4.800	 -0.1925408488	 -0.4584472569
4.900	 -0.1797012199	 -0.4016930033
5.000	 -0.1651032986	 -0.3409996322