⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hessenbergandqr.cpp

📁 矩阵上hessenberg化及QR方法(带原点位移)
💻 CPP
字号:
//===========================================
//矩阵上hessenberg化及QR方法(带原点位移)
//===========================================
#include <stdio.h>
#include <math.h>
#include <iostream.h>
//--------------------------------------------
void main(){
//变量声明-----------------------------------
    int n;                                 //矩阵阶数
    double a1[20][20],a2[20][20];              
    double u[20][20]={0};
    double h[20][20];
    int i,j,k,l,m;
    double alpha;
    double b;
//输入---------------------------------------
	cout<<"请输入矩阵阶数:"<<endl;
	cin>>n;
	cout<<"请输入矩阵元素:"<<endl;
	for(i=1;i<=n;i++){
		for(j=1;j<=n;j++){
			cin>>a1[i][j];
		}
	}
//--------------------------------------------
	for(k=1;k<=n-2;k++){
	//计算alpha
		alpha=0;
		for(i=k+1;i<=n;i++){
			alpha=alpha+a1[i][k]*a1[i][k];
		}
		alpha=sqrt(alpha);
		if(a1[k+1][k]>=0)alpha=-alpha;
	//计算第k次的u向量
		u[k][k+1]=a1[k+1][k]-alpha;
		for(j=k+2;j<=n;j++){
			u[k][j]=a1[j][k];
		}
	//计算b
		b=alpha*(alpha-a1[k+1][k]);
	//计算内部householder矩阵
		for(i=k+1;i<=n;i++){
			for(j=k+1;j<=n;j++){
				if(i==j)h[i][j]=1-u[k][i]*u[k][j]/b;
				else h[i][j]=-u[k][i]*u[k][j]/b;
			}
		}
	//计算经过一次变换后的矩阵
		//i<=k&&j>k时
        for(i=1;i<=k;i++){
			for(j=k+1;j<=n;j++){
				a2[i][j]=0;
				for(l=k+1;l<=n;l++){
					a2[i][j]=a2[i][j]+a1[i][l]*h[l][j];
				}
			}
		}
		//i>k&&j<=k时
		for(i=k+1;i<=n;i++){
			for(j=1;j<=k;j++){
				a2[i][j]=0;
				for(m=k+1;m<=n;m++){
					a2[i][j]=a2[i][j]+h[i][m]*a1[m][j];
				}
			}
		}
        //i>k&&j>k时
		for(i=k+1;i<=n;i++){
			for(j=k+1;j<=n;j++){
				a2[i][j]=0;
				for(l=k+1;l<=n;l++){
					for(m=k+1;m<=n;m++){
						a2[i][j]=a2[i][j]+h[i][m]*a1[m][l]*h[l][j];
					}
				}
			}
		}
		for(i=1;i<=n;i++){
			for(j=1;j<=n;j++){
				if(i<=k&&j<=k)continue;
				a1[i][j]=a2[i][j];
			}
		}
	}
//输出最终变换后的hessenberg矩阵
	cout<<"Hessenberg矩阵为:"<<endl;
	for(i=1;i<=n;i++){
		for(j=1;j<=n;j++){
			if(fabs(a1[i][j])<0.000000001)a1[i][j]=0;
			cout<<a1[i][j]<<"\t";
		}
		cout<<endl;
	}
//QR方法(带原点平移)
	{
		double s[20],c[20],d;
		double delta=0.000000001;
		double t;
		for(m=1;fabs(a1[n][n-1])>delta*(fabs(a1[n][n])+fabs(a1[n-1][n-1]));m++){
			t=a1[n][n];
			a1[1][1]=a1[1][1]-t;
			for(k=1;k<=n;k++){
				if(k!=n){
				//确定R(k,k+1)
					if(a1[k+1][k]==0){
						c[k]=1;s[k]=0;d=a1[k][k];
					}
					else{
						d=sqrt(a1[k][k]*a1[k][k]+a1[k+1][k]*a1[k+1][k]);
						c[k]=a1[k][k]/d;
						s[k]=a1[k+1][k]/d;
					}
				//用R(k,k+1)左乘A-tI
					a1[k][k]=d;
					a1[k+1][k]=0;
					a1[k+1][k+1]=a1[k+1][k+1]-t;
					for(j=k+1;j<=n;j++){
						b=a1[k][j]*c[k]+a1[k+1][j]*s[k];
						a1[k+1][j]=-a1[k][j]*s[k]+a1[k+1][j]*c[k];
						a1[k][j]=b;
					}
				}
				if(k!=1){
					for(i=1;i<=k;i++){
						b=a1[i][k-1]*c[k-1]+a1[i][k]*s[k-1];
						a1[i][k]=-a1[i][k-1]*s[k-1]+a1[i][k]*c[k-1];
						a1[i][k-1]=b;
					}
					a1[k-1][k-1]=a1[k-1][k-1]+t;
				}
			}
			a1[n][n]=a1[n][n]+t;
		}
	//输出矩阵特征值
		cout<<"矩阵特征值为:"<<endl;
		for(i=1;i<=n;i++){
			cout<<a1[i][i]<<"\t";
		}
		cout<<endl;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -