#include <stdio.h>
#include <math.h>
#define N 4 // Matrix size
#define EPS 1e-6 // Convergence threshold (terminates when max off-diagonal element falls below this)
#define MAX_ITER 100
// Function to print a matrix
void print_matrix(double mat[N][N]) {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
}
}
}
int main() {
// Initial Matrix A Definition
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 A for verification later
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];
// Eigenvector matrix P (initialized as an Identity Matrix)
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;
}
}
}
// Output convergence status to track reduction of off-diagonal elements
printf("Iteration %d: Max off-diagonal = %f (at A[%d][%d])\n", iter
, max_val
, p
, q
);
// Convergence check
if (max_val < EPS) {
printf("\n--> Successfully converged! (Total iterations: %d)\n\n", iter
); break;
}
// 2. Calculate the rotation angle theta (phi)
double phi, cos_t, sin_t;
if (fabs(A
[p
][p
] - A
[q
][q
]) < 1e-12) { phi
= acos(-1.0) / 4.0; // 45 degrees if diagonal elements are equal } else {
phi
= 0.5 * atan2(2.0 * A
[p
][q
], A
[p
][p
] - A
[q
][q
]); }
// 3. Update Matrix A (P^T * A * P)
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; // Zero out the target element
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)
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++;
}
// === Display Results ===
printf("=== Final Results ===\n"); printf("Diagonalized Matrix A (Diagonal Elements = Eigenvalues):\n"); print_matrix(A);
// === Verification of Ax = lambda * x ===
printf("=== Verification (Ax - lambda * x) ===\n"); printf("Note: If the values are extremely close to 0, the math holds true!\n\n");
for (int j = 0; j < N; j++) {
double lambda = A[j][j];
printf("Eigenvalue %d: %7.4f Verification Error:\n", j
+ 1, lambda
);
for (int i = 0; i < N; i++) {
// Compute Ax
double Ax = 0.0;
for (int k = 0; k < N; k++) {
Ax += A_orig[i][k] * P[k][j];
}
// Compute lambda * x
double rx = lambda * P[i][j];
// Output the difference (Residual Error)
printf(" Row %d: %10.3e\n", i
+ 1, Ax
- rx
); }
}
return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxtYXRoLmg+CgojZGVmaW5lIE4gNCAgICAgICAgIC8vIE1hdHJpeCBzaXplCiNkZWZpbmUgRVBTIDFlLTYgICAgLy8gQ29udmVyZ2VuY2UgdGhyZXNob2xkICh0ZXJtaW5hdGVzIHdoZW4gbWF4IG9mZi1kaWFnb25hbCBlbGVtZW50IGZhbGxzIGJlbG93IHRoaXMpCiNkZWZpbmUgTUFYX0lURVIgMTAwCgovLyBGdW5jdGlvbiB0byBwcmludCBhIG1hdHJpeAp2b2lkIHByaW50X21hdHJpeChkb3VibGUgbWF0W05dW05dKSB7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IE47IGkrKykgewogICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgTjsgaisrKSB7CiAgICAgICAgICAgIHByaW50ZigiJTcuNGYgIiwgbWF0W2ldW2pdKTsKICAgICAgICB9CiAgICAgICAgcHJpbnRmKCJcbiIpOwogICAgfQp9CgppbnQgbWFpbigpIHsKICAgIC8vIEluaXRpYWwgTWF0cml4IEEgRGVmaW5pdGlvbgogICAgZG91YmxlIEFbTl1bTl0gPSB7CiAgICAgICAgezUuMCwgNC4wLCAxLjAsIDEuMH0sCiAgICAgICAgezQuMCwgNS4wLCAxLjAsIDEuMH0sCiAgICAgICAgezEuMCwgMS4wLCA0LjAsIDIuMH0sCiAgICAgICAgezEuMCwgMS4wLCAyLjAsIDQuMH0KICAgIH07CgogICAgLy8gQmFja3VwIHRoZSBvcmlnaW5hbCBtYXRyaXggQSBmb3IgdmVyaWZpY2F0aW9uIGxhdGVyCiAgICBkb3VibGUgQV9vcmlnW05dW05dOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBOOyBpKyspCiAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBOOyBqKyspCiAgICAgICAgICAgIEFfb3JpZ1tpXVtqXSA9IEFbaV1bal07CgogICAgLy8gRWlnZW52ZWN0b3IgbWF0cml4IFAgKGluaXRpYWxpemVkIGFzIGFuIElkZW50aXR5IE1hdHJpeCkKICAgIGRvdWJsZSBQW05dW05dID0gezB9OwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBOOyBpKyspIFBbaV1baV0gPSAxLjA7CgogICAgaW50IGl0ZXIgPSAwOwogICAgcHJpbnRmKCI9PT0gSmFjb2JpIE1ldGhvZCBDb252ZXJnZW5jZSBQcm9jZXNzID09PVxuXG4iKTsKCiAgICB3aGlsZSAoaXRlciA8IE1BWF9JVEVSKSB7CiAgICAgICAgLy8gMS4gRmluZCB0aGUgbWF4aW11bSBvZmYtZGlhZ29uYWwgZWxlbWVudCBBW3BdW3FdCiAgICAgICAgaW50IHAgPSAwLCBxID0gMTsKICAgICAgICBkb3VibGUgbWF4X3ZhbCA9IGZhYnMoQVswXVsxXSk7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBOOyBpKyspIHsKICAgICAgICAgICAgZm9yIChpbnQgaiA9IGkgKyAxOyBqIDwgTjsgaisrKSB7CiAgICAgICAgICAgICAgICBpZiAoZmFicyhBW2ldW2pdKSA+IG1heF92YWwpIHsKICAgICAgICAgICAgICAgICAgICBtYXhfdmFsID0gZmFicyhBW2ldW2pdKTsKICAgICAgICAgICAgICAgICAgICBwID0gaTsKICAgICAgICAgICAgICAgICAgICBxID0gajsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gT3V0cHV0IGNvbnZlcmdlbmNlIHN0YXR1cyB0byB0cmFjayByZWR1Y3Rpb24gb2Ygb2ZmLWRpYWdvbmFsIGVsZW1lbnRzCiAgICAgICAgcHJpbnRmKCJJdGVyYXRpb24gJWQ6IE1heCBvZmYtZGlhZ29uYWwgPSAlZiAoYXQgQVslZF1bJWRdKVxuIiwgaXRlciwgbWF4X3ZhbCwgcCwgcSk7CgogICAgICAgIC8vIENvbnZlcmdlbmNlIGNoZWNrCiAgICAgICAgaWYgKG1heF92YWwgPCBFUFMpIHsKICAgICAgICAgICAgcHJpbnRmKCJcbi0tPiBTdWNjZXNzZnVsbHkgY29udmVyZ2VkISAoVG90YWwgaXRlcmF0aW9uczogJWQpXG5cbiIsIGl0ZXIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIC8vIDIuIENhbGN1bGF0ZSB0aGUgcm90YXRpb24gYW5nbGUgdGhldGEgKHBoaSkKICAgICAgICBkb3VibGUgcGhpLCBjb3NfdCwgc2luX3Q7CiAgICAgICAgaWYgKGZhYnMoQVtwXVtwXSAtIEFbcV1bcV0pIDwgMWUtMTIpIHsKICAgICAgICAgICAgcGhpID0gYWNvcygtMS4wKSAvIDQuMDsgLy8gNDUgZGVncmVlcyBpZiBkaWFnb25hbCBlbGVtZW50cyBhcmUgZXF1YWwKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBwaGkgPSAwLjUgKiBhdGFuMigyLjAgKiBBW3BdW3FdLCBBW3BdW3BdIC0gQVtxXVtxXSk7CiAgICAgICAgfQogICAgICAgIGNvc190ID0gY29zKHBoaSk7CiAgICAgICAgc2luX3QgPSBzaW4ocGhpKTsKCiAgICAgICAgLy8gMy4gVXBkYXRlIE1hdHJpeCBBIChQXlQgKiBBICogUCkKICAgICAgICBkb3VibGUgQXBfb2xkID0gQVtwXVtwXTsKICAgICAgICBkb3VibGUgQXFfb2xkID0gQVtxXVtxXTsKICAgICAgICAKICAgICAgICBBW3BdW3BdID0gQXBfb2xkICogY29zX3QgKiBjb3NfdCArIEFxX29sZCAqIHNpbl90ICogc2luX3QgKyAyLjAgKiBBW3BdW3FdICogc2luX3QgKiBjb3NfdDsKICAgICAgICBBW3FdW3FdID0gQXBfb2xkICogc2luX3QgKiBzaW5fdCArIEFxX29sZCAqIGNvc190ICogY29zX3QgLSAyLjAgKiBBW3BdW3FdICogc2luX3QgKiBjb3NfdDsKICAgICAgICBBW3BdW3FdID0gQVtxXVtwXSA9IDAuMDsgLy8gWmVybyBvdXQgdGhlIHRhcmdldCBlbGVtZW50CgogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgTjsgaSsrKSB7CiAgICAgICAgICAgIGlmIChpICE9IHAgJiYgaSAhPSBxKSB7CiAgICAgICAgICAgICAgICBkb3VibGUgYV9pcCA9IEFbaV1bcF07CiAgICAgICAgICAgICAgICBkb3VibGUgYV9pcSA9IEFbaV1bcV07CiAgICAgICAgICAgICAgICBBW2ldW3BdID0gQVtwXVtpXSA9IGFfaXAgKiBjb3NfdCArIGFfaXEgKiBzaW5fdDsKICAgICAgICAgICAgICAgIEFbaV1bcV0gPSBBW3FdW2ldID0gLWFfaXAgKiBzaW5fdCArIGFfaXEgKiBjb3NfdDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gNC4gVXBkYXRlIEVpZ2VudmVjdG9yIE1hdHJpeCBQIChQID0gUCAqIFBfaykKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IE47IGkrKykgewogICAgICAgICAgICBkb3VibGUgcF9pcCA9IFBbaV1bcF07CiAgICAgICAgICAgIGRvdWJsZSBwX2lxID0gUFtpXVtxXTsKICAgICAgICAgICAgUFtpXVtwXSA9IHBfaXAgKiBjb3NfdCArIHBfaXEgKiBzaW5fdDsKICAgICAgICAgICAgUFtpXVtxXSA9IC1wX2lwICogc2luX3QgKyBwX2lxICogY29zX3Q7CiAgICAgICAgfQoKICAgICAgICBpdGVyKys7CiAgICB9CgogICAgLy8gPT09IERpc3BsYXkgUmVzdWx0cyA9PT0KICAgIHByaW50ZigiPT09IEZpbmFsIFJlc3VsdHMgPT09XG4iKTsKICAgIHByaW50ZigiRGlhZ29uYWxpemVkIE1hdHJpeCBBIChEaWFnb25hbCBFbGVtZW50cyA9IEVpZ2VudmFsdWVzKTpcbiIpOwogICAgcHJpbnRfbWF0cml4KEEpOwogICAgcHJpbnRmKCJcbiIpOwoKICAgIC8vID09PSBWZXJpZmljYXRpb24gb2YgQXggPSBsYW1iZGEgKiB4ID09PQogICAgcHJpbnRmKCI9PT0gVmVyaWZpY2F0aW9uIChBeCAtIGxhbWJkYSAqIHgpID09PVxuIik7CiAgICBwcmludGYoIk5vdGU6IElmIHRoZSB2YWx1ZXMgYXJlIGV4dHJlbWVseSBjbG9zZSB0byAwLCB0aGUgbWF0aCBob2xkcyB0cnVlIVxuXG4iKTsKCiAgICBmb3IgKGludCBqID0gMDsgaiA8IE47IGorKykgewogICAgICAgIGRvdWJsZSBsYW1iZGEgPSBBW2pdW2pdOwogICAgICAgIHByaW50ZigiRWlnZW52YWx1ZSAlZDogJTcuNGYgVmVyaWZpY2F0aW9uIEVycm9yOlxuIiwgaiArIDEsIGxhbWJkYSk7CiAgICAgICAgCiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBOOyBpKyspIHsKICAgICAgICAgICAgLy8gQ29tcHV0ZSBBeAogICAgICAgICAgICBkb3VibGUgQXggPSAwLjA7CiAgICAgICAgICAgIGZvciAoaW50IGsgPSAwOyBrIDwgTjsgaysrKSB7CiAgICAgICAgICAgICAgICBBeCArPSBBX29yaWdbaV1ba10gKiBQW2tdW2pdOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIENvbXB1dGUgbGFtYmRhICogeAogICAgICAgICAgICBkb3VibGUgcnggPSBsYW1iZGEgKiBQW2ldW2pdOwogICAgICAgICAgICAKICAgICAgICAgICAgLy8gT3V0cHV0IHRoZSBkaWZmZXJlbmNlIChSZXNpZHVhbCBFcnJvcikKICAgICAgICAgICAgcHJpbnRmKCIgIFJvdyAlZDogJTEwLjNlXG4iLCBpICsgMSwgQXggLSByeCk7CiAgICAgICAgfQogICAgICAgIHByaW50ZigiXG4iKTsKICAgIH0KCiAgICByZXR1cm4gMDsKfQo=