矩阵分析之Householder Reduction

矩阵分析之Householder Reduction

我们都知道通过高斯消元法、初等行变换可以得到一个矩阵的行阶梯表达。但这不是唯一的方法。Householder reduction就可以完成这项任务。

1.Householder Reduction原理

矩阵分析之Householder Reduction_第1张图片
矩阵分析之Householder Reduction_第2张图片
矩阵分析之Householder Reduction_第3张图片

2.具体问题

给定一个矩阵 A ,求矩阵 P,T 使得 PA=T ,其中矩阵 T 为上三角矩阵,如果 A 是实数矩阵,则 P 为正交矩阵。给定 A 如下:

A=0342027111442

求矩阵 P,T ?
具体程序实现如下:

/**********************************************************
Description:Matrix Householder Reduction
Author:Robert.Tianyi
Date:2016.11.3
***********************************************************/ 
#include
#include
#include
#include
using namespace std;
float Get_Norm(float a[],int size);/*向量求模*/ 
float *VectorDivNum(float a[],float num,int len);/*向量除以一个数*/ 
float * VectorMULNum(float a[],float num,int len);/*向量数乘*/ 
float  VectorMUL(float a[],float b[],int len);/*向量内积*/
float * VectorADD(float a[],float b[],int len); /*向量加法*/ 
float * VectorSUB(float a[],float b[],int len);/*向量减法*/ 
float * MatrixMulMatrix(float *Pone,float *Rone,int m);//矩阵乘法 
float * VectorMulVector2Matrix(float *U,int sizeU,float *UT,int sizeUT);//向量乘法 
void Matrix_HouseholderReduction(float *B,int m,int n);//HouseholderReduction 
int main(){
    float A[3][3]={{0,-20,-14},{3,27,-4},{4,11,-2}};
    float B[9];
    cout<<"原始矩阵A:"<for(int i=0;i<3;i++){
        for(int j=0;j<3;j++){
            cout<6)<" ";
            B[i*3+j]=A[i][j];
        }
        cout<3,3); 
}
void Matrix_HouseholderReduction(float *B,int m,int n){
    float AA[m][n];
    for(int i=0;ifor(int j=0;jcout<<"进行HouseholderReduction:"<for(int i=0;i<3;i++){
        for(int j=0;j<3;j++){
            cout<6)<" ";   
        }
        cout<int k;//记录R矩阵个数 
    if(m>n)
        k=n;//矩阵R的个数 
    else
        k=m-1;//矩阵R的个数  
    float (*P)[m];
    P=(float (*)[m])malloc(sizeof(float)*(m)*(m));//初始化矩阵P为单位阵 
    for(int i=0;ifor(int j=0;j0;
            if(i==j){
                P[i][j]=1;
            }
        }
    }
    for(int temp_k=0;temp_kfloat A[m-temp_k][n-temp_k];
        //从AA矩阵读取每次需要的矩阵A_k
        for(int i=0;ifor(int j=0;jfloat I[m-temp_k][m-temp_k];//单位矩阵I 
        for(int i=0;ifor(int j=0;jif(i==j)
                    I[i][j]=1;
                else
                    I[i][j]=0;
            }
        }
        float A_0[m-temp_k],e1[m-temp_k];
        e1[0]=1;
        for(int i=1;i0;        
        }
        for(int i=0;i0];//取出A中的第0列 
        }
        cout<float *u1=new float[m-temp_k];
        u1=VectorSUB(A_0,VectorMULNum(e1,Get_Norm(A_0,m-temp_k),m-temp_k),m-temp_k);
        float *UmulUT=new float [(m-temp_k)*(m-temp_k)];
        UmulUT=VectorMulVector2Matrix(u1,m-temp_k,u1,m-temp_k); 
        float (*temp)[m-temp_k];
        int tt=0;
        temp=(float (*)[m-temp_k])malloc(sizeof(float)*(m-temp_k)*(m-temp_k));
        for(int i=0;ifor(int j=0;j//计算R_k 
        float R1[m][m];
        for(int i=0;ifor(int j=0;j2.0/VectorMUL(u1,u1,m-temp_k);  
            }
        }
        //计算当前矩阵R_k*A_k,矩阵相乘 
        float result[m-temp_k][n-temp_k];
        for(int i=0;ifloat *Rvector=new float[m-temp_k];
            for(int t=0;t//读取R的第i行 
                Rvector[t]=R1[i][t];    
            }
            for(int j=0;jfloat *Avector=new float[m-temp_k];
                for(int t=0;t//读取A的第J列 
                    Avector[t]=A[t][j]; 
                }
                result[i][j]=VectorMUL(Rvector,Avector,m-temp_k);
                if(result[i][j]<0.00001&&result[i][j]>-0.00001)//error 
                    result[i][j]=0;
            }
        }

        //对R_k进行还原成m-by-m的矩阵R 在根据temp_k对R矩阵更新
        float (*R)[m];
        R=(float (*)[m])malloc(sizeof(float)*(m)*(m));
        for(int i=0;ifor(int j=0;j0;
                if(i==j)
                    R[i][j]=1;
            }
        }
        for(int i=0;ifor(int j=0;j//更新计算矩阵P  每次要左乘新的R矩阵 大小都是m-by-m
        float *Pone=new float[m*m]; 
        float *Rone=new float[m*m];
        int t=0;
        for(int i=0;ifor(int j=0;jfloat *PmulR=new float [m*m];
        t=0;
        PmulR=MatrixMulMatrix(Pone,Rone,m);
        for(int i=0;ifor(int j=0;j//更新AA矩阵 将当前计算好的子A矩阵更新到原始矩阵AA中 
        for(int i=0;ifor(int j=0;j//输出矩阵T=P*A矩阵
    cout<<"矩阵P*A,即矩阵T:"<for(int i=0;ifor(int j=0;jcout<6)<" ";
        }
        cout<//输出矩阵P矩阵
    cout<<"矩阵P:"<for(int i=0;ifor(int j=0;jcout<6)<" ";
        }
        cout<float * MatrixMulMatrix(float *Pone,float *Rone,int m){
    int n=m;
    float *PmulR=new float [m*n];
    float result[m][n];
    float (*P)[m];
    P=(float (*)[m])malloc(sizeof(float)*(m)*(m));
    float (*R)[n];
    R=(float (*)[n])malloc(sizeof(float)*(n)*(n));
    int k=0;
    for(int i=0;ifor(int j=0;jfor(int i=0;i//读取R的第i行 
        float *Rvector=new float[m];
        for(int k=0;kfor(int j=0;j//读取P 第J列 
            float *Pvector=new float[m];
            for(int k=0;kreturn PmulR;
}
/*****************************************************
Description:向量相乘得到矩阵 大小为 sizea-by-sizeb 
a 为列向量
b 为行向量 
******************************************************/
float* VectorMulVector2Matrix(float *U,int sizeU,float *UT,int sizeUT){
    float *result=new float [sizeU*sizeUT];
    int k=0;
    for(int i=0;ifor(int j=0;jreturn result;  
} 
/*向量求模*/ 
float Get_Norm(float a[],int size){
    float sum=0;
    for(int i=0;ireturn sqrt(sum);   
}
/*向量除以一个数*/ 
float *VectorDivNum(float a[],float num,int len){
    float *p;
    p=new float[len];
    for(int i=0;ireturn p;
}
/*向量数乘*/ 
float * VectorMULNum(float a[],float num,int len){
    float *p;
    p=new float[len];
    for(int i=0;ireturn p;
}
/*向量内积*/ 
float  VectorMUL(float a[],float b[],int len){
    float *p;
    float result=0;
    for(int i=0;ireturn result;
}
/*向量加法*/ 
float * VectorADD(float a[],float b[],int len){
    float *p;
    p=new float[len];
    for(int i=0;ireturn p;
}
/*向量减法*/ 
float * VectorSUB(float a[],float b[],int len){
    float *p;
    p=new float[len];
    for(int i=0;ireturn p;
} 

结果如下图:
矩阵分析之Householder Reduction_第4张图片

你可能感兴趣的:(算法设计与分析,矩阵分析与应用)