📄 unpower_method.cpp
字号:
//反幂法求方阵的按模最小特征值及对应特征向量。
#include<iostream.h>
#include<math.h>
#include<stdlib.h>
#include<stdio.h>
#define eps 0.000001
#define N 10
void doolittle(double a[N][N],double b[N],double x[N],int n){
int i,j,k,r;//其中 b[N]=u[N];x[N]=v[N]
double l[N][N],u[N][N],y[N];
for(i=0;i<n;i++){
for(j=0;j<n;j++){
if(i==j)l[i][i]=1.0;
else l[i][j]=0.0;
if(i>j)u[i][j]=0.0;
}
}
for(k=0;k<n;k++){
for(j=k;j<n;j++){//计算U中的第K行元素
u[k][j]=a[k][j];
for(r=0;r<=k-1;r++)u[k][j]=u[k][j]-l[k][r]*u[r][j];
}
for(i=k+1;i<n;i++){//计算L中的第K行元素
l[i][k]=a[i][k];
for(r=0;r<=k-1;r++)l[i][k]=l[i][k]-l[i][r]*u[r][k];
l[i][k]/=u[k][k];
}
}
/* //-------------------------------------------
printf("l=:");
for(i=0;i<n;i++){
for(j=0;j<n;j++)printf("\t%12lf",l[i][j]);printf("\n");}
printf("\n");
printf("u=:");
for(i=0;i<n;i++){
for(j=0;j<n;j++)printf("\t%12lf",u[i][j]);printf("\n");}
printf("\n");
//----------------------------------------------*/
for(i=0;i<n;i++){
y[i]=b[i];//由LY=B求Y
for(j=0;j<=i-1;j++)y[i]=y[i]-l[i][j]*y[j];
}
for(i=n-1;i>=0;i--){
x[i]=y[i];//由UX=Y求X
for(j=i+1;j<n;j++)y[i]=y[i]-u[i][j]*x[j];
x[i]=y[i]/u[i][i];
//printf("x%d=%5.4f\t",i,x[i]);
};
/* //----------------
printf("\tx=:");
for(i=0;i<n;i++){
for(j=0;j<i-1;j++)printf("\t%5.4f",l[i][j]);}
printf("\n");
//----------*/
}
double fanshu(double x[],int n){//求无穷范数||(x[])||∞
double norm;
int i;
norm=fabs(x[0]);
for(i=1;i<n;i++){
if(fabs(x[i])>norm)norm=fabs(x[i]);
}
return(norm);
}
void unpower_method(double a[N][N],int m){//规范化幂法实现反幂法
double v0[N],v1[N],v10[N],u[N],vx[N];//v0[]存放vk;v1[]存放vk+1;v10[]为v0[]与vi[]的差向量
int i,j;
for(i=0;i<m;i++){
v0[i]=0;v1[i]=1;v10[i]=v1[i]-v0[i];
u[i]=v1[i];//要在循环计算v1时要给u提前赋初值,不能在循环内部赋。
}
while((fanshu(v10,m)>=eps)){
for(i=0;i<m;i++)v0[i]=v1[i];
doolittle(a,u,v1,m);//计算av1(k)=u(k)采用LU分解法求得v1(k)
for(i=0;i<m;i++)u[i]=v1[i]/fanshu(v1,m);//规范化
for(i=0;i<m;i++)v10[i]=v1[i]-v0[i];
}
printf("\n\n\t 反幂法求方阵的按模最小特征值及对应特征向量:\n");
printf("\t***********************************************************\n");
printf("\t 特征值:%5.4lf\n",1/fanshu(v1,m));
printf("\t 特征向量:( ");
for(i=0;i<m;i++)printf("%5.4lf ",u[i]);
printf(" )\n");
printf("\t***********************************************************\n");
printf("\n");
}
main(){
double a[N][N]={{133,6,135},{44,5,46},{-88,-6,-90}};
unpower_method(a,3);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -