#include <stdio.h>
#include <math.h>
#include <complex.h>
#define N 4
#define EPS 1e-8
#define MAX_ITER 100
double complex 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}
};
/* LU decomposition */
void lu_decomposition(double complex B[N][N],
double complex L[N][N],
double complex 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*I:0.0+0.0*I;
U[i][j]=0.0+0.0*I;
}
}
for(int i=0;i<N;i++){
for(int j=i;j<N;j++){
double complex sum = 0.0 + 0.0*I;
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 complex sum = 0.0 + 0.0*I;
for(int k=0;k<i;k++)
sum += L[j][k]*U[k][i];
L[j][i] = (B[j][i]-sum)/U[i][i];
}
}
}
/* Forward substitution */
void forward_substitution(double complex L[N][N],
double complex x[N],
double complex y[N])
{
for(int i=0;i<N;i++){
double complex sum = 0.0 + 0.0*I;
for(int j=0;j<i;j++)
sum += L[i][j]*y[j];
y[i] = x[i] - sum;
}
}
/* Backward substitution */
void backward_substitution(double complex U[N][N],
double complex y[N],
double complex x[N])
{
for(int i=N-1;i>=0;i--){
double complex sum = 0.0 + 0.0*I;
for(int j=i+1;j<N;j++)
sum += U[i][j]*x[j];
x[i] = (y[i]-sum)/U[i][i];
}
}
void inverse_iteration(double complex lambda_hat)
{
double complex B[N][N];
double complex L[N][N];
double complex U[N][N];
double complex x[N] =
{
1.0+0.0*I,
1.0+0.0*I,
1.0+0.0*I,
1.0+0.0*I
};
double complex y[N];
double complex x_next[N];
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
B[i][j] = A[i][j];
if(i==j)
B[i][j] -= lambda_hat;
}
}
lu_decomposition(B,L,U);
printf("\n=====================================\n"); printf("shift = %.6f %+ .6fi\n", printf("=====================================\n");
int iter=0;
double diff;
double complex lambda = 0.0 + 0.0*I;
do{
forward_substitution(L,x,y);
backward_substitution(U,y,x_next);
/* largest magnitude component */
double max_mag = 0.0;
int idx = 0;
for(int i=0;i<N;i++){
if(cabs(x_next
[i
]) > max_mag
){ max_mag
= cabs(x_next
[i
]); idx = i;
}
}
double complex scale = x_next[idx];
for(int i=0;i<N;i++)
x_next[i] /= scale;
diff = 0.0;
for(int i=0;i<N;i++)
diff
+= cabs(x_next
[i
]-x
[i
]);
for(int i=0;i<N;i++)
x[i]=x_next[i];
lambda = lambda_hat + 1.0/scale;
printf("Iter %2d : lambda = %.8f %+ .8fi\n", iter+1,
iter++;
}while(diff>EPS && iter<MAX_ITER);
printf("\nFinal eigenvalue:\n");
for(int i=0;i<N;i++){
}
}
int main()
{
inverse_iteration(-5.4 + 0.0*I);
inverse_iteration(-2.1 + 1.7*I);
inverse_iteration(-2.1 - 1.7*I);
return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxtYXRoLmg+CiNpbmNsdWRlIDxjb21wbGV4Lmg+CgojZGVmaW5lIE4gNAojZGVmaW5lIEVQUyAxZS04CiNkZWZpbmUgTUFYX0lURVIgMTAwCgpkb3VibGUgY29tcGxleCBBW05dW05dID0gewogICAgezEuMCwgMi4wLCAzLjAsIDUuMH0sCiAgICB7My4wLCAtNS4wLCAxLjAsIDQuMH0sCiAgICB7NS4wLCA5LjAsIDIuMCwgLTYuMH0sCiAgICB7MS4wLCA3LjAsIDQuMCwgMS4wfQp9OwoKLyogTFUgZGVjb21wb3NpdGlvbiAqLwp2b2lkIGx1X2RlY29tcG9zaXRpb24oZG91YmxlIGNvbXBsZXggQltOXVtOXSwKICAgICAgICAgICAgICAgICAgICAgIGRvdWJsZSBjb21wbGV4IExbTl1bTl0sCiAgICAgICAgICAgICAgICAgICAgICBkb3VibGUgY29tcGxleCBVW05dW05dKQp7CiAgICBmb3IoaW50IGk9MDtpPE47aSsrKXsKICAgICAgICBmb3IoaW50IGo9MDtqPE47aisrKXsKICAgICAgICAgICAgTFtpXVtqXT0oaT09aik/MS4wKzAuMCpJOjAuMCswLjAqSTsKICAgICAgICAgICAgVVtpXVtqXT0wLjArMC4wKkk7CiAgICAgICAgfQogICAgfQoKICAgIGZvcihpbnQgaT0wO2k8TjtpKyspewoKICAgICAgICBmb3IoaW50IGo9aTtqPE47aisrKXsKICAgICAgICAgICAgZG91YmxlIGNvbXBsZXggc3VtID0gMC4wICsgMC4wKkk7CgogICAgICAgICAgICBmb3IoaW50IGs9MDtrPGk7aysrKQogICAgICAgICAgICAgICAgc3VtICs9IExbaV1ba10qVVtrXVtqXTsKCiAgICAgICAgICAgIFVbaV1bal0gPSBCW2ldW2pdIC0gc3VtOwogICAgICAgIH0KCiAgICAgICAgZm9yKGludCBqPWkrMTtqPE47aisrKXsKICAgICAgICAgICAgZG91YmxlIGNvbXBsZXggc3VtID0gMC4wICsgMC4wKkk7CgogICAgICAgICAgICBmb3IoaW50IGs9MDtrPGk7aysrKQogICAgICAgICAgICAgICAgc3VtICs9IExbal1ba10qVVtrXVtpXTsKCiAgICAgICAgICAgIExbal1baV0gPSAoQltqXVtpXS1zdW0pL1VbaV1baV07CiAgICAgICAgfQogICAgfQp9CgovKiBGb3J3YXJkIHN1YnN0aXR1dGlvbiAqLwp2b2lkIGZvcndhcmRfc3Vic3RpdHV0aW9uKGRvdWJsZSBjb21wbGV4IExbTl1bTl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlIGNvbXBsZXggeFtOXSwKICAgICAgICAgICAgICAgICAgICAgICAgICBkb3VibGUgY29tcGxleCB5W05dKQp7CiAgICBmb3IoaW50IGk9MDtpPE47aSsrKXsKCiAgICAgICAgZG91YmxlIGNvbXBsZXggc3VtID0gMC4wICsgMC4wKkk7CgogICAgICAgIGZvcihpbnQgaj0wO2o8aTtqKyspCiAgICAgICAgICAgIHN1bSArPSBMW2ldW2pdKnlbal07CgogICAgICAgIHlbaV0gPSB4W2ldIC0gc3VtOwogICAgfQp9CgovKiBCYWNrd2FyZCBzdWJzdGl0dXRpb24gKi8Kdm9pZCBiYWNrd2FyZF9zdWJzdGl0dXRpb24oZG91YmxlIGNvbXBsZXggVVtOXVtOXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlIGNvbXBsZXggeVtOXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlIGNvbXBsZXggeFtOXSkKewogICAgZm9yKGludCBpPU4tMTtpPj0wO2ktLSl7CgogICAgICAgIGRvdWJsZSBjb21wbGV4IHN1bSA9IDAuMCArIDAuMCpJOwoKICAgICAgICBmb3IoaW50IGo9aSsxO2o8TjtqKyspCiAgICAgICAgICAgIHN1bSArPSBVW2ldW2pdKnhbal07CgogICAgICAgIHhbaV0gPSAoeVtpXS1zdW0pL1VbaV1baV07CiAgICB9Cn0KCnZvaWQgaW52ZXJzZV9pdGVyYXRpb24oZG91YmxlIGNvbXBsZXggbGFtYmRhX2hhdCkKewogICAgZG91YmxlIGNvbXBsZXggQltOXVtOXTsKICAgIGRvdWJsZSBjb21wbGV4IExbTl1bTl07CiAgICBkb3VibGUgY29tcGxleCBVW05dW05dOwoKICAgIGRvdWJsZSBjb21wbGV4IHhbTl0gPQogICAgewogICAgICAgIDEuMCswLjAqSSwKICAgICAgICAxLjArMC4wKkksCiAgICAgICAgMS4wKzAuMCpJLAogICAgICAgIDEuMCswLjAqSQogICAgfTsKCiAgICBkb3VibGUgY29tcGxleCB5W05dOwogICAgZG91YmxlIGNvbXBsZXggeF9uZXh0W05dOwoKICAgIGZvcihpbnQgaT0wO2k8TjtpKyspewogICAgICAgIGZvcihpbnQgaj0wO2o8TjtqKyspewoKICAgICAgICAgICAgQltpXVtqXSA9IEFbaV1bal07CgogICAgICAgICAgICBpZihpPT1qKQogICAgICAgICAgICAgICAgQltpXVtqXSAtPSBsYW1iZGFfaGF0OwogICAgICAgIH0KICAgIH0KCiAgICBsdV9kZWNvbXBvc2l0aW9uKEIsTCxVKTsKCiAgICBwcmludGYoIlxuPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuIik7CiAgICBwcmludGYoInNoaWZ0ID0gJS42ZiAlKyAuNmZpXG4iLAogICAgICAgICAgIGNyZWFsKGxhbWJkYV9oYXQpLCBjaW1hZyhsYW1iZGFfaGF0KSk7CiAgICBwcmludGYoIj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiIpOwoKICAgIGludCBpdGVyPTA7CiAgICBkb3VibGUgZGlmZjsKICAgIGRvdWJsZSBjb21wbGV4IGxhbWJkYSA9IDAuMCArIDAuMCpJOwoKICAgIGRvewoKICAgICAgICBmb3J3YXJkX3N1YnN0aXR1dGlvbihMLHgseSk7CiAgICAgICAgYmFja3dhcmRfc3Vic3RpdHV0aW9uKFUseSx4X25leHQpOwoKICAgICAgICAvKiBsYXJnZXN0IG1hZ25pdHVkZSBjb21wb25lbnQgKi8KICAgICAgICBkb3VibGUgbWF4X21hZyA9IDAuMDsKICAgICAgICBpbnQgaWR4ID0gMDsKCiAgICAgICAgZm9yKGludCBpPTA7aTxOO2krKyl7CiAgICAgICAgICAgIGlmKGNhYnMoeF9uZXh0W2ldKSA+IG1heF9tYWcpewogICAgICAgICAgICAgICAgbWF4X21hZyA9IGNhYnMoeF9uZXh0W2ldKTsKICAgICAgICAgICAgICAgIGlkeCA9IGk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGRvdWJsZSBjb21wbGV4IHNjYWxlID0geF9uZXh0W2lkeF07CgogICAgICAgIGZvcihpbnQgaT0wO2k8TjtpKyspCiAgICAgICAgICAgIHhfbmV4dFtpXSAvPSBzY2FsZTsKCiAgICAgICAgZGlmZiA9IDAuMDsKCiAgICAgICAgZm9yKGludCBpPTA7aTxOO2krKykKICAgICAgICAgICAgZGlmZiArPSBjYWJzKHhfbmV4dFtpXS14W2ldKTsKCiAgICAgICAgZm9yKGludCBpPTA7aTxOO2krKykKICAgICAgICAgICAgeFtpXT14X25leHRbaV07CgogICAgICAgIGxhbWJkYSA9IGxhbWJkYV9oYXQgKyAxLjAvc2NhbGU7CgogICAgICAgIHByaW50ZigiSXRlciAlMmQgOiBsYW1iZGEgPSAlLjhmICUrIC44ZmlcbiIsCiAgICAgICAgICAgICAgIGl0ZXIrMSwKICAgICAgICAgICAgICAgY3JlYWwobGFtYmRhKSwKICAgICAgICAgICAgICAgY2ltYWcobGFtYmRhKSk7CgogICAgICAgIGl0ZXIrKzsKCiAgICB9d2hpbGUoZGlmZj5FUFMgJiYgaXRlcjxNQVhfSVRFUik7CgogICAgcHJpbnRmKCJcbkZpbmFsIGVpZ2VudmFsdWU6XG4iKTsKICAgIHByaW50ZigiJS4xMGYgJSsgLjEwZmlcbiIsCiAgICAgICAgICAgY3JlYWwobGFtYmRhKSwKICAgICAgICAgICBjaW1hZyhsYW1iZGEpKTsKCiAgICBwcmludGYoIlxuRWlnZW52ZWN0b3I6XG4iKTsKCiAgICBmb3IoaW50IGk9MDtpPE47aSsrKXsKICAgICAgICBwcmludGYoIiglLjZmICUrIC42ZmkpXG4iLAogICAgICAgICAgICAgICBjcmVhbCh4W2ldKSwKICAgICAgICAgICAgICAgY2ltYWcoeFtpXSkpOwogICAgfQp9CgppbnQgbWFpbigpCnsKICAgIGludmVyc2VfaXRlcmF0aW9uKC01LjQgKyAwLjAqSSk7CgogICAgaW52ZXJzZV9pdGVyYXRpb24oLTIuMSArIDEuNypJKTsKCiAgICBpbnZlcnNlX2l0ZXJhdGlvbigtMi4xIC0gMS43KkkpOwoKICAgIHJldHVybiAwOwp9Cg==