fork download
  1. #include <stdio.h>
  2. #include <math.h>
  3.  
  4. // 円周率の定義
  5. #ifndef M_PI
  6. #define M_PI 3.14159265358979323846
  7. #endif
  8.  
  9. // --- 関数定義 ---
  10. // 対象関数: y = sin(x) / x
  11. double f(double x) {
  12. if (fabs(x) < 1e-9) return 1.0; // x=0付近の極限処理
  13. return sin(x) / x;
  14. }
  15.  
  16. // 導関数の真値: y' = (x*cos(x) - sin(x)) / x^2
  17. double df_true(double x) {
  18. if (fabs(x) < 1e-9) return 0.0;
  19. return (x * cos(x) - sin(x)) / (x * x);
  20. }
  21.  
  22. // --- (1) 微分の実行関数 (5等分, 10等分用) ---
  23. void run_differentiation(int N) {
  24. double x_start = 2.0;
  25. double x_end = 4.0;
  26. double h = (x_end - x_start) / N;
  27. int num_points = N + 1;
  28.  
  29. double x[100];
  30. double y[100];
  31. double dy_3pt[100];
  32. double dy_5pt[100];
  33.  
  34. printf("\n======================================================\n");
  35. printf(" ★ 微分課題: %d 等分 (h = %.4f)\n", N, h);
  36. printf("======================================================\n");
  37.  
  38. // データの作成
  39. for (int i = 0; i < num_points; i++) {
  40. x[i] = x_start + i * h;
  41. y[i] = f(x[i]);
  42. }
  43.  
  44. // 微係数の計算
  45. for (int i = 0; i < num_points; i++) {
  46. // --- 3点微分公式 ---
  47. if (i == 0) {
  48. // 前進差分
  49. dy_3pt[i] = (-3*y[i] + 4*y[i+1] - y[i+2]) / (2*h);
  50. } else if (i == num_points - 1) {
  51. // 後退差分
  52. dy_3pt[i] = (y[i-2] - 4*y[i-1] + 3*y[i]) / (2*h);
  53. } else {
  54. // 中央差分
  55. dy_3pt[i] = (y[i+1] - y[i-1]) / (2*h);
  56. }
  57.  
  58. // --- 5点微分公式 ---
  59. if (i == 0) {
  60. // 端点 (x1)
  61. dy_5pt[i] = (-11*y[i] + 18*y[i+1] - 9*y[i+2] + 2*y[i+3]) / (6*h);
  62. } else if (i == 1) {
  63. // 端点の隣 (x2)
  64. dy_5pt[i] = (-2*y[i-1] - 3*y[i] + 6*y[i+1] - y[i+2]) / (6*h);
  65. } else if (i == num_points - 2) {
  66. // 終点の隣 (xn-1)
  67. dy_5pt[i] = (y[i-2] - 6*y[i-1] + 3*y[i] + 2*y[i+1]) / (6*h);
  68. } else if (i == num_points - 1) {
  69. // 終点 (xn)
  70. dy_5pt[i] = (-2*y[i-3] + 9*y[i-2] - 18*y[i-1] + 11*y[i]) / (6*h);
  71. } else {
  72. // 中央
  73. dy_5pt[i] = (y[i-2] - 8*y[i-1] + 8*y[i+1] - y[i+2]) / (12*h);
  74. }
  75. }
  76.  
  77. // 結果表示
  78. printf(" x y(x) 3点公式 5点公式 真値 3点誤差 5点誤差\n");
  79. printf("-------------------------------------------------------------------------\n");
  80. for (int i = 0; i < num_points; i++) {
  81. double true_val = df_true(x[i]);
  82. printf("%6.2f %8.5f %9.5f %9.5f %9.5f %10.2e %10.2e\n",
  83. x[i], y[i], dy_3pt[i], dy_5pt[i], true_val,
  84. fabs(dy_3pt[i] - true_val), fabs(dy_5pt[i] - true_val));
  85. }
  86. }
  87.  
  88. // --- (2) 積分の実行関数 (4等分, 10等分用) ---
  89. void run_integration(int N) {
  90. double x_start = 2.0;
  91. double x_end = 4.0;
  92. double h = (x_end - x_start) / N;
  93. int num_points = N + 1;
  94.  
  95. double x[100];
  96. double y[100];
  97.  
  98. printf("\n\n======================================================\n");
  99. printf(" ★ 積分課題: %d 等分 (h = %.4f)\n", N, h);
  100. printf("======================================================\n");
  101.  
  102. // データの作成と表示 (離散データを確認するため)
  103. printf(" [使用する離散データ]\n");
  104. for (int i = 0; i < num_points; i++) {
  105. x[i] = x_start + i * h;
  106. y[i] = f(x[i]);
  107. printf(" x[%d]=%.2f, y[%d]=%.5f\n", i, x[i], i, y[i]);
  108. }
  109.  
  110. // 1. 長方形公式 (左端基準と仮定: y0 + ... + yn-1)
  111. double S_rect = 0.0;
  112. for (int j = 0; j < N; j++) {
  113. S_rect += h * y[j];
  114. }
  115.  
  116. // 2. 台形公式
  117. double S_trap = 0.0;
  118. for (int j = 0; j < N; j++) {
  119. S_trap += h * (y[j] + y[j+1]) / 2.0;
  120. }
  121.  
  122. // 3. シンプソンの公式
  123. double S_simp = 0.0;
  124. if (N % 2 == 0) { // 偶数分割のみ適用可能
  125. double sum_odd = 0.0;
  126. double sum_even = 0.0;
  127.  
  128. for (int i = 1; i < N; i++) {
  129. if (i % 2 != 0) sum_odd += y[i]; // y1, y3...
  130. else sum_even += y[i]; // y2, y4...
  131. }
  132. S_simp = (h / 3.0) * (y[0] + y[N] + 4.0 * sum_odd + 2.0 * sum_even);
  133. } else {
  134. printf(" (※分割数N=%d は偶数ではないため、シンプソンの公式は適用できません)\n", N);
  135. }
  136.  
  137. // 結果表示
  138. printf("\n [積分値の比較]\n");
  139. printf(" 長方形公式 : %.8f\n", S_rect);
  140. printf(" 台形公式 : %.8f\n", S_trap);
  141. if(N % 2 == 0) {
  142. printf(" シンプソン法 : %.8f\n", S_simp);
  143. }
  144.  
  145. double true_integral = 0.1527901621;
  146. printf(" (参考真値) : %.8f\n", true_integral);
  147. }
  148.  
  149. int main() {
  150. // 1. 微分の課題 (5等分, 10等分)
  151. run_differentiation(5);
  152. run_differentiation(10);
  153.  
  154. // 2. 積分の課題 (4等分, 10等分)
  155. run_integration(4);
  156. run_integration(10);
  157.  
  158. return 0;
  159. }
  160.  
Success #stdin #stdout 0s 5320KB
stdin
Standard input is empty
stdout
======================================================
 ★ 微分課題: 5 等分 (h = 0.4000)
======================================================
   x      y(x)     3点公式    5点公式     真値       3点誤差     5点誤差
-------------------------------------------------------------------------
  2.00   0.45465   -0.44727   -0.43683   -0.43540    1.19e-02    1.43e-03
  2.40   0.28144   -0.41876   -0.42398   -0.42452    5.75e-03    5.35e-04
  2.80   0.11964   -0.37461   -0.37915   -0.37924    4.63e-03    8.85e-05
  3.20  -0.01824   -0.30320   -0.30622   -0.30627    3.07e-03    4.90e-05
  3.60  -0.12292   -0.21370   -0.21587   -0.21495    1.26e-03    9.11e-04
  4.00  -0.18920   -0.11769   -0.11336   -0.11611    1.58e-03    2.75e-03

======================================================
 ★ 微分課題: 10 等分 (h = 0.2000)
======================================================
   x      y(x)     3点公式    5点公式     真値       3点誤差     5点誤差
-------------------------------------------------------------------------
  2.00   0.45465   -0.43849   -0.43551   -0.43540    3.09e-03    1.13e-04
  2.20   0.36750   -0.43301   -0.43450   -0.43455    1.53e-03    4.16e-05
  2.40   0.28144   -0.42307   -0.42451   -0.42452    1.44e-03    7.47e-06
  2.60   0.19827   -0.40451   -0.40582   -0.40583    1.32e-03    6.63e-06
  2.80   0.11964   -0.37807   -0.37923   -0.37924    1.16e-03    5.59e-06
  3.00   0.04704   -0.34470   -0.34567   -0.34568    9.76e-04    4.39e-06
  3.20  -0.01824   -0.30550   -0.30626   -0.30627    7.69e-04    3.09e-06
  3.40  -0.07516   -0.26170   -0.26225   -0.26225    5.46e-04    1.71e-06
  3.60  -0.12292   -0.21464   -0.21495   -0.21495    3.14e-04    3.01e-07
  3.80  -0.16102   -0.16570   -0.16589   -0.16578    8.13e-05    1.16e-04
  4.00  -0.18920   -0.11616   -0.11576   -0.11611    4.74e-05    3.48e-04


======================================================
 ★ 積分課題: 4 等分 (h = 0.5000)
======================================================
 [使用する離散データ]
  x[0]=2.00, y[0]=0.45465
  x[1]=2.50, y[1]=0.23939
  x[2]=3.00, y[2]=0.04704
  x[3]=3.50, y[3]=-0.10022
  x[4]=4.00, y[4]=-0.18920

 [積分値の比較]
  長方形公式 : 0.32042690
  台形公式   : 0.15946456
  シンプソン法 : 0.15269807
  (参考真値) : 0.15279016


======================================================
 ★ 積分課題: 10 等分 (h = 0.2000)
======================================================
 [使用する離散データ]
  x[0]=2.00, y[0]=0.45465
  x[1]=2.20, y[1]=0.36750
  x[2]=2.40, y[2]=0.28144
  x[3]=2.60, y[3]=0.19827
  x[4]=2.80, y[4]=0.11964
  x[5]=3.00, y[5]=0.04704
  x[6]=3.20, y[6]=-0.01824
  x[7]=3.40, y[7]=-0.07516
  x[8]=3.60, y[8]=-0.12292
  x[9]=3.80, y[9]=-0.16102
  x[10]=4.00, y[10]=-0.18920

 [積分値の比較]
  長方形公式 : 0.21823996
  台形公式   : 0.15385503
  シンプソン法 : 0.15278785
  (参考真値) : 0.15279016