/*LU분해 후 역행렬을 구하고 난뒤 최대 고유값을 구한다*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
double A[10][10],x0[10],sum[10],xR[10],B[10][10],c[10][10],L[10][10],U[10][10],b2[10],E[10],x[10],B[10][10];
int n;
void LUCrout();
void Reverse();
void LUCrout() {
int i,j,k;
double sum;
for(i=1;i<=n;i++)
L[i][1]=A[i][1];
for(j=1;j<=n;j++)
U[1][j]=A[1][j]/L[1][1];
for(j=2;j<=n;j++) {
for(i=j;i<=n;i++) {
sum=0;
for(k=1;k<=j-1;k++) sum=sum+L[i][k]*U[k][j];
L[i][j]=A[i][j]-sum;
}
U[j][j]=1;
for(i=j+1;i<=n;i++) {
sum=0.0;
for(k=1;k<=j-1;k++) sum=sum+L[j][k]*U[k][i];
U[j][i]=(A[j][i]-sum)/L[j][j];
}
}
}//end of LuCrout
void Reverse() {
int i,j,a;
double sum;
printf("역행렬을 구합니다\n");
for(a=1;a<=n;a++){
printf("역행렬을 구합니다. 단위 행렬을 입력해주세요\n");
for(i=1;i<=n;i++){
printf("E[%d]:",i);
scanf("%lf", &E[i]);
}
for(i=1;i<=n;i++){
sum=0;
for(j=1;j<=i-1;j++)
sum=sum+L[i][j]*b2[j];
b2[i]=(E[i]-sum)/L[i][i];
}
printf("\n");
for(i=n;i>=1;i--){
sum=0;
for(j=i+1;j<=n;j++)
sum=sum+U[i][j]*x[j];
x[i]=b2[i]-sum;
}
for(i=1;i<=n;i++)
printf("역행렬 x[%d]:%lf\n",i,x[i]);
for(i=1;i<=n;i++)
B[i][a]=x[i];
}
}// end of Reverse
int main(){
int i,j,k,repeat,v;
float ramda,temp,temp2,x1,deter;
printf("몇 행렬: ");
scanf("%d",&n);
printf("반복 횟수 입력:");
scanf("%d",&repeat);
printf("기본 행렬을 입력해 주세요:\n");
for(i=1;i<=n;i++) //행 입력
{
for(j=1;j<=n;j++) //열 입력
{
printf("A[%d][%d]:",i,j);
scanf("%lf",&A[i][j]);
}
}
LUCrout();
Reverse();
printf("역행렬(B): \n");
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
printf("%f\t",B[i][j]);
}
printf("\n");
}
for(i=1;i<=n;i++)
{
printf("초기 x(0)을 입력해 주세요: ");
scanf("%lf",&x0[i]);
}
v=1;
for(i=1;i<=repeat;i++) //수렴기준 대신에 반복 횟수로 카운트
{
for(j=1;j<=n;j++)
{
sum[j]=0;
for(k=1;k<=n;k++)
{
sum[j]=sum[j]+B[j][k]*x0[k]; // Y = sum, A역행렬=B
}
//printf("Y값 계산:%f\n",sum[j]);
}
temp = 0;
temp2 = 0;
for(j=1;j<=n;j++)
{
temp=x0[j]*sum[j]+temp; // temp는 lamda구하기 위한 임시 변수
//printf("x0[%d]=%f, temp:%f\t",j,x0[j], temp);
temp2=x0[j]*x0[j]+temp2;
//printf("temp2:%f\n",temp2);
ramda=temp/temp2;
}
//printf("Lamda:%f\n",ramda);
x1=0;
for(j=1;j<=n;j++)
x1=pow(sum[j],2)+x1;
x1=sqrt(x1);
//printf("x(1):%f\n",x1);
for(j=1;j<=n;j++)
x0[j]=sum[j]/x1;
printf("반복횟수:%d\t Lamda2:%f\t Lamda:%f\t x(1):%f\t x(2):%f\t x(3):%f\n",v,ramda,1/ramda,x0[1],x0[2],x0[3]);
v++;
}//end of repeat
}//end of main
'언어 > Coding' 카테고리의 다른 글
simpson 1/3 공식 (0) | 2015.12.22 |
---|---|
거듭제곱 (0) | 2015.12.22 |
Lagrange (0) | 2015.12.22 |
Gauss Seidel (0) | 2015.12.21 |
Jacobi (0) | 2015.12.21 |