#include <stdio.h>
#include <math.h>
#define N 4 // Matrix size
#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() {
// Original matrix A
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}
};
// Keep a backup of the original matrix A 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 of P will become our eigenvectors.
double P[N][N] = {0};
for (int i = 0; i < N; i++) P[i][i] = 1.0;
int iter = 0;
printf("=== Jacobi Method Convergence Process ===\n\n");
while (iter < MAX_ITER) {
// 1. Find the maximum off-diagonal element A[p][q]
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;
}
}
}
// Print track of convergence
printf("Iteration %d: Max off-diagonal = %f (at A[%d][%d])\n", iter
, max_val
, p
, q
);
if (max_val < EPS) {
printf("\n--> Successfully converged after %d iterations.\n\n", iter
); break;
}
// 2. Calculate the rotation angle theta (using acos(-1.0) for Pi)
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 (P_k^T * A * P_k)
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 Eigenvector Matrix P (P = P * P_k)
// We modify the columns p and q of matrix P
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 Eigenvalues & Eigenvectors ===
printf("=== Final Results ===\n"); for (int j = 0; j < N; j++) {
double lambda = A[j][j]; // Diagonal elements are eigenvalues
printf("Eigenvalue %d: %7.4f\n", j
+ 1, lambda
); printf("Eigenvector %d (Column vector):\n", j
+ 1); for (int i = 0; i < N; i++) {
printf(" [%7.4f]\n", P
[i
][j
]); // P[i][j] extracts the j-th column }
}
// === Verification (Ax = lambda * x) ===
printf("=== Code-Level Verification (Ax - lambda * x) ===\n"); printf("If the values below are essentially 0, Ax = lambda * x holds true perfectly.\n\n");
for (int j = 0; j < N; j++) {
double lambda = A[j][j];
printf("Verifying Eigenvalue %d (%7.4f):\n", j
+ 1, lambda
);
for (int i = 0; i < N; i++) {
// Compute i-th row of (A_orig * j-th column of P)
double Ax_i = 0.0;
for (int k = 0; k < N; k++) {
Ax_i += A_orig[i][k] * P[k][j];
}
// Compute i-th row of (lambda * j-th column of P)
double lambda_x_i = lambda * P[i][j];
// Difference should approach 0
printf(" Row %d difference: %10.3e\n", i
+ 1, Ax_i
- lambda_x_i
); }
}
return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxtYXRoLmg+CgojZGVmaW5lIE4gNCAgICAgICAgIC8vIE1hdHJpeCBzaXplCiNkZWZpbmUgRVBTIDFlLTYgICAgLy8gQ29udmVyZ2VuY2UgdGhyZXNob2xkCiNkZWZpbmUgTUFYX0lURVIgMTAwCgp2b2lkIHByaW50X21hdHJpeChkb3VibGUgbWF0W05dW05dKSB7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IE47IGkrKykgewogICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgTjsgaisrKSB7CiAgICAgICAgICAgIHByaW50ZigiJTcuNGYgIiwgbWF0W2ldW2pdKTsKICAgICAgICB9CiAgICAgICAgcHJpbnRmKCJcbiIpOwogICAgfQp9CgppbnQgbWFpbigpIHsKICAgIC8vIE9yaWdpbmFsIG1hdHJpeCBBCiAgICBkb3VibGUgQVtOXVtOXSA9IHsKICAgICAgICB7NS4wLCA0LjAsIDEuMCwgMS4wfSwKICAgICAgICB7NC4wLCA1LjAsIDEuMCwgMS4wfSwKICAgICAgICB7MS4wLCAxLjAsIDQuMCwgMi4wfSwKICAgICAgICB7MS4wLCAxLjAsIDIuMCwgNC4wfQogICAgfTsKCiAgICAvLyBLZWVwIGEgYmFja3VwIG9mIHRoZSBvcmlnaW5hbCBtYXRyaXggQSBmb3IgdmVyaWZpY2F0aW9uIChBeCA9IGxhbWJkYSAqIHgpCiAgICBkb3VibGUgQV9vcmlnW05dW05dOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBOOyBpKyspCiAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBOOyBqKyspCiAgICAgICAgICAgIEFfb3JpZ1tpXVtqXSA9IEFbaV1bal07CgogICAgLy8gSW5pdGlhbGl6ZSBQIGFzIGFuIElkZW50aXR5IE1hdHJpeC4gQ29sdW1ucyBvZiBQIHdpbGwgYmVjb21lIG91ciBlaWdlbnZlY3RvcnMuCiAgICBkb3VibGUgUFtOXVtOXSA9IHswfTsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgTjsgaSsrKSBQW2ldW2ldID0gMS4wOwoKICAgIGludCBpdGVyID0gMDsKICAgIHByaW50ZigiPT09IEphY29iaSBNZXRob2QgQ29udmVyZ2VuY2UgUHJvY2VzcyA9PT1cblxuIik7CgogICAgd2hpbGUgKGl0ZXIgPCBNQVhfSVRFUikgewogICAgICAgIC8vIDEuIEZpbmQgdGhlIG1heGltdW0gb2ZmLWRpYWdvbmFsIGVsZW1lbnQgQVtwXVtxXQogICAgICAgIGludCBwID0gMCwgcSA9IDE7CiAgICAgICAgZG91YmxlIG1heF92YWwgPSBmYWJzKEFbMF1bMV0pOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgTjsgaSsrKSB7CiAgICAgICAgICAgIGZvciAoaW50IGogPSBpICsgMTsgaiA8IE47IGorKykgewogICAgICAgICAgICAgICAgaWYgKGZhYnMoQVtpXVtqXSkgPiBtYXhfdmFsKSB7CiAgICAgICAgICAgICAgICAgICAgbWF4X3ZhbCA9IGZhYnMoQVtpXVtqXSk7CiAgICAgICAgICAgICAgICAgICAgcCA9IGk7CiAgICAgICAgICAgICAgICAgICAgcSA9IGo7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIFByaW50IHRyYWNrIG9mIGNvbnZlcmdlbmNlCiAgICAgICAgcHJpbnRmKCJJdGVyYXRpb24gJWQ6IE1heCBvZmYtZGlhZ29uYWwgPSAlZiAoYXQgQVslZF1bJWRdKVxuIiwgaXRlciwgbWF4X3ZhbCwgcCwgcSk7CgogICAgICAgIGlmIChtYXhfdmFsIDwgRVBTKSB7CiAgICAgICAgICAgIHByaW50ZigiXG4tLT4gU3VjY2Vzc2Z1bGx5IGNvbnZlcmdlZCBhZnRlciAlZCBpdGVyYXRpb25zLlxuXG4iLCBpdGVyKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICAvLyAyLiBDYWxjdWxhdGUgdGhlIHJvdGF0aW9uIGFuZ2xlIHRoZXRhICh1c2luZyBhY29zKC0xLjApIGZvciBQaSkKICAgICAgICBkb3VibGUgcGhpLCBjb3NfdCwgc2luX3Q7CiAgICAgICAgaWYgKGZhYnMoQVtwXVtwXSAtIEFbcV1bcV0pIDwgMWUtMTIpIHsKICAgICAgICAgICAgcGhpID0gYWNvcygtMS4wKSAvIDQuMDsgCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcGhpID0gMC41ICogYXRhbjIoMi4wICogQVtwXVtxXSwgQVtwXVtwXSAtIEFbcV1bcV0pOwogICAgICAgIH0KICAgICAgICBjb3NfdCA9IGNvcyhwaGkpOwogICAgICAgIHNpbl90ID0gc2luKHBoaSk7CgogICAgICAgIC8vIDMuIFVwZGF0ZSBNYXRyaXggQSAoUF9rXlQgKiBBICogUF9rKQogICAgICAgIGRvdWJsZSBBcF9vbGQgPSBBW3BdW3BdOwogICAgICAgIGRvdWJsZSBBcV9vbGQgPSBBW3FdW3FdOwogICAgICAgIAogICAgICAgIEFbcF1bcF0gPSBBcF9vbGQgKiBjb3NfdCAqIGNvc190ICsgQXFfb2xkICogc2luX3QgKiBzaW5fdCArIDIuMCAqIEFbcF1bcV0gKiBzaW5fdCAqIGNvc190OwogICAgICAgIEFbcV1bcV0gPSBBcF9vbGQgKiBzaW5fdCAqIHNpbl90ICsgQXFfb2xkICogY29zX3QgKiBjb3NfdCAtIDIuMCAqIEFbcF1bcV0gKiBzaW5fdCAqIGNvc190OwogICAgICAgIEFbcF1bcV0gPSBBW3FdW3BdID0gMC4wOyAKCiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBOOyBpKyspIHsKICAgICAgICAgICAgaWYgKGkgIT0gcCAmJiBpICE9IHEpIHsKICAgICAgICAgICAgICAgIGRvdWJsZSBhX2lwID0gQVtpXVtwXTsKICAgICAgICAgICAgICAgIGRvdWJsZSBhX2lxID0gQVtpXVtxXTsKICAgICAgICAgICAgICAgIEFbaV1bcF0gPSBBW3BdW2ldID0gYV9pcCAqIGNvc190ICsgYV9pcSAqIHNpbl90OwogICAgICAgICAgICAgICAgQVtpXVtxXSA9IEFbcV1baV0gPSAtYV9pcCAqIHNpbl90ICsgYV9pcSAqIGNvc190OwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyA0LiBVcGRhdGUgRWlnZW52ZWN0b3IgTWF0cml4IFAgKFAgPSBQICogUF9rKQogICAgICAgIC8vIFdlIG1vZGlmeSB0aGUgY29sdW1ucyBwIGFuZCBxIG9mIG1hdHJpeCBQCiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBOOyBpKyspIHsKICAgICAgICAgICAgZG91YmxlIHBfaXAgPSBQW2ldW3BdOwogICAgICAgICAgICBkb3VibGUgcF9pcSA9IFBbaV1bcV07CiAgICAgICAgICAgIFBbaV1bcF0gPSBwX2lwICogY29zX3QgKyBwX2lxICogc2luX3Q7CiAgICAgICAgICAgIFBbaV1bcV0gPSAtcF9pcCAqIHNpbl90ICsgcF9pcSAqIGNvc190OwogICAgICAgIH0KCiAgICAgICAgaXRlcisrOwogICAgfQoKICAgIC8vID09PSBPdXRwdXQgRmluYWwgRWlnZW52YWx1ZXMgJiBFaWdlbnZlY3RvcnMgPT09CiAgICBwcmludGYoIj09PSBGaW5hbCBSZXN1bHRzID09PVxuIik7CiAgICBmb3IgKGludCBqID0gMDsgaiA8IE47IGorKykgewogICAgICAgIGRvdWJsZSBsYW1iZGEgPSBBW2pdW2pdOyAvLyBEaWFnb25hbCBlbGVtZW50cyBhcmUgZWlnZW52YWx1ZXMKICAgICAgICBwcmludGYoIkVpZ2VudmFsdWUgJWQ6ICU3LjRmXG4iLCBqICsgMSwgbGFtYmRhKTsKICAgICAgICBwcmludGYoIkVpZ2VudmVjdG9yICVkIChDb2x1bW4gdmVjdG9yKTpcbiIsIGogKyAxKTsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IE47IGkrKykgewogICAgICAgICAgICBwcmludGYoIiAgWyU3LjRmXVxuIiwgUFtpXVtqXSk7IC8vIFBbaV1bal0gZXh0cmFjdHMgdGhlIGotdGggY29sdW1uCiAgICAgICAgfQogICAgICAgIHByaW50ZigiXG4iKTsKICAgIH0KCiAgICAvLyA9PT0gVmVyaWZpY2F0aW9uIChBeCA9IGxhbWJkYSAqIHgpID09PQogICAgcHJpbnRmKCI9PT0gQ29kZS1MZXZlbCBWZXJpZmljYXRpb24gKEF4IC0gbGFtYmRhICogeCkgPT09XG4iKTsKICAgIHByaW50ZigiSWYgdGhlIHZhbHVlcyBiZWxvdyBhcmUgZXNzZW50aWFsbHkgMCwgQXggPSBsYW1iZGEgKiB4IGhvbGRzIHRydWUgcGVyZmVjdGx5LlxuXG4iKTsKCiAgICBmb3IgKGludCBqID0gMDsgaiA8IE47IGorKykgewogICAgICAgIGRvdWJsZSBsYW1iZGEgPSBBW2pdW2pdOwogICAgICAgIHByaW50ZigiVmVyaWZ5aW5nIEVpZ2VudmFsdWUgJWQgKCU3LjRmKTpcbiIsIGogKyAxLCBsYW1iZGEpOwogICAgICAgIAogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgTjsgaSsrKSB7CiAgICAgICAgICAgIC8vIENvbXB1dGUgaS10aCByb3cgb2YgKEFfb3JpZyAqIGotdGggY29sdW1uIG9mIFApCiAgICAgICAgICAgIGRvdWJsZSBBeF9pID0gMC4wOwogICAgICAgICAgICBmb3IgKGludCBrID0gMDsgayA8IE47IGsrKykgewogICAgICAgICAgICAgICAgQXhfaSArPSBBX29yaWdbaV1ba10gKiBQW2tdW2pdOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIENvbXB1dGUgaS10aCByb3cgb2YgKGxhbWJkYSAqIGotdGggY29sdW1uIG9mIFApCiAgICAgICAgICAgIGRvdWJsZSBsYW1iZGFfeF9pID0gbGFtYmRhICogUFtpXVtqXTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIERpZmZlcmVuY2Ugc2hvdWxkIGFwcHJvYWNoIDAKICAgICAgICAgICAgcHJpbnRmKCIgIFJvdyAlZCBkaWZmZXJlbmNlOiAlMTAuM2VcbiIsIGkgKyAxLCBBeF9pIC0gbGFtYmRhX3hfaSk7CiAgICAgICAgfQogICAgICAgIHByaW50ZigiXG4iKTsKICAgIH0KCiAgICByZXR1cm4gMDsKfQ==