#include <stdio.h>
#include <math.h>
#define SIZE 4 // 行列のサイズ
#define MAX_ITER 1000 // 最大反復回数
#define TOL 1e-6 // 収束判定の許容誤差
// QR分解を行うための関数(グラムシュミット直交化を使用)
void qr_decompose(double A[SIZE][SIZE], double Q[SIZE][SIZE], double R[SIZE][SIZE]) {
int i, j, k;
double norm;
for (i = 0; i < SIZE; i++) {
for (j = 0; j < SIZE; j++) {
Q[i][j] = 0.0;
R[i][j] = 0.0;
}
}
for (k = 0; k < SIZE; k++) {
for (i = 0; i < SIZE; i++) {
Q[i][k] = A[i][k];
}
for (j = 0; j < k; j++) {
R[j][k] = 0.0;
for (i = 0; i < SIZE; i++) {
R[j][k] += Q[i][j] * A[i][k];
}
for (i = 0; i < SIZE; i++) {
Q[i][k] -= R[j][k] * Q[i][j];
}
}
norm = 0.0;
for (i = 0; i < SIZE; i++) {
norm += Q[i][k] * Q[i][k];
}
for (i = 0; i < SIZE; i++) {
Q[i][k] /= R[k][k];
}
}
}
// QR法で固有値を計算する関数
int qr_algorithm(double A[SIZE][SIZE], double eigenvalues[SIZE]) {
double Q[SIZE][SIZE], R[SIZE][SIZE], A_next[SIZE][SIZE];
int i, j, k;
int iteration_count = 0;
for (k = 0; k < MAX_ITER; k++) {
iteration_count++;
// QR分解
qr_decompose(A, Q, R);
// 新しい行列 A = R * Q を計算
for (i = 0; i < SIZE; i++) {
for (j = 0; j < SIZE; j++) {
A_next[i][j] = 0.0;
for (int l = 0; l < SIZE; l++) {
A_next[i][j] += R[i][l] * Q[l][j];
}
}
}
// 収束判定
int converged = 1;
for (i = 0; i < SIZE; i++) {
if (fabs(A
[i
][i
] - A_next
[i
][i
]) > TOL
) { converged = 0;
break;
}
}
if (converged) break;
// 更新
for (i = 0; i < SIZE; i++) {
for (j = 0; j < SIZE; j++) {
A[i][j] = A_next[i][j];
}
}
}
// 固有値を対角成分として取得
for (i = 0; i < SIZE; i++) {
eigenvalues[i] = A[i][i];
}
return iteration_count;
}
// メイン関数
int main() {
double A[SIZE][SIZE] = {
{16, -1, 1, 2},
{2, 12, 1, -1},
{1, 3, 24, 2},
{4, -2, 1, 20}
};
double eigenvalues[SIZE];
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
}
}
int iteration_count = qr_algorithm(A, eigenvalues);
for (int i = 0; i < SIZE; i++) {
printf("lambda[%d] = %8.4f\n", i
, eigenvalues
[i
]); }
printf("\n反復回数: %d\n", iteration_count
); return 0;
}
ICNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8bWF0aC5oPgoKI2RlZmluZSBTSVpFIDQgLy8g6KGM5YiX44Gu44K144Kk44K6CiNkZWZpbmUgTUFYX0lURVIgMTAwMCAvLyDmnIDlpKflj43lvqnlm57mlbAKI2RlZmluZSBUT0wgMWUtNiAvLyDlj47mnZ/liKTlrprjga7oqLHlrrnoqqTlt64KCi8vIFFS5YiG6Kej44KS6KGM44GG44Gf44KB44Gu6Zai5pWw77yI44Kw44Op44Og44K344Ol44Of44OD44OI55u05Lqk5YyW44KS5L2/55So77yJCnZvaWQgcXJfZGVjb21wb3NlKGRvdWJsZSBBW1NJWkVdW1NJWkVdLCBkb3VibGUgUVtTSVpFXVtTSVpFXSwgZG91YmxlIFJbU0laRV1bU0laRV0pIHsKICAgIGludCBpLCBqLCBrOwogICAgZG91YmxlIG5vcm07CgogICAgZm9yIChpID0gMDsgaSA8IFNJWkU7IGkrKykgewogICAgICAgIGZvciAoaiA9IDA7IGogPCBTSVpFOyBqKyspIHsKICAgICAgICAgICAgUVtpXVtqXSA9IDAuMDsKICAgICAgICAgICAgUltpXVtqXSA9IDAuMDsKICAgICAgICB9CiAgICB9CgogICAgZm9yIChrID0gMDsgayA8IFNJWkU7IGsrKykgewogICAgICAgIGZvciAoaSA9IDA7IGkgPCBTSVpFOyBpKyspIHsKICAgICAgICAgICAgUVtpXVtrXSA9IEFbaV1ba107CiAgICAgICAgfQogICAgICAgIGZvciAoaiA9IDA7IGogPCBrOyBqKyspIHsKICAgICAgICAgICAgUltqXVtrXSA9IDAuMDsKICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IFNJWkU7IGkrKykgewogICAgICAgICAgICAgICAgUltqXVtrXSArPSBRW2ldW2pdICogQVtpXVtrXTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgU0laRTsgaSsrKSB7CiAgICAgICAgICAgICAgICBRW2ldW2tdIC09IFJbal1ba10gKiBRW2ldW2pdOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIG5vcm0gPSAwLjA7CiAgICAgICAgZm9yIChpID0gMDsgaSA8IFNJWkU7IGkrKykgewogICAgICAgICAgICBub3JtICs9IFFbaV1ba10gKiBRW2ldW2tdOwogICAgICAgIH0KICAgICAgICBSW2tdW2tdID0gc3FydChub3JtKTsKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgU0laRTsgaSsrKSB7CiAgICAgICAgICAgIFFbaV1ba10gLz0gUltrXVtrXTsKICAgICAgICB9CiAgICB9Cn0KCi8vIFFS5rOV44Gn5Zu65pyJ5YCk44KS6KiI566X44GZ44KL6Zai5pWwCmludCBxcl9hbGdvcml0aG0oZG91YmxlIEFbU0laRV1bU0laRV0sIGRvdWJsZSBlaWdlbnZhbHVlc1tTSVpFXSkgewogICAgZG91YmxlIFFbU0laRV1bU0laRV0sIFJbU0laRV1bU0laRV0sIEFfbmV4dFtTSVpFXVtTSVpFXTsKICAgIGludCBpLCBqLCBrOwogICAgaW50IGl0ZXJhdGlvbl9jb3VudCA9IDA7CgogICAgZm9yIChrID0gMDsgayA8IE1BWF9JVEVSOyBrKyspIHsKICAgICAgICBpdGVyYXRpb25fY291bnQrKzsKICAgICAgICAvLyBRUuWIhuinowogICAgICAgIHFyX2RlY29tcG9zZShBLCBRLCBSKTsKICAgICAgICAvLyDmlrDjgZfjgYTooYzliJcgQSA9IFIgKiBRIOOCkuioiOeulwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBTSVpFOyBpKyspIHsKICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IFNJWkU7IGorKykgewogICAgICAgICAgICAgICAgQV9uZXh0W2ldW2pdID0gMC4wOwogICAgICAgICAgICAgICAgZm9yIChpbnQgbCA9IDA7IGwgPCBTSVpFOyBsKyspIHsKICAgICAgICAgICAgICAgICAgICBBX25leHRbaV1bal0gKz0gUltpXVtsXSAqIFFbbF1bal07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy8g5Y+O5p2f5Yik5a6aCiAgICAgICAgaW50IGNvbnZlcmdlZCA9IDE7CiAgICAgICAgZm9yIChpID0gMDsgaSA8IFNJWkU7IGkrKykgewogICAgICAgICAgICBpZiAoZmFicyhBW2ldW2ldIC0gQV9uZXh0W2ldW2ldKSA+IFRPTCkgewogICAgICAgICAgICAgICAgY29udmVyZ2VkID0gMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChjb252ZXJnZWQpIGJyZWFrOwogICAgICAgIC8vIOabtOaWsAogICAgICAgIGZvciAoaSA9IDA7IGkgPCBTSVpFOyBpKyspIHsKICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IFNJWkU7IGorKykgewogICAgICAgICAgICAgICAgQVtpXVtqXSA9IEFfbmV4dFtpXVtqXTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIC8vIOWbuuacieWApOOCkuWvvuinkuaIkOWIhuOBqOOBl+OBpuWPluW+lwogICAgZm9yIChpID0gMDsgaSA8IFNJWkU7IGkrKykgewogICAgICAgIGVpZ2VudmFsdWVzW2ldID0gQVtpXVtpXTsKICAgIH0KICAgIHJldHVybiBpdGVyYXRpb25fY291bnQ7Cn0KCi8vIOODoeOCpOODs+mWouaVsAppbnQgbWFpbigpIHsKICAgIGRvdWJsZSBBW1NJWkVdW1NJWkVdID0gewogICAgICAgIHsxNiwgLTEsIDEsIDJ9LAogICAgICAgIHsyLCAxMiwgMSwgLTF9LAogICAgICAgIHsxLCAzLCAyNCwgMn0sCiAgICAgICAgezQsIC0yLCAxLCAyMH0KICAgIH07CiAgICBkb3VibGUgZWlnZW52YWx1ZXNbU0laRV07CgogICAgcHJpbnRmKCLliJ3mnJ/ooYzliJc6XG4iKTsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgU0laRTsgaSsrKSB7CiAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBTSVpFOyBqKyspIHsKICAgICAgICAgICAgcHJpbnRmKCIlOC40ZiAiLCBBW2ldW2pdKTsKICAgICAgICB9CiAgICAgICAgcHJpbnRmKCJcbiIpOwogICAgfQoKICAgIGludCBpdGVyYXRpb25fY291bnQgPSBxcl9hbGdvcml0aG0oQSwgZWlnZW52YWx1ZXMpOwoKICAgIHByaW50ZigiXG7lm7rmnInlgKQ6XG4iKTsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgU0laRTsgaSsrKSB7CiAgICAgICAgcHJpbnRmKCJsYW1iZGFbJWRdID0gJTguNGZcbiIsIGksIGVpZ2VudmFsdWVzW2ldKTsKICAgIH0KCiAgICBwcmludGYoIlxu5Y+N5b6p5Zue5pWwOiAlZFxuIiwgaXRlcmF0aW9uX2NvdW50KTsKICAgIHJldHVybiAwOwp9Cg==