#include <stdio.h>
#include <math.h>
#define N 4
#define EPS 1e-6 // Convergence threshold
#define MAX_ITER 100
void print_matrix(double mat[N][N]) {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
}
}
}
int main() {
// Initial symmetric matrix A [cite: 13]
double A[N][N] = {
{5.0, 4.0, 1.0, 1.0},
{4.0, 5.0, 1.0, 1.0},
{1.0, 1.0, 4.0, 2.0},
{1.0, 1.0, 2.0, 4.0}
};
// Backup the original matrix for verification (Ax = lambda * x)
double A_orig[N][N];
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
A_orig[i][j] = A[i][j];
// Initialize P as an Identity Matrix. Columns will store eigenvectors[cite: 39].
double P[N][N] = {0};
for (int i = 0; i < N; i++) P[i][i] = 1.0;
int iter = 0;
// Tidy, aligned table header for convergence history
printf("=== CONVERGENCE HISTORY ===\n"); printf("%-5s %-16s %-8s\n", "Iter", "Max Off-Diagonal", "Position"); printf("---------------------------------------\n");
while (iter < MAX_ITER) {
// 1. Find the maximum off-diagonal element A[p][q] [cite: 76]
int p = 0, q = 1;
double max_val
= fabs(A
[0][1]); for (int i = 0; i < N; i++) {
for (int j = i + 1; j < N; j++) {
if (fabs(A
[i
][j
]) > max_val
) { p = i;
q = j;
}
}
}
// Tabled log row output
printf("%-5d %-16.6f A[%d][%d]\n", iter
, max_val
, p
, q
);
// Check convergence status [cite: 76]
if (max_val < EPS) {
printf("---------------------------------------\n"); printf("Status: Successfully converged.\n\n"); break;
}
// 2. Calculate rotation angle using acos(-1.0) dynamically [cite: 54]
double phi, cos_t, sin_t;
if (fabs(A
[p
][p
] - A
[q
][q
]) < 1e-12) { } else {
phi
= 0.5 * atan2(2.0 * A
[p
][q
], A
[p
][p
] - A
[q
][q
]); }
// 3. Update Matrix A [cite: 51]
double Ap_old = A[p][p];
double Aq_old = A[q][q];
A[p][p] = Ap_old * cos_t * cos_t + Aq_old * sin_t * sin_t + 2.0 * A[p][q] * sin_t * cos_t;
A[q][q] = Ap_old * sin_t * sin_t + Aq_old * cos_t * cos_t - 2.0 * A[p][q] * sin_t * cos_t;
A[p][q] = A[q][p] = 0.0;
for (int i = 0; i < N; i++) {
if (i != p && i != q) {
double a_ip = A[i][p];
double a_iq = A[i][q];
A[i][p] = A[p][i] = a_ip * cos_t + a_iq * sin_t;
A[i][q] = A[q][i] = -a_ip * sin_t + a_iq * cos_t;
}
}
// 4. Update Cumulative Eigenvector Matrix P [cite: 77]
for (int i = 0; i < N; i++) {
double p_ip = P[i][p];
double p_iq = P[i][q];
P[i][p] = p_ip * cos_t + p_iq * sin_t;
P[i][q] = -p_ip * sin_t + p_iq * cos_t;
}
iter++;
}
// === Output Final Results ===
printf("=== EIGENVALUES & EIGENVECTORS ===\n"); for (int j = 0; j < N; j++) {
printf("Eigenvalue %d (固有値): %f\n", j
+ 1, A
[j
][j
]); // [cite: 24] printf("Eigenvector %d (固有ベクトル):\n[ ", j
+ 1); for (int i = 0; i < N; i++) {
printf("%f ", P
[i
][j
]); // Prints column vectors horizontally [cite: 39] }
}
// === Automated Verification Step (Ax = lambda * x) ===
printf("=== 固有対の検証チェック (A*x - lambda*x) ===\n");
for (int j = 0; j < N; j++) {
double lambda = A[j][j];
printf("Eigenvalue %d (%f):\n", j
+ 1, lambda
);
for (int i = 0; i < N; i++) {
// Compute elements of Ax
double Ax_i = 0.0;
for (int k = 0; k < N; k++) {
Ax_i += A_orig[i][k] * P[k][j];
}
// Compute elements of lambda * x
double lambda_x_i = lambda * P[i][j];
// Calculate absolute residual error
double residual
= fabs(Ax_i
- lambda_x_i
);
// Print out the numerical matching comparison with scientific notation residuals
printf(" 第 %d 行: A*x = %9.6f, lambda*x = %9.6f, 残差絶対値 = %e\n", i + 1, Ax_i, lambda_x_i, residual);
}
}
return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxtYXRoLmg+CgojZGVmaW5lIE4gNCAgICAgICAgIAojZGVmaW5lIEVQUyAxZS02ICAgIC8vIENvbnZlcmdlbmNlIHRocmVzaG9sZAojZGVmaW5lIE1BWF9JVEVSIDEwMAoKdm9pZCBwcmludF9tYXRyaXgoZG91YmxlIG1hdFtOXVtOXSkgewogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBOOyBpKyspIHsKICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IE47IGorKykgewogICAgICAgICAgICBwcmludGYoIiU3LjRmICIsIG1hdFtpXVtqXSk7CiAgICAgICAgfQogICAgICAgIHByaW50ZigiXG4iKTsKICAgIH0KfQoKaW50IG1haW4oKSB7CiAgICAvLyBJbml0aWFsIHN5bW1ldHJpYyBtYXRyaXggQSBbY2l0ZTogMTNdCiAgICBkb3VibGUgQVtOXVtOXSA9IHsKICAgICAgICB7NS4wLCA0LjAsIDEuMCwgMS4wfSwKICAgICAgICB7NC4wLCA1LjAsIDEuMCwgMS4wfSwKICAgICAgICB7MS4wLCAxLjAsIDQuMCwgMi4wfSwKICAgICAgICB7MS4wLCAxLjAsIDIuMCwgNC4wfQogICAgfTsKCiAgICAvLyBCYWNrdXAgdGhlIG9yaWdpbmFsIG1hdHJpeCBmb3IgdmVyaWZpY2F0aW9uIChBeCA9IGxhbWJkYSAqIHgpCiAgICBkb3VibGUgQV9vcmlnW05dW05dOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBOOyBpKyspCiAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBOOyBqKyspCiAgICAgICAgICAgIEFfb3JpZ1tpXVtqXSA9IEFbaV1bal07CgogICAgLy8gSW5pdGlhbGl6ZSBQIGFzIGFuIElkZW50aXR5IE1hdHJpeC4gQ29sdW1ucyB3aWxsIHN0b3JlIGVpZ2VudmVjdG9yc1tjaXRlOiAzOV0uCiAgICBkb3VibGUgUFtOXVtOXSA9IHswfTsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgTjsgaSsrKSBQW2ldW2ldID0gMS4wOwoKICAgIGludCBpdGVyID0gMDsKICAgIAogICAgLy8gVGlkeSwgYWxpZ25lZCB0YWJsZSBoZWFkZXIgZm9yIGNvbnZlcmdlbmNlIGhpc3RvcnkKICAgIHByaW50ZigiPT09IENPTlZFUkdFTkNFIEhJU1RPUlkgPT09XG4iKTsKICAgIHByaW50ZigiJS01cyAgICUtMTZzICAgJS04c1xuIiwgIkl0ZXIiLCAiTWF4IE9mZi1EaWFnb25hbCIsICJQb3NpdGlvbiIpOwogICAgcHJpbnRmKCItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiIpOwoKICAgIHdoaWxlIChpdGVyIDwgTUFYX0lURVIpIHsKICAgICAgICAvLyAxLiBGaW5kIHRoZSBtYXhpbXVtIG9mZi1kaWFnb25hbCBlbGVtZW50IEFbcF1bcV0gW2NpdGU6IDc2XQogICAgICAgIGludCBwID0gMCwgcSA9IDE7CiAgICAgICAgZG91YmxlIG1heF92YWwgPSBmYWJzKEFbMF1bMV0pOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgTjsgaSsrKSB7CiAgICAgICAgICAgIGZvciAoaW50IGogPSBpICsgMTsgaiA8IE47IGorKykgewogICAgICAgICAgICAgICAgaWYgKGZhYnMoQVtpXVtqXSkgPiBtYXhfdmFsKSB7CiAgICAgICAgICAgICAgICAgICAgbWF4X3ZhbCA9IGZhYnMoQVtpXVtqXSk7CiAgICAgICAgICAgICAgICAgICAgcCA9IGk7CiAgICAgICAgICAgICAgICAgICAgcSA9IGo7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIFRhYmxlZCBsb2cgcm93IG91dHB1dAogICAgICAgIHByaW50ZigiJS01ZCAgICUtMTYuNmYgICBBWyVkXVslZF1cbiIsIGl0ZXIsIG1heF92YWwsIHAsIHEpOwoKICAgICAgICAvLyBDaGVjayBjb252ZXJnZW5jZSBzdGF0dXMgW2NpdGU6IDc2XQogICAgICAgIGlmIChtYXhfdmFsIDwgRVBTKSB7CiAgICAgICAgICAgIHByaW50ZigiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iKTsKICAgICAgICAgICAgcHJpbnRmKCJTdGF0dXM6IFN1Y2Nlc3NmdWxseSBjb252ZXJnZWQuXG5cbiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIC8vIDIuIENhbGN1bGF0ZSByb3RhdGlvbiBhbmdsZSB1c2luZyBhY29zKC0xLjApIGR5bmFtaWNhbGx5IFtjaXRlOiA1NF0KICAgICAgICBkb3VibGUgcGhpLCBjb3NfdCwgc2luX3Q7CiAgICAgICAgaWYgKGZhYnMoQVtwXVtwXSAtIEFbcV1bcV0pIDwgMWUtMTIpIHsKICAgICAgICAgICAgcGhpID0gYWNvcygtMS4wKSAvIDQuMDsgCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcGhpID0gMC41ICogYXRhbjIoMi4wICogQVtwXVtxXSwgQVtwXVtwXSAtIEFbcV1bcV0pOwogICAgICAgIH0KICAgICAgICBjb3NfdCA9IGNvcyhwaGkpOwogICAgICAgIHNpbl90ID0gc2luKHBoaSk7CgogICAgICAgIC8vIDMuIFVwZGF0ZSBNYXRyaXggQSBbY2l0ZTogNTFdCiAgICAgICAgZG91YmxlIEFwX29sZCA9IEFbcF1bcF07CiAgICAgICAgZG91YmxlIEFxX29sZCA9IEFbcV1bcV07CiAgICAgICAgCiAgICAgICAgQVtwXVtwXSA9IEFwX29sZCAqIGNvc190ICogY29zX3QgKyBBcV9vbGQgKiBzaW5fdCAqIHNpbl90ICsgMi4wICogQVtwXVtxXSAqIHNpbl90ICogY29zX3Q7CiAgICAgICAgQVtxXVtxXSA9IEFwX29sZCAqIHNpbl90ICogc2luX3QgKyBBcV9vbGQgKiBjb3NfdCAqIGNvc190IC0gMi4wICogQVtwXVtxXSAqIHNpbl90ICogY29zX3Q7CiAgICAgICAgQVtwXVtxXSA9IEFbcV1bcF0gPSAwLjA7IAoKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IE47IGkrKykgewogICAgICAgICAgICBpZiAoaSAhPSBwICYmIGkgIT0gcSkgewogICAgICAgICAgICAgICAgZG91YmxlIGFfaXAgPSBBW2ldW3BdOwogICAgICAgICAgICAgICAgZG91YmxlIGFfaXEgPSBBW2ldW3FdOwogICAgICAgICAgICAgICAgQVtpXVtwXSA9IEFbcF1baV0gPSBhX2lwICogY29zX3QgKyBhX2lxICogc2luX3Q7CiAgICAgICAgICAgICAgICBBW2ldW3FdID0gQVtxXVtpXSA9IC1hX2lwICogc2luX3QgKyBhX2lxICogY29zX3Q7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIDQuIFVwZGF0ZSBDdW11bGF0aXZlIEVpZ2VudmVjdG9yIE1hdHJpeCBQIFtjaXRlOiA3N10KICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IE47IGkrKykgewogICAgICAgICAgICBkb3VibGUgcF9pcCA9IFBbaV1bcF07CiAgICAgICAgICAgIGRvdWJsZSBwX2lxID0gUFtpXVtxXTsKICAgICAgICAgICAgUFtpXVtwXSA9IHBfaXAgKiBjb3NfdCArIHBfaXEgKiBzaW5fdDsKICAgICAgICAgICAgUFtpXVtxXSA9IC1wX2lwICogc2luX3QgKyBwX2lxICogY29zX3Q7CiAgICAgICAgfQoKICAgICAgICBpdGVyKys7CiAgICB9CgogICAgLy8gPT09IE91dHB1dCBGaW5hbCBSZXN1bHRzID09PQogICAgcHJpbnRmKCI9PT0gRUlHRU5WQUxVRVMgJiBFSUdFTlZFQ1RPUlMgPT09XG4iKTsKICAgIGZvciAoaW50IGogPSAwOyBqIDwgTjsgaisrKSB7CiAgICAgICAgcHJpbnRmKCJFaWdlbnZhbHVlICVkICjlm7rmnInlgKQpOiAlZlxuIiwgaiArIDEsIEFbal1bal0pOyAvLyBbY2l0ZTogMjRdCiAgICAgICAgcHJpbnRmKCJFaWdlbnZlY3RvciAlZCAo5Zu65pyJ44OZ44Kv44OI44OrKTpcblsgIiwgaiArIDEpOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgTjsgaSsrKSB7CiAgICAgICAgICAgIHByaW50ZigiJWYgIiwgUFtpXVtqXSk7IC8vIFByaW50cyBjb2x1bW4gdmVjdG9ycyBob3Jpem9udGFsbHkgW2NpdGU6IDM5XQogICAgICAgIH0KICAgICAgICBwcmludGYoIl1cblxuIik7CiAgICB9CgogICAgLy8gPT09IEF1dG9tYXRlZCBWZXJpZmljYXRpb24gU3RlcCAoQXggPSBsYW1iZGEgKiB4KSA9PT0KICAgIHByaW50ZigiPT09IOWbuuacieWvvuOBruaknOiovOODgeOCp+ODg+OCryAoQSp4IC0gbGFtYmRhKngpID09PVxuIik7CiAgICAKICAgIGZvciAoaW50IGogPSAwOyBqIDwgTjsgaisrKSB7CiAgICAgICAgZG91YmxlIGxhbWJkYSA9IEFbal1bal07CiAgICAgICAgcHJpbnRmKCJFaWdlbnZhbHVlICVkICglZik6XG4iLCBqICsgMSwgbGFtYmRhKTsKICAgICAgICAKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IE47IGkrKykgewogICAgICAgICAgICAvLyBDb21wdXRlIGVsZW1lbnRzIG9mIEF4CiAgICAgICAgICAgIGRvdWJsZSBBeF9pID0gMC4wOwogICAgICAgICAgICBmb3IgKGludCBrID0gMDsgayA8IE47IGsrKykgewogICAgICAgICAgICAgICAgQXhfaSArPSBBX29yaWdbaV1ba10gKiBQW2tdW2pdOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIENvbXB1dGUgZWxlbWVudHMgb2YgbGFtYmRhICogeAogICAgICAgICAgICBkb3VibGUgbGFtYmRhX3hfaSA9IGxhbWJkYSAqIFBbaV1bal07CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBDYWxjdWxhdGUgYWJzb2x1dGUgcmVzaWR1YWwgZXJyb3IKICAgICAgICAgICAgZG91YmxlIHJlc2lkdWFsID0gZmFicyhBeF9pIC0gbGFtYmRhX3hfaSk7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBQcmludCBvdXQgdGhlIG51bWVyaWNhbCBtYXRjaGluZyBjb21wYXJpc29uIHdpdGggc2NpZW50aWZpYyBub3RhdGlvbiByZXNpZHVhbHMKICAgICAgICAgICAgcHJpbnRmKCIgIOesrCAlZCDooYw6IEEqeCA9ICU5LjZmLCBsYW1iZGEqeCA9ICU5LjZmLCDmrovlt67ntbblr77lgKQgPSAlZVxuIiwgCiAgICAgICAgICAgICAgICAgICBpICsgMSwgQXhfaSwgbGFtYmRhX3hfaSwgcmVzaWR1YWwpOwogICAgICAgIH0KICAgICAgICBwcmludGYoIlxuIik7CiAgICB9CgogICAgcmV0dXJuIDA7Cn0=
=== CONVERGENCE HISTORY ===
Iter Max Off-Diagonal Position
---------------------------------------
0 4.000000 A[0][1]
1 2.000000 A[2][3]
2 2.000000 A[0][2]
3 0.000000 A[0][3]
---------------------------------------
Status: Successfully converged.
=== EIGENVALUES & EIGENVECTORS ===
Eigenvalue 1 (固有値): 10.000000
Eigenvector 1 (固有ベクトル):
[ 0.632456 0.632456 0.316228 0.316228 ]
Eigenvalue 2 (固有値): 1.000000
Eigenvector 2 (固有ベクトル):
[ -0.707107 0.707107 0.000000 0.000000 ]
Eigenvalue 3 (固有値): 5.000000
Eigenvector 3 (固有ベクトル):
[ -0.316228 -0.316228 0.632456 0.632456 ]
Eigenvalue 4 (固有値): 2.000000
Eigenvector 4 (固有ベクトル):
[ 0.000000 0.000000 -0.707107 0.707107 ]
=== 固有対の検証チェック (A*x - lambda*x) ===
Eigenvalue 1 (10.000000):
第 1 行: A*x = 6.324555, lambda*x = 6.324555, 残差絶対値 = 8.881784e-16
第 2 行: A*x = 6.324555, lambda*x = 6.324555, 残差絶対値 = 1.776357e-15
第 3 行: A*x = 3.162278, lambda*x = 3.162278, 残差絶対値 = 4.440892e-16
第 4 行: A*x = 3.162278, lambda*x = 3.162278, 残差絶対値 = 8.881784e-16
Eigenvalue 2 (1.000000):
第 1 行: A*x = -0.707107, lambda*x = -0.707107, 残差絶対値 = 4.440892e-16
第 2 行: A*x = 0.707107, lambda*x = 0.707107, 残差絶対値 = 3.330669e-16
第 3 行: A*x = 0.000000, lambda*x = 0.000000, 残差絶対値 = 1.110223e-16
第 4 行: A*x = 0.000000, lambda*x = 0.000000, 残差絶対値 = 1.110223e-16
Eigenvalue 3 (5.000000):
第 1 行: A*x = -1.581139, lambda*x = -1.581139, 残差絶対値 = 4.440892e-16
第 2 行: A*x = -1.581139, lambda*x = -1.581139, 残差絶対値 = 2.220446e-16
第 3 行: A*x = 3.162278, lambda*x = 3.162278, 残差絶対値 = 4.440892e-16
第 4 行: A*x = 3.162278, lambda*x = 3.162278, 残差絶対値 = 0.000000e+00
Eigenvalue 4 (2.000000):
第 1 行: A*x = 0.000000, lambda*x = 0.000000, 残差絶対値 = 1.110223e-16
第 2 行: A*x = 0.000000, lambda*x = 0.000000, 残差絶対値 = 1.110223e-16
第 3 行: A*x = -1.414214, lambda*x = -1.414214, 残差絶対値 = 2.220446e-16
第 4 行: A*x = 1.414214, lambda*x = 1.414214, 残差絶対値 = 2.220446e-16