#include <stdio.h>
#include <math.h>
#define N 4
#define MAX_ITER 150
#define EPS 1e-7
void print_system(double A[N][N], double b[N]);
void jacobi_solver(double A[N][N], double b[N]);
void gauss_seidel_solver(double A[N][N], double b[N]);
void verify_solution(double A[N][N], double b[N], double x[N]);
int main() {
double A[N][N] = {
{ 5.0, -1.0, -2.0, 0.0},
{ 0.0, 8.0, 1.0, 7.0},
{-2.0, -7.0, -4.0, 0.0},
{ 4.0, 0.0, -3.0, -25.0}
};
double b[N] = {-1.32, 14.41, 0.70, -0.03};
print_system(A, b);
printf("\n======================================================\n"); printf("======================================================\n"); jacobi_solver(A, b);
printf("\n======================================================\n"); printf("======================================================\n"); gauss_seidel_solver(A, b);
return 0;
}
void print_system(double A[N][N], double b[N]) {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
}
printf("] [x%d] = [ %6.2f ]\n", i
+ 1, b
[i
]); }
}
void jacobi_solver(double A[N][N], double b[N]) {
double x[N] = {0.0, 0.0, 0.0, 0.0};
double x_new[N];
int converged = 0;
printf("計算回数\t残差2乗和\t\tx1\t\tx2\t\tx3\t\tx4\n"); printf("------------------------------------------------------------------------\n");
for (int k = 1; k <= MAX_ITER; k++) {
for (int i = 0; i < N; i++) {
double sum = 0.0;
for (int j = 0; j < N; j++) {
if (j != i) {
sum += A[i][j] * x[j];
}
}
x_new[i] = (b[i] - sum) / A[i][i];
}
double rss = 0.0;
for (int i = 0; i < N; i++) {
rss
+= pow(x_new
[i
] - x
[i
], 2); }
printf("%d\t\t%.2e\t\t%.5f\t%.5f\t%.5f\t%.5f\n", k
, rss
, x_new
[0], x_new
[1], x_new
[2], x_new
[3]);
for (int i = 0; i < N; i++) {
x[i] = x_new[i];
}
if (rss < EPS) {
printf("\n>> 収束判定条件を満足しました(計算回数: %d回)\n", k
); converged = 1;
break;
}
}
if (!converged) {
printf("\n警告: 指定された計算回数以内に収束しませんでした。\n"); }
printf("\n=== 最終解 (ヤコビの反復法) ===\n"); for (int i = 0; i < N; i++) {
printf("x[%d] = %10.6f\n", i
+ 1, x
[i
]); }
verify_solution(A, b, x);
}
void gauss_seidel_solver(double A[N][N], double b[N]) {
double x[N] = {0.0, 0.0, 0.0, 0.0};
double x_old[N];
int converged = 0;
printf("回数 残差2乗和\t\tx1\t\tx2\t\tx3\t\tx4\n"); printf("------------------------------------------------------------------------\n");
for (int k = 1; k <= MAX_ITER; k++) {
for (int i = 0; i < N; i++) {
x_old[i] = x[i];
}
for (int i = 0; i < N; i++) {
double sum = 0.0;
for (int j = 0; j < N; j++) {
if (j != i) {
sum += A[i][j] * x[j];
}
}
x[i] = (b[i] - sum) / A[i][i];
}
double rss = 0.0;
for (int i = 0; i < N; i++) {
rss
+= pow(x
[i
] - x_old
[i
], 2); }
printf("%d \t%.2e\t\t%.4f\t%.4f\t%.4f\t%.4f\n", k
, rss
, x
[0], x
[1], x
[2], x
[3]);
if (rss < EPS) {
printf("\n>> 収束判定条件を満足しました(計算回数: %d回)\n", k
); converged = 1;
break;
}
}
if (!converged) {
printf("\n警告: 指定された計算回数以内に収束しませんでした。\n"); }
printf("\n=== 最終解 (ガウス・ザイデル法) ===\n"); for (int i = 0; i < N; i++) {
printf("x[%d] = %10.6f\n", i
+ 1, x
[i
]); }
verify_solution(A, b, x);
}
void verify_solution(double A[N][N], double b[N], double x[N]) {
printf("\n--- コード内での解の確認(検算: Ax == b) ---\n"); for (int i = 0; i < N; i++) {
double lhs_calc = 0.0;
for (int j = 0; j < N; j++) {
lhs_calc += A[i][j] * x[j];
}
double error = lhs_calc - b[i];
printf("%d行目: 計算値 Ax = %10.5f | 設定値 b = %10.5f | 誤差 = %e\n", i + 1, lhs_calc, b[i], error);
}
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxtYXRoLmg+CgojZGVmaW5lIE4gNAojZGVmaW5lIE1BWF9JVEVSIDE1MAojZGVmaW5lIEVQUyAxZS03Cgp2b2lkIHByaW50X3N5c3RlbShkb3VibGUgQVtOXVtOXSwgZG91YmxlIGJbTl0pOwp2b2lkIGphY29iaV9zb2x2ZXIoZG91YmxlIEFbTl1bTl0sIGRvdWJsZSBiW05dKTsKdm9pZCBnYXVzc19zZWlkZWxfc29sdmVyKGRvdWJsZSBBW05dW05dLCBkb3VibGUgYltOXSk7CnZvaWQgdmVyaWZ5X3NvbHV0aW9uKGRvdWJsZSBBW05dW05dLCBkb3VibGUgYltOXSwgZG91YmxlIHhbTl0pOwoKaW50IG1haW4oKSB7CiAgICBkb3VibGUgQVtOXVtOXSA9IHsKICAgICAgICB7IDUuMCwgLTEuMCwgLTIuMCwgIDAuMH0sCiAgICAgICAgeyAwLjAsICA4LjAsICAxLjAsICA3LjB9LAogICAgICAgIHstMi4wLCAtNy4wLCAtNC4wLCAgMC4wfSwKICAgICAgICB7IDQuMCwgIDAuMCwgLTMuMCwgLTI1LjB9CiAgICB9OwogICAgZG91YmxlIGJbTl0gPSB7LTEuMzIsIDE0LjQxLCAwLjcwLCAtMC4wM307CgogICAgcHJpbnRfc3lzdGVtKEEsIGIpOwogICAgCiAgICBwcmludGYoIlxuPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4iKTsKICAgIHByaW50ZigiICAgICAgICAgICAgICAgMS4g44Ok44Kz44OT44Gu5Y+N5b6p5rOVXG4iKTsKICAgIHByaW50ZigiPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4iKTsKICAgIGphY29iaV9zb2x2ZXIoQSwgYik7CgogICAgcHJpbnRmKCJcbj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuIik7CiAgICBwcmludGYoIiAgICAgICAgICAgICAgIDIuIOOCrOOCpuOCueODu+OCtuOCpOODh+ODq+azlVxuIik7CiAgICBwcmludGYoIj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuIik7CiAgICBnYXVzc19zZWlkZWxfc29sdmVyKEEsIGIpOwoKICAgIHJldHVybiAwOwp9Cgp2b2lkIHByaW50X3N5c3RlbShkb3VibGUgQVtOXVtOXSwgZG91YmxlIGJbTl0pIHsKICAgIHByaW50Zigi5a++6KeS5YSq5L2N5YyW44GX44Gf6YCj56uL5LiA5qyh5pa556iL5byPOlxuIik7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IE47IGkrKykgewogICAgICAgIHByaW50ZigiWyAiKTsKICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IE47IGorKykgewogICAgICAgICAgICBwcmludGYoIiU2LjFmICIsIEFbaV1bal0pOwogICAgICAgIH0KICAgICAgICBwcmludGYoIl0gW3glZF0gPSBbICU2LjJmIF1cbiIsIGkgKyAxLCBiW2ldKTsKICAgIH0KfQoKdm9pZCBqYWNvYmlfc29sdmVyKGRvdWJsZSBBW05dW05dLCBkb3VibGUgYltOXSkgewogICAgZG91YmxlIHhbTl0gPSB7MC4wLCAwLjAsIDAuMCwgMC4wfTsKICAgIGRvdWJsZSB4X25ld1tOXTsKICAgIGludCBjb252ZXJnZWQgPSAwOwoKICAgIHByaW50Zigi6KiI566X5Zue5pWwXHTmrovlt64y5LmX5ZKMXHRcdHgxXHRcdHgyXHRcdHgzXHRcdHg0XG4iKTsKICAgIHByaW50ZigiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iKTsKCiAgICBmb3IgKGludCBrID0gMTsgayA8PSBNQVhfSVRFUjsgaysrKSB7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBOOyBpKyspIHsKICAgICAgICAgICAgZG91YmxlIHN1bSA9IDAuMDsKICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBOOyBqKyspIHsKICAgICAgICAgICAgICAgIGlmIChqICE9IGkpIHsKICAgICAgICAgICAgICAgICAgICBzdW0gKz0gQVtpXVtqXSAqIHhbal07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgeF9uZXdbaV0gPSAoYltpXSAtIHN1bSkgLyBBW2ldW2ldOwogICAgICAgIH0KCiAgICAgICAgZG91YmxlIHJzcyA9IDAuMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IE47IGkrKykgewogICAgICAgICAgICByc3MgKz0gcG93KHhfbmV3W2ldIC0geFtpXSwgMik7CiAgICAgICAgfQoKICAgICAgICBwcmludGYoIiVkXHRcdCUuMmVcdFx0JS41Zlx0JS41Zlx0JS41Zlx0JS41ZlxuIiwgaywgcnNzLCB4X25ld1swXSwgeF9uZXdbMV0sIHhfbmV3WzJdLCB4X25ld1szXSk7CgogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgTjsgaSsrKSB7CiAgICAgICAgICAgIHhbaV0gPSB4X25ld1tpXTsKICAgICAgICB9CgogICAgICAgIGlmIChyc3MgPCBFUFMpIHsKICAgICAgICAgICAgcHJpbnRmKCJcbj4+IOWPjuadn+WIpOWumuadoeS7tuOCkua6gOi2s+OBl+OBvuOBl+OBn++8iOioiOeul+WbnuaVsDogJWTlm57vvIlcbiIsIGspOwogICAgICAgICAgICBjb252ZXJnZWQgPSAxOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CgogICAgaWYgKCFjb252ZXJnZWQpIHsKICAgICAgICBwcmludGYoIlxu6K2m5ZGKOiDmjIflrprjgZXjgozjgZ/oqIjnrpflm57mlbDku6XlhoXjgavlj47mnZ/jgZfjgb7jgZvjgpPjgafjgZfjgZ/jgIJcbiIpOwogICAgfQoKICAgIHByaW50ZigiXG49PT0g5pyA57WC6KejICjjg6TjgrPjg5Pjga7lj43lvqnms5UpID09PVxuIik7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IE47IGkrKykgewogICAgICAgIHByaW50ZigieFslZF0gPSAlMTAuNmZcbiIsIGkgKyAxLCB4W2ldKTsKICAgIH0KCiAgICB2ZXJpZnlfc29sdXRpb24oQSwgYiwgeCk7Cn0KCnZvaWQgZ2F1c3Nfc2VpZGVsX3NvbHZlcihkb3VibGUgQVtOXVtOXSwgZG91YmxlIGJbTl0pIHsKICAgIGRvdWJsZSB4W05dID0gezAuMCwgMC4wLCAwLjAsIDAuMH07CiAgICBkb3VibGUgeF9vbGRbTl07CiAgICBpbnQgY29udmVyZ2VkID0gMDsKCiAgICBwcmludGYoIuWbnuaVsCAg5q6L5beuMuS5l+WSjFx0XHR4MVx0XHR4Mlx0XHR4M1x0XHR4NFxuIik7CiAgICBwcmludGYoIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuIik7CgogICAgZm9yIChpbnQgayA9IDE7IGsgPD0gTUFYX0lURVI7IGsrKykgewogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgTjsgaSsrKSB7CiAgICAgICAgICAgIHhfb2xkW2ldID0geFtpXTsKICAgICAgICB9CgogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgTjsgaSsrKSB7CiAgICAgICAgICAgIGRvdWJsZSBzdW0gPSAwLjA7CiAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgTjsgaisrKSB7CiAgICAgICAgICAgICAgICBpZiAoaiAhPSBpKSB7CiAgICAgICAgICAgICAgICAgICAgc3VtICs9IEFbaV1bal0gKiB4W2pdOyAKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICB4W2ldID0gKGJbaV0gLSBzdW0pIC8gQVtpXVtpXTsKICAgICAgICB9CgogICAgICAgIGRvdWJsZSByc3MgPSAwLjA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBOOyBpKyspIHsKICAgICAgICAgICAgcnNzICs9IHBvdyh4W2ldIC0geF9vbGRbaV0sIDIpOwogICAgICAgIH0KCiAgICAgICAgcHJpbnRmKCIlZCAgXHQlLjJlXHRcdCUuNGZcdCUuNGZcdCUuNGZcdCUuNGZcbiIsIGssIHJzcywgeFswXSwgeFsxXSwgeFsyXSwgeFszXSk7CgogICAgICAgIGlmIChyc3MgPCBFUFMpIHsKICAgICAgICAgICAgcHJpbnRmKCJcbj4+IOWPjuadn+WIpOWumuadoeS7tuOCkua6gOi2s+OBl+OBvuOBl+OBn++8iOioiOeul+WbnuaVsDogJWTlm57vvIlcbiIsIGspOwogICAgICAgICAgICBjb252ZXJnZWQgPSAxOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CgogICAgaWYgKCFjb252ZXJnZWQpIHsKICAgICAgICBwcmludGYoIlxu6K2m5ZGKOiDmjIflrprjgZXjgozjgZ/oqIjnrpflm57mlbDku6XlhoXjgavlj47mnZ/jgZfjgb7jgZvjgpPjgafjgZfjgZ/jgIJcbiIpOwogICAgfQoKICAgIHByaW50ZigiXG49PT0g5pyA57WC6KejICjjgqzjgqbjgrnjg7vjgrbjgqTjg4fjg6vms5UpID09PVxuIik7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IE47IGkrKykgewogICAgICAgIHByaW50ZigieFslZF0gPSAlMTAuNmZcbiIsIGkgKyAxLCB4W2ldKTsKICAgIH0KCiAgICB2ZXJpZnlfc29sdXRpb24oQSwgYiwgeCk7Cn0KCnZvaWQgdmVyaWZ5X3NvbHV0aW9uKGRvdWJsZSBBW05dW05dLCBkb3VibGUgYltOXSwgZG91YmxlIHhbTl0pIHsKICAgIHByaW50ZigiXG4tLS0g44Kz44O844OJ5YaF44Gn44Gu6Kej44Gu56K66KqN77yI5qSc566XOiBBeCA9PSBi77yJIC0tLVxuIik7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IE47IGkrKykgewogICAgICAgIGRvdWJsZSBsaHNfY2FsYyA9IDAuMDsKICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IE47IGorKykgewogICAgICAgICAgICBsaHNfY2FsYyArPSBBW2ldW2pdICogeFtqXTsKICAgICAgICB9CiAgICAgICAgZG91YmxlIGVycm9yID0gbGhzX2NhbGMgLSBiW2ldOwogICAgICAgIHByaW50ZigiJWTooYznm646IOioiOeul+WApCBBeCA9ICUxMC41ZiB8IOioreWumuWApCBiID0gJTEwLjVmIHwg6Kqk5beuID0gJWVcbiIsIAogICAgICAgICAgICAgICBpICsgMSwgbGhzX2NhbGMsIGJbaV0sIGVycm9yKTsKICAgIH0KfQ==