#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] = {
{10.0, 2.0, -3.0, 1.0},
{ 1.0, 9.0, 2.0, -1.0},
{ 2.0, -1.0, 8.0, 3.0},
{ 3.0, 2.0, 1.0, 7.0}
};
double b[N] = {13.0, -5.0, 41.0, 35.0};
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%.2e \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("回数\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++) {
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%.5f \t%.5f \t%.5f \t%.5f \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+CgojZGVmaW5lIE4gNAojZGVmaW5lIE1BWF9JVEVSIDE1MAojZGVmaW5lIEVQUyAxZS03Cgp2b2lkIHByaW50X3N5c3RlbShkb3VibGUgQVtOXVtOXSwgZG91YmxlIGJbTl0pOwp2b2lkIGphY29iaV9zb2x2ZXIoZG91YmxlIEFbTl1bTl0sIGRvdWJsZSBiW05dKTsKdm9pZCBnYXVzc19zZWlkZWxfc29sdmVyKGRvdWJsZSBBW05dW05dLCBkb3VibGUgYltOXSk7CnZvaWQgdmVyaWZ5X3NvbHV0aW9uKGRvdWJsZSBBW05dW05dLCBkb3VibGUgYltOXSwgZG91YmxlIHhbTl0pOwoKaW50IG1haW4oKSB7CiAgICBkb3VibGUgQVtOXVtOXSA9IHsKICAgICAgICB7MTAuMCwgIDIuMCwgLTMuMCwgIDEuMH0sCiAgICAgICAgeyAxLjAsICA5LjAsICAyLjAsIC0xLjB9LAogICAgICAgIHsgMi4wLCAtMS4wLCAgOC4wLCAgMy4wfSwKICAgICAgICB7IDMuMCwgIDIuMCwgIDEuMCwgIDcuMH0KICAgIH07CiAgICBkb3VibGUgYltOXSA9IHsxMy4wLCAtNS4wLCA0MS4wLCAzNS4wfTsKCiAgICBwcmludF9zeXN0ZW0oQSwgYik7CiAgICAKICAgIHByaW50ZigiXG49PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiIpOwogICAgcHJpbnRmKCIgMS4g44Ok44Kz44OT44Gu5Y+N5b6p5rOVXG4iKTsKICAgIHByaW50ZigiPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4iKTsKICAgIGphY29iaV9zb2x2ZXIoQSwgYik7CgogICAgcHJpbnRmKCJcbj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuIik7CiAgICBwcmludGYoIiAyLiDjgqzjgqbjgrnjg7vjgrbjgqTjg4fjg6vms5VcbiIpOwogICAgcHJpbnRmKCI9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiIpOwogICAgZ2F1c3Nfc2VpZGVsX3NvbHZlcihBLCBiKTsKCiAgICByZXR1cm4gMDsKfQoKdm9pZCBwcmludF9zeXN0ZW0oZG91YmxlIEFbTl1bTl0sIGRvdWJsZSBiW05dKSB7CiAgICBwcmludGYoIuWvvuinkuWEquS9jeWMluW+jOOBruaWueeoi+W8jzpcbiIpOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBOOyBpKyspIHsKICAgICAgICBwcmludGYoIlsgIik7CiAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBOOyBqKyspIHsKICAgICAgICAgICAgcHJpbnRmKCIlNi4xZiAiLCBBW2ldW2pdKTsKICAgICAgICB9CiAgICAgICAgcHJpbnRmKCJdIFt4JWRdID0gWyAlNi4yZiBdXG4iLCBpICsgMSwgYltpXSk7CiAgICB9Cn0KCnZvaWQgamFjb2JpX3NvbHZlcihkb3VibGUgQVtOXVtOXSwgZG91YmxlIGJbTl0pIHsKICAgIGRvdWJsZSB4W05dID0gezAuMCwgMC4wLCAwLjAsIDAuMH07CiAgICBkb3VibGUgeF9uZXdbTl07CiAgICBpbnQgY29udmVyZ2VkID0gMDsKCiAgICBwcmludGYoIuWbnuaVsFx05q6L5beuMuS5l+WSjFx0XHR4MVx0XHR4Mlx0XHR4M1x0XHR4NFxuIik7CiAgICBwcmludGYoIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuIik7CgogICAgZm9yIChpbnQgayA9IDE7IGsgPD0gTUFYX0lURVI7IGsrKykgewogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgTjsgaSsrKSB7CiAgICAgICAgICAgIGRvdWJsZSBzdW0gPSAwLjA7CiAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgTjsgaisrKSB7CiAgICAgICAgICAgICAgICBpZiAoaiAhPSBpKSB7CiAgICAgICAgICAgICAgICAgICAgc3VtICs9IEFbaV1bal0gKiB4W2pdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHhfbmV3W2ldID0gKGJbaV0gLSBzdW0pIC8gQVtpXVtpXTsKICAgICAgICB9CgogICAgICAgIGRvdWJsZSByc3MgPSAwLjA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBOOyBpKyspIHsKICAgICAgICAgICAgcnNzICs9IHBvdyh4X25ld1tpXSAtIHhbaV0sIDIpOwogICAgICAgIH0KCiAgICAgICAgcHJpbnRmKCIlZCAgXHQlLjJlIFx0JS41ZiBcdCUuNWYgXHQlLjVmIFx0JS41ZiBcbiIsIGssIHJzcywgeF9uZXdbMF0sIHhfbmV3WzFdLCB4X25ld1syXSwgeF9uZXdbM10pOwoKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IE47IGkrKykgewogICAgICAgICAgICB4W2ldID0geF9uZXdbaV07CiAgICAgICAgfQoKICAgICAgICBpZiAocnNzIDwgRVBTKSB7CiAgICAgICAgICAgIHByaW50ZigiXG4+PiDlj47mnZ/liKTlrprmnaHku7bjgpLmuoDotrPjgZfjgb7jgZfjgZ/vvIjoqIjnrpflm57mlbA6ICVk5Zue77yJXG4iLCBrKTsKICAgICAgICAgICAgY29udmVyZ2VkID0gMTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQoKICAgIGlmICghY29udmVyZ2VkKSB7CiAgICAgICAgcHJpbnRmKCJcbuitpuWRijog5oyH5a6a44GV44KM44Gf6KiI566X5Zue5pWw5Lul5YaF44Gr5Y+O5p2f44GX44G+44Gb44KT44Gn44GX44Gf44CCXG4iKTsKICAgIH0KCiAgICBwcmludGYoIlxuPT09IOmAo+eri+aWueeoi+W8j+OBruacgOe1guinoyAo44Ok44Kz44OT44Gu5Y+N5b6p5rOVKSA9PT1cbiIpOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBOOyBpKyspIHsKICAgICAgICBwcmludGYoInhbJWRdID0gJTEwLjZmXG4iLCBpICsgMSwgeFtpXSk7CiAgICB9CgogICAgdmVyaWZ5X3NvbHV0aW9uKEEsIGIsIHgpOwp9Cgp2b2lkIGdhdXNzX3NlaWRlbF9zb2x2ZXIoZG91YmxlIEFbTl1bTl0sIGRvdWJsZSBiW05dKSB7CiAgICBkb3VibGUgeFtOXSA9IHswLjAsIDAuMCwgMC4wLCAwLjB9OwogICAgZG91YmxlIHhfb2xkW05dOwogICAgaW50IGNvbnZlcmdlZCA9IDA7CgogICAgcHJpbnRmKCLlm57mlbBcdOaui+W3rjLkuZflkoxcdFx0eDFcdFx0eDJcdFx0eDNcdFx0eDRcbiIpOwogICAgcHJpbnRmKCItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiIpOwoKICAgIGZvciAoaW50IGsgPSAxOyBrIDw9IE1BWF9JVEVSOyBrKyspIHsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IE47IGkrKykgewogICAgICAgICAgICB4X29sZFtpXSA9IHhbaV07CiAgICAgICAgfQoKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IE47IGkrKykgewogICAgICAgICAgICBkb3VibGUgc3VtID0gMC4wOwogICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IE47IGorKykgewogICAgICAgICAgICAgICAgaWYgKGogIT0gaSkgewogICAgICAgICAgICAgICAgICAgIHN1bSArPSBBW2ldW2pdICogeFtqXTsgCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgeFtpXSA9IChiW2ldIC0gc3VtKSAvIEFbaV1baV07CiAgICAgICAgfQoKICAgICAgICBkb3VibGUgcnNzID0gMC4wOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgTjsgaSsrKSB7CiAgICAgICAgICAgIHJzcyArPSBwb3coeFtpXSAtIHhfb2xkW2ldLCAyKTsKICAgICAgICB9CgogICAgICAgIHByaW50ZigiJWQgIFx0JS4yZSBcdCUuNWYgXHQlLjVmIFx0JS41ZiBcdCUuNWYgXG4iLCBrLCByc3MsIHhbMF0sIHhbMV0sIHhbMl0sIHhbM10pOwoKICAgICAgICBpZiAocnNzIDwgRVBTKSB7CiAgICAgICAgICAgIHByaW50ZigiXG4+PiDlj47mnZ/liKTlrprmnaHku7bjgpLmuoDotrPjgZfjgb7jgZfjgZ/vvIjoqIjnrpflm57mlbA6ICVk5Zue77yJXG4iLCBrKTsKICAgICAgICAgICAgY29udmVyZ2VkID0gMTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQoKICAgIGlmICghY29udmVyZ2VkKSB7CiAgICAgICAgcHJpbnRmKCJcbuitpuWRijog5oyH5a6a44GV44KM44Gf6KiI566X5Zue5pWw5Lul5YaF44Gr5Y+O5p2f44GX44G+44Gb44KT44Gn44GX44Gf44CCXG4iKTsKICAgIH0KCiAgICBwcmludGYoIlxuPT09IOmAo+eri+aWueeoi+W8j+OBruacgOe1guinoyAo44Ks44Km44K544O744K244Kk44OH44Or5rOVKSA9PT1cbiIpOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBOOyBpKyspIHsKICAgICAgICBwcmludGYoInhbJWRdID0gJTEwLjZmXG4iLCBpICsgMSwgeFtpXSk7CiAgICB9CgogICAgdmVyaWZ5X3NvbHV0aW9uKEEsIGIsIHgpOwp9Cgp2b2lkIHZlcmlmeV9zb2x1dGlvbihkb3VibGUgQVtOXVtOXSwgZG91YmxlIGJbTl0sIGRvdWJsZSB4W05dKSB7CiAgICBwcmludGYoIlxuLS0tIOaxguOBvuOBo+OBn+OCguOBruOBjOino+OBp+OBguOCi+eiuuiqje+8iOOCs+ODvOODieWGheOBp+OBruaknOeulzogQXggPT0gYu+8iSAtLS1cbiIpOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBOOyBpKyspIHsKICAgICAgICBkb3VibGUgbGhzX2NhbGMgPSAwLjA7CiAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBOOyBqKyspIHsKICAgICAgICAgICAgbGhzX2NhbGMgKz0gQVtpXVtqXSAqIHhbal07CiAgICAgICAgfQogICAgICAgIGRvdWJsZSBlcnJvciA9IGxoc19jYWxjIC0gYltpXTsKICAgICAgICBwcmludGYoIiVk6KGM55uuOiDoqIjnrpflgKQgQXggPSAlMTAuNWYgfCDoqK3lrprlgKQgYiA9ICUxMC41ZiB8IOiqpOW3riA9ICVlXG4iLCAKICAgICAgICAgICAgICAgaSArIDEsIGxoc19jYWxjLCBiW2ldLCBlcnJvcik7CiAgICB9Cn0=