#include <stdio.h>
#include <math.h>
#define N 4
#define EPS 1e-6
#define MAX_ITER 100
// MATRIX 1 definition
double A[N][N] = {
{1.0, 2.0, 3.0, 5.0},
{3.0, -5.0, 1.0, 4.0},
{5.0, 9.0, 2.0, -6.0},
{1.0, 7.0, 4.0, 1.0}
};
// Standard LU decomposition as shown in the lecture
void lu_decomposition(double B[N][N], double L[N][N], double U[N][N]) {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
L[i][j] = (i == j) ? 1.0 : 0.0;
U[i][j] = 0.0;
}
}
for (int i = 0; i < N; i++) {
for (int j = i; j < N; j++) {
double sum = 0.0;
for (int k = 0; k < i; k++) sum += L[i][k] * U[k][j];
U[i][j] = B[i][j] - sum;
}
for (int j = i + 1; j < N; j++) {
double sum = 0.0;
for (int k = 0; k < i; k++) sum += L[j][k] * U[k][i];
L[j][i] = (B[j][i] - sum) / U[i][i];
}
}
}
void forward_substitution(double L[N][N], double x[N], double y[N]) {
for (int i = 0; i < N; i++) {
double sum = 0.0;
for (int j = 0; j < i; j++) sum += L[i][j] * y[j];
y[i] = x[i] - sum;
}
}
void backward_substitution(double U[N][N], double y[N], double x[N]) {
for (int i = N - 1; i >= 0; i--) {
double sum = 0.0;
for (int j = i + 1; j < N; j++) sum += U[i][j] * x[j];
x[i] = (y[i] - sum) / U[i][i];
}
}
void find_remaining_eigen(double lambda_hat) {
double B[N][N], L[N][N], U[N][N];
double y[N], x_next[N];
double x[N] = {1.0, 1.0, 1.0, 1.0}; // Initial vector x^(0)
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
B[i][j] = A[i][j] - (i == j ? lambda_hat : 0.0);
}
}
lu_decomposition(B, L, U);
printf("\n==================================================\n"); printf(" Shift (lambda_hat) = %.3f\n", lambda_hat
); printf("==================================================\n");
int iter = 0;
double diff;
double lambda = 0.0;
do {
forward_substitution(L, x, y); // Ly = x
backward_substitution(U, y, x_next); // Ux_next = y
// FIX: Scale by the first element x_next[0] exactly like Slide 57
double scale_factor = x_next[0];
for (int i = 0; i < N; i++) {
x_next[i] /= scale_factor;
}
// Convergence criteria calculation
diff = 0.0;
for (int i = 0; i < N; i++) {
diff
+= fabs(x_next
[i
] - x
[i
]); }
for (int i = 0; i < N; i++) {
x[i] = x_next[i];
}
// Slide 10 Formula: lambda = lambda_hat + 1 / scale_factor
lambda = lambda_hat + (1.0 / scale_factor);
iter++;
printf("Iter %2d: x = [%.4f, %.4f, %.4f, %.4f], lambda = %.6f\n", iter, x[0], x[1], x[2], x[3], lambda);
} while (diff > EPS && iter < MAX_ITER);
printf("\n Solution Found:\n"); printf(" Eigenvalue (lambda) = %.6f\n", lambda
); printf(" Eigenvector (x) = [%.4f, %.4f, %.4f, %.4f]\n", x
[0], x
[1], x
[2], x
[3]); }
int main() {
// Test a negative shift to pull out the remaining real eigenvalue cleanly
find_remaining_eigen(-6.0);
return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxtYXRoLmg+CgojZGVmaW5lIE4gNAojZGVmaW5lIEVQUyAxZS02CiNkZWZpbmUgTUFYX0lURVIgMTAwCgovLyBNQVRSSVggMSBkZWZpbml0aW9uCmRvdWJsZSBBW05dW05dID0geyAKICAgIHsxLjAsIDIuMCwgMy4wLCA1LjB9LCAKICAgIHszLjAsIC01LjAsIDEuMCwgNC4wfSwgCiAgICB7NS4wLCA5LjAsIDIuMCwgLTYuMH0sIAogICAgezEuMCwgNy4wLCA0LjAsIDEuMH0gCn07CgovLyBTdGFuZGFyZCBMVSBkZWNvbXBvc2l0aW9uIGFzIHNob3duIGluIHRoZSBsZWN0dXJlCnZvaWQgbHVfZGVjb21wb3NpdGlvbihkb3VibGUgQltOXVtOXSwgZG91YmxlIExbTl1bTl0sIGRvdWJsZSBVW05dW05dKSB7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IE47IGkrKykgewogICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgTjsgaisrKSB7CiAgICAgICAgICAgIExbaV1bal0gPSAoaSA9PSBqKSA/IDEuMCA6IDAuMDsKICAgICAgICAgICAgVVtpXVtqXSA9IDAuMDsKICAgICAgICB9CiAgICB9CiAgICBmb3IgKGludCBpID0gMDsgaSA8IE47IGkrKykgewogICAgICAgIGZvciAoaW50IGogPSBpOyBqIDwgTjsgaisrKSB7CiAgICAgICAgICAgIGRvdWJsZSBzdW0gPSAwLjA7CiAgICAgICAgICAgIGZvciAoaW50IGsgPSAwOyBrIDwgaTsgaysrKSBzdW0gKz0gTFtpXVtrXSAqIFVba11bal07CiAgICAgICAgICAgIFVbaV1bal0gPSBCW2ldW2pdIC0gc3VtOwogICAgICAgIH0KICAgICAgICBmb3IgKGludCBqID0gaSArIDE7IGogPCBOOyBqKyspIHsKICAgICAgICAgICAgZG91YmxlIHN1bSA9IDAuMDsKICAgICAgICAgICAgZm9yIChpbnQgayA9IDA7IGsgPCBpOyBrKyspIHN1bSArPSBMW2pdW2tdICogVVtrXVtpXTsKICAgICAgICAgICAgTFtqXVtpXSA9IChCW2pdW2ldIC0gc3VtKSAvIFVbaV1baV07CiAgICAgICAgfQogICAgfQp9Cgp2b2lkIGZvcndhcmRfc3Vic3RpdHV0aW9uKGRvdWJsZSBMW05dW05dLCBkb3VibGUgeFtOXSwgZG91YmxlIHlbTl0pIHsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgTjsgaSsrKSB7CiAgICAgICAgZG91YmxlIHN1bSA9IDAuMDsKICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGk7IGorKykgc3VtICs9IExbaV1bal0gKiB5W2pdOwogICAgICAgIHlbaV0gPSB4W2ldIC0gc3VtOwogICAgfQp9Cgp2b2lkIGJhY2t3YXJkX3N1YnN0aXR1dGlvbihkb3VibGUgVVtOXVtOXSwgZG91YmxlIHlbTl0sIGRvdWJsZSB4W05dKSB7CiAgICBmb3IgKGludCBpID0gTiAtIDE7IGkgPj0gMDsgaS0tKSB7CiAgICAgICAgZG91YmxlIHN1bSA9IDAuMDsKICAgICAgICBmb3IgKGludCBqID0gaSArIDE7IGogPCBOOyBqKyspIHN1bSArPSBVW2ldW2pdICogeFtqXTsKICAgICAgICB4W2ldID0gKHlbaV0gLSBzdW0pIC8gVVtpXVtpXTsKICAgIH0KfQoKdm9pZCBmaW5kX3JlbWFpbmluZ19laWdlbihkb3VibGUgbGFtYmRhX2hhdCkgewogICAgZG91YmxlIEJbTl1bTl0sIExbTl1bTl0sIFVbTl1bTl07CiAgICBkb3VibGUgeVtOXSwgeF9uZXh0W05dOwogICAgZG91YmxlIHhbTl0gPSB7MS4wLCAxLjAsIDEuMCwgMS4wfTsgLy8gSW5pdGlhbCB2ZWN0b3IgeF4oMCkKCiAgICBmb3IgKGludCBpID0gMDsgaSA8IE47IGkrKykgewogICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgTjsgaisrKSB7CiAgICAgICAgICAgIEJbaV1bal0gPSBBW2ldW2pdIC0gKGkgPT0gaiA/IGxhbWJkYV9oYXQgOiAwLjApOwogICAgICAgIH0KICAgIH0KCiAgICBsdV9kZWNvbXBvc2l0aW9uKEIsIEwsIFUpOwoKICAgIHByaW50ZigiXG49PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuIik7CiAgICBwcmludGYoIiBTaGlmdCAobGFtYmRhX2hhdCkgPSAlLjNmXG4iLCBsYW1iZGFfaGF0KTsKICAgIHByaW50ZigiPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiIpOwoKICAgIGludCBpdGVyID0gMDsKICAgIGRvdWJsZSBkaWZmOwogICAgZG91YmxlIGxhbWJkYSA9IDAuMDsKCiAgICBkbyB7CiAgICAgICAgZm9yd2FyZF9zdWJzdGl0dXRpb24oTCwgeCwgeSk7ICAgICAgLy8gTHkgPSB4CiAgICAgICAgYmFja3dhcmRfc3Vic3RpdHV0aW9uKFUsIHksIHhfbmV4dCk7IC8vIFV4X25leHQgPSB5CgogICAgICAgIC8vIEZJWDogU2NhbGUgYnkgdGhlIGZpcnN0IGVsZW1lbnQgeF9uZXh0WzBdIGV4YWN0bHkgbGlrZSBTbGlkZSA1NwogICAgICAgIGRvdWJsZSBzY2FsZV9mYWN0b3IgPSB4X25leHRbMF07IAoKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IE47IGkrKykgewogICAgICAgICAgICB4X25leHRbaV0gLz0gc2NhbGVfZmFjdG9yOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29udmVyZ2VuY2UgY3JpdGVyaWEgY2FsY3VsYXRpb24KICAgICAgICBkaWZmID0gMC4wOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgTjsgaSsrKSB7CiAgICAgICAgICAgIGRpZmYgKz0gZmFicyh4X25leHRbaV0gLSB4W2ldKTsKICAgICAgICB9CgogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgTjsgaSsrKSB7CiAgICAgICAgICAgIHhbaV0gPSB4X25leHRbaV07CiAgICAgICAgfQoKICAgICAgICAvLyBTbGlkZSAxMCBGb3JtdWxhOiBsYW1iZGEgPSBsYW1iZGFfaGF0ICsgMSAvIHNjYWxlX2ZhY3RvcgogICAgICAgIGxhbWJkYSA9IGxhbWJkYV9oYXQgKyAoMS4wIC8gc2NhbGVfZmFjdG9yKTsKICAgICAgICBpdGVyKys7CgogICAgICAgIHByaW50ZigiSXRlciAlMmQ6IHggPSBbJS40ZiwgJS40ZiwgJS40ZiwgJS40Zl0sIGxhbWJkYSA9ICUuNmZcbiIsIAogICAgICAgICAgICAgICBpdGVyLCB4WzBdLCB4WzFdLCB4WzJdLCB4WzNdLCBsYW1iZGEpOwoKICAgIH0gd2hpbGUgKGRpZmYgPiBFUFMgJiYgaXRlciA8IE1BWF9JVEVSKTsKCiAgICBwcmludGYoIlxuIFNvbHV0aW9uIEZvdW5kOlxuIik7CiAgICBwcmludGYoIiBFaWdlbnZhbHVlIChsYW1iZGEpID0gJS42ZlxuIiwgbGFtYmRhKTsKICAgIHByaW50ZigiIEVpZ2VudmVjdG9yICh4KSAgICA9IFslLjRmLCAlLjRmLCAlLjRmLCAlLjRmXVxuIiwgeFswXSwgeFsxXSwgeFsyXSwgeFszXSk7Cn0KCmludCBtYWluKCkgewogICAgLy8gVGVzdCBhIG5lZ2F0aXZlIHNoaWZ0IHRvIHB1bGwgb3V0IHRoZSByZW1haW5pbmcgcmVhbCBlaWdlbnZhbHVlIGNsZWFubHkKICAgIGZpbmRfcmVtYWluaW5nX2VpZ2VuKC02LjApOwogICAgcmV0dXJuIDA7Cn0K
==================================================
Shift (lambda_hat) = -6.000
==================================================
Iter 1: x = [1.0000, 1.8667, -2.8000, -0.2667], lambda = -5.000000
Iter 2: x = [1.0000, 1.7750, -2.9619, -0.2426], lambda = -5.548495
Iter 3: x = [1.0000, 1.7585, -2.9594, -0.2276], lambda = -5.499430
Iter 4: x = [1.0000, 1.7568, -2.9590, -0.2254], lambda = -5.490355
Iter 5: x = [1.0000, 1.7567, -2.9590, -0.2251], lambda = -5.489339
Iter 6: x = [1.0000, 1.7567, -2.9590, -0.2251], lambda = -5.489256
Iter 7: x = [1.0000, 1.7567, -2.9590, -0.2251], lambda = -5.489253
Iter 8: x = [1.0000, 1.7567, -2.9590, -0.2251], lambda = -5.489254
Solution Found:
Eigenvalue (lambda) = -5.489254
Eigenvector (x) = [1.0000, 1.7567, -2.9590, -0.2251]