#include <stdio.h>
#include <math.h>
// 円周率の定義
#define PI 3.14159265358979323846
// 対象の関数 f(x) = 1 / (2 + cos(pi * x))
double f(double x) {
return 1.0 / (2.0 + cos(PI
* x
)); }
// ラグランジュ基底多項式 l_j(x) の計算
double lagrange_basis(int j, double x, const double nodes[], int n) {
double l = 1.0;
for (int k = 0; k <= n; k++) {
if (k != j) {
l *= (x - nodes[k]) / (nodes[j] - nodes[k]);
}
}
return l;
}
// 補間多項式 P_n(x) の値の計算
double interpolant(double x, const double nodes[], const double values[], int n) {
double p = 0.0;
for (int j = 0; j <= n; j++) {
p += values[j] * lagrange_basis(j, x, nodes, n);
}
return p;
}
int main(void) {
int i, j, k;
int n = 7; // 7次のチェビシェフ補間(節点数 8個)
double nodes[8];
double values[8];
// 0. 積分の真値を高精度(十分な分割数による数値積分)で近似
int ref_steps = 100000;
double a = -1.0, b = 1.0;
double h_ref = (b - a) / ref_steps;
double true_integral = 0.5 * (f(a) + f(b));
for (i = 1; i < ref_steps; i++) {
true_integral += f(a + i * h_ref);
}
true_integral *= h_ref;
printf("積分の真値 (近似): %.12f\n\n", true_integral
);
// ==========================================
// (1) 7次のチェビシェフ補間の節点と値の計算
// ==========================================
for (k = 0; k <= n; k++) {
// チェビシェフ節点: x_k = cos((2k+1)pi / (2(n+1)))
nodes
[k
] = cos((2.0 * k
+ 1.0) * PI
/ (2.0 * (n
+ 1.0))); values[k] = f(nodes[k]);
}
printf("--- (1) 7次チェビシェフ補間の節点 ---\n"); for (k = 0; k <= n; k++) {
printf("x_%d = %10.6f, f(x_%d) = %10.6f\n", k
, nodes
[k
], k
, values
[k
]); }
// ==========================================
// (2) 補間多項式の [-1, 1] での積分と真値との誤差
// ==========================================
// 補間多項式を十分に細かい分割(例: 1000分割)で数値積分する
int interp_steps = 1000;
double h_interp = (b - a) / interp_steps;
double poly_integral = 0.5 * (interpolant(a, nodes, values, n) + interpolant(b, nodes, values, n));
for (i = 1; i < interp_steps; i++) {
double xi = a + i * h_interp;
poly_integral += interpolant(xi, nodes, values, n);
}
poly_integral *= h_interp;
double error_interp
= fabs(poly_integral
- true_integral
);
printf("--- (2) 補間多項式の積分と誤差 ---\n"); printf("補間多項式の積分値: %.12f\n", poly_integral
); printf("真値との誤差 : %.2e\n\n", error_interp
);
// ==========================================
// (3) 7分割・8分割の台形則による数値積分
// ==========================================
// 7分割の台形則
int n7 = 7;
double h7 = (b - a) / n7;
double trap_7 = 0.5 * (f(-1.0) + f(1.0));
for (i = 1; i < n7; i++) {
trap_7 += f(-1.0 + i * h7);
}
trap_7 *= h7;
double err_trap_7
= fabs(trap_7
- true_integral
);
// 8分割の台形則
int n8 = 8;
double h8 = (b - a) / n8;
double trap_8 = 0.5 * (f(-1.0) + f(1.0));
for (i = 1; i < n8; i++) {
trap_8 += f(-1.0 + i * h8);
}
trap_8 *= h8;
double err_trap_8
= fabs(trap_8
- true_integral
);
printf("--- (3) 台形則による数値積分と誤差 ---\n"); printf("7分割の台形則 積分値: %.12f, 誤差: %.2e\n", trap_7
, err_trap_7
); printf("8分割の台形則 積分値: %.12f, 誤差: %.2e\n", trap_8
, err_trap_8
);
return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxtYXRoLmg+CgovLyDlhoblkajnjofjga7lrprnvqkKI2RlZmluZSBQSSAzLjE0MTU5MjY1MzU4OTc5MzIzODQ2CgovLyDlr77osaHjga7plqLmlbAgZih4KSA9IDEgLyAoMiArIGNvcyhwaSAqIHgpKQpkb3VibGUgZihkb3VibGUgeCkgewogICAgcmV0dXJuIDEuMCAvICgyLjAgKyBjb3MoUEkgKiB4KSk7Cn0KCi8vIOODqeOCsOODqeODs+OCuOODpeWfuuW6leWkmumgheW8jyBsX2ooeCkg44Gu6KiI566XCmRvdWJsZSBsYWdyYW5nZV9iYXNpcyhpbnQgaiwgZG91YmxlIHgsIGNvbnN0IGRvdWJsZSBub2Rlc1tdLCBpbnQgbikgewogICAgZG91YmxlIGwgPSAxLjA7CiAgICBmb3IgKGludCBrID0gMDsgayA8PSBuOyBrKyspIHsKICAgICAgICBpZiAoayAhPSBqKSB7CiAgICAgICAgICAgIGwgKj0gKHggLSBub2Rlc1trXSkgLyAobm9kZXNbal0gLSBub2Rlc1trXSk7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGw7Cn0KCi8vIOijnOmWk+WkmumgheW8jyBQX24oeCkg44Gu5YCk44Gu6KiI566XCmRvdWJsZSBpbnRlcnBvbGFudChkb3VibGUgeCwgY29uc3QgZG91YmxlIG5vZGVzW10sIGNvbnN0IGRvdWJsZSB2YWx1ZXNbXSwgaW50IG4pIHsKICAgIGRvdWJsZSBwID0gMC4wOwogICAgZm9yIChpbnQgaiA9IDA7IGogPD0gbjsgaisrKSB7CiAgICAgICAgcCArPSB2YWx1ZXNbal0gKiBsYWdyYW5nZV9iYXNpcyhqLCB4LCBub2Rlcywgbik7CiAgICB9CiAgICByZXR1cm4gcDsKfQoKaW50IG1haW4odm9pZCkgewogICAgaW50IGksIGosIGs7CiAgICBpbnQgbiA9IDc7IC8vIDfmrKHjga7jg4Hjgqfjg5Pjgrfjgqfjg5Xoo5zplpPvvIjnr4DngrnmlbAgOOWAi++8iQogICAgZG91YmxlIG5vZGVzWzhdOwogICAgZG91YmxlIHZhbHVlc1s4XTsKCiAgICAvLyAwLiDnqY3liIbjga7nnJ/lgKTjgpLpq5jnsr7luqbvvIjljYHliIbjgarliIblibLmlbDjgavjgojjgovmlbDlgKTnqY3liIbvvInjgafov5HkvLwKICAgIGludCByZWZfc3RlcHMgPSAxMDAwMDA7CiAgICBkb3VibGUgYSA9IC0xLjAsIGIgPSAxLjA7CiAgICBkb3VibGUgaF9yZWYgPSAoYiAtIGEpIC8gcmVmX3N0ZXBzOwogICAgZG91YmxlIHRydWVfaW50ZWdyYWwgPSAwLjUgKiAoZihhKSArIGYoYikpOwogICAgZm9yIChpID0gMTsgaSA8IHJlZl9zdGVwczsgaSsrKSB7CiAgICAgICAgdHJ1ZV9pbnRlZ3JhbCArPSBmKGEgKyBpICogaF9yZWYpOwogICAgfQogICAgdHJ1ZV9pbnRlZ3JhbCAqPSBoX3JlZjsKICAgIHByaW50Zigi56mN5YiG44Gu55yf5YCkICjov5HkvLwpOiAlLjEyZlxuXG4iLCB0cnVlX2ludGVncmFsKTsKCiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAgIC8vICgxKSA35qyh44Gu44OB44Kn44OT44K344Kn44OV6KOc6ZaT44Gu56+A54K544Go5YCk44Gu6KiI566XCiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAgIGZvciAoayA9IDA7IGsgPD0gbjsgaysrKSB7CiAgICAgICAgLy8g44OB44Kn44OT44K344Kn44OV56+A54K5OiB4X2sgPSBjb3MoKDJrKzEpcGkgLyAoMihuKzEpKSkKICAgICAgICBub2Rlc1trXSA9IGNvcygoMi4wICogayArIDEuMCkgKiBQSSAvICgyLjAgKiAobiArIDEuMCkpKTsKICAgICAgICB2YWx1ZXNba10gPSBmKG5vZGVzW2tdKTsKICAgIH0KCiAgICBwcmludGYoIi0tLSAoMSkgN+asoeODgeOCp+ODk+OCt+OCp+ODleijnOmWk+OBruevgOeCuSAtLS1cbiIpOwogICAgZm9yIChrID0gMDsgayA8PSBuOyBrKyspIHsKICAgICAgICBwcmludGYoInhfJWQgPSAlMTAuNmYsIGYoeF8lZCkgPSAlMTAuNmZcbiIsIGssIG5vZGVzW2tdLCBrLCB2YWx1ZXNba10pOwogICAgfQogICAgcHJpbnRmKCJcbiIpOwoKICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogICAgLy8gKDIpIOijnOmWk+WkmumgheW8j+OBriBbLTEsIDFdIOOBp+OBruepjeWIhuOBqOecn+WApOOBqOOBruiqpOW3rgogICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgICAvLyDoo5zplpPlpJrpoIXlvI/jgpLljYHliIbjgavntLDjgYvjgYTliIblibLvvIjkvos6IDEwMDDliIblibLvvInjgafmlbDlgKTnqY3liIbjgZnjgosKICAgIGludCBpbnRlcnBfc3RlcHMgPSAxMDAwOwogICAgZG91YmxlIGhfaW50ZXJwID0gKGIgLSBhKSAvIGludGVycF9zdGVwczsKICAgIGRvdWJsZSBwb2x5X2ludGVncmFsID0gMC41ICogKGludGVycG9sYW50KGEsIG5vZGVzLCB2YWx1ZXMsIG4pICsgaW50ZXJwb2xhbnQoYiwgbm9kZXMsIHZhbHVlcywgbikpOwogICAgZm9yIChpID0gMTsgaSA8IGludGVycF9zdGVwczsgaSsrKSB7CiAgICAgICAgZG91YmxlIHhpID0gYSArIGkgKiBoX2ludGVycDsKICAgICAgICBwb2x5X2ludGVncmFsICs9IGludGVycG9sYW50KHhpLCBub2RlcywgdmFsdWVzLCBuKTsKICAgIH0KICAgIHBvbHlfaW50ZWdyYWwgKj0gaF9pbnRlcnA7CgogICAgZG91YmxlIGVycm9yX2ludGVycCA9IGZhYnMocG9seV9pbnRlZ3JhbCAtIHRydWVfaW50ZWdyYWwpOwoKICAgIHByaW50ZigiLS0tICgyKSDoo5zplpPlpJrpoIXlvI/jga7nqY3liIbjgajoqqTlt64gLS0tXG4iKTsKICAgIHByaW50Zigi6KOc6ZaT5aSa6aCF5byP44Gu56mN5YiG5YCkOiAlLjEyZlxuIiwgcG9seV9pbnRlZ3JhbCk7CiAgICBwcmludGYoIuecn+WApOOBqOOBruiqpOW3riAgICAgIDogJS4yZVxuXG4iLCBlcnJvcl9pbnRlcnApOwoKICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogICAgLy8gKDMpIDfliIblibLjg7s45YiG5Ymy44Gu5Y+w5b2i5YmH44Gr44KI44KL5pWw5YCk56mN5YiGCiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAgIC8vIDfliIblibLjga7lj7DlvaLliYcKICAgIGludCBuNyA9IDc7CiAgICBkb3VibGUgaDcgPSAoYiAtIGEpIC8gbjc7CiAgICBkb3VibGUgdHJhcF83ID0gMC41ICogKGYoLTEuMCkgKyBmKDEuMCkpOwogICAgZm9yIChpID0gMTsgaSA8IG43OyBpKyspIHsKICAgICAgICB0cmFwXzcgKz0gZigtMS4wICsgaSAqIGg3KTsKICAgIH0KICAgIHRyYXBfNyAqPSBoNzsKICAgIGRvdWJsZSBlcnJfdHJhcF83ID0gZmFicyh0cmFwXzcgLSB0cnVlX2ludGVncmFsKTsKCiAgICAvLyA45YiG5Ymy44Gu5Y+w5b2i5YmHCiAgICBpbnQgbjggPSA4OwogICAgZG91YmxlIGg4ID0gKGIgLSBhKSAvIG44OwogICAgZG91YmxlIHRyYXBfOCA9IDAuNSAqIChmKC0xLjApICsgZigxLjApKTsKICAgIGZvciAoaSA9IDE7IGkgPCBuODsgaSsrKSB7CiAgICAgICAgdHJhcF84ICs9IGYoLTEuMCArIGkgKiBoOCk7CiAgICB9CiAgICB0cmFwXzggKj0gaDg7CiAgICBkb3VibGUgZXJyX3RyYXBfOCA9IGZhYnModHJhcF84IC0gdHJ1ZV9pbnRlZ3JhbCk7CgogICAgcHJpbnRmKCItLS0gKDMpIOWPsOW9ouWJh+OBq+OCiOOCi+aVsOWApOepjeWIhuOBqOiqpOW3riAtLS1cbiIpOwogICAgcHJpbnRmKCI35YiG5Ymy44Gu5Y+w5b2i5YmHIOepjeWIhuWApDogJS4xMmYsIOiqpOW3rjogJS4yZVxuIiwgdHJhcF83LCBlcnJfdHJhcF83KTsKICAgIHByaW50ZigiOOWIhuWJsuOBruWPsOW9ouWJhyDnqY3liIblgKQ6ICUuMTJmLCDoqqTlt646ICUuMmVcbiIsIHRyYXBfOCwgZXJyX3RyYXBfOCk7CgogICAgcmV0dXJuIDA7Cn0=