几种常见的矩阵分解综合程序_matlab

矩阵分析与应用–矩阵分解

参数输入:

待分解矩阵: A A A
求解方法: m e t h o d method method
  1. LU分解(‘LU’)
  2. QR分解-古典施密特正交法(‘QR-古典型施密特’)
  3. QR分解-改进施密特正交法(‘QR-改进型施密特’)
  4. Householder分解(‘HouseholderReduction’)
  5. Givens分解(‘GivensReduction’)
  6. URV分解(‘URV’)
  7. 求行列式(‘Det’)
  8. 求解向量: b b b

原理说明:

  1. LU分解
    本程序使用部分主元法进行LU分解,要求输入矩阵可逆
    分解结果 P A = L U PA=LU PA=LU,其中, P P P为初等行变换阵, L L L为主对角线元素为1的下三角矩阵, U U U为上三角矩阵。

本程序实现了四种QR分解的方法,分别是 Gram-Schmidt、modified Gram-Schmidt、Householder reduction 和 Givens reduction。要求输入矩阵列向量无关, 分解所得矩阵 A = Q R A=QR A=QR, 其中Q为正交方阵,R为上三角矩阵。

  1. QR分解-古典施密特正交法

  2. QR分解-改进施密特正交法

  3. QR分解-Householder分解

  4. QR分解-Givens分解

  5. URV分解
    A = U R V T A=URV^T A=URVT,其中, A A A m ∗ n m*n mn矩阵, U U U V V V分别为 m m m阶和 n n n阶正交矩阵。
    U U U的前 r r r列是 R ( A ) R(A) R(A)的标准正交基,后 m − r m-r mr列是 N ( A T ) N(A^T) N(AT)的标准正交基。
    V V V的前 r r r列是 R ( A T ) R(A^T) R(AT)的标准正交基,后 m − r m-r mr列是 N ( A ) N(A) N(A)的标准正交基.

  6. 求行列式

    1. d e t ( A B ) = d e t ( A ) d e t ( B ) det(AB)=det(A)det(B) det(AB)=det(A)det(B)
    2. 每进行一次基本行变换,行列式的值取负。
    3. 三角阵的行列式的值为主对角线元素乘积。
      因此进行LU分解,PA=LU,记录P的行交换次数n,即 ( − 1 ) n ∗ d e t ( A ) = d e t ( L ) d e t ( U ) (-1)^n*det(A)=det(L)det(U) 1ndet(A)=det(L)det(U).
  7. 求解向量
    求解向量的有三种情况,即无解、有唯一解、有无穷多解
    本程序在QR分解的基础上:

    • 当存在唯一解时,使用解方程法逐步求解上三角阵R的逆,并将其代入方程中进行求解方程组。
    • 当方程不可解时返回错误信息
    • 当方程有无穷多解时返回基础解系和特解,

输入输出示例:

  1. LU分解
  • 输入:
    • A=[0 -20 -14; 3 27 -4; 4 11 -2]
    • method = ‘LU’
  • 调用:
    • [P,L,U] = matrixAnalysis(A,‘LU’)
  1. QR分解(古典施密特正交法)
  • 输入:
    • A=[0 -20 -14; 3 27 -4; 4 11 -2]
    • method = ‘QR-古典型施密特’
  • 调用:
    • [Q,R] = matrixAnalysis(A,‘QR-古典型施密特’)
  1. QR分解(改进施密特正交法)
  • 输入:
    • A=[0 -20 -14; 3 27 -4; 4 11 -2]
    • method = ‘QR-古典型施密特’
  • 调用:
    • [Q,R] = matrixAnalysis(A,‘QR-改进型施密特’)
  • 输入输出程序截图
  1. Householder分解
  • 输入:
    • A=[0 -20 -14; 3 27 -4; 4 11 -2]
    • method = ‘HouseholderReduction’
  • 调用:
    • [Q,R] = matrixAnalysis(A,‘HouseholderReduction’)
  1. Givens分解
  • 输入:
    • A=[0 -20 -14; 3 27 -4; 4 11 -2]
    • method = ‘GivensReduction’
  • 调用:
    • [Q,R] = matrixAnalysis(A,‘GivensReduction’)
  1. URV分解
  • 输入:
    • A = [-4 -2 -4 -2;2 -2 2 1;-4 1 -4 -2];
    • method = ‘URV2’
  • 调用:
    • [U,V,R] = matrixAnalysis(A,‘URV2’)
  1. 求行列式(‘Det’)
  • 输入:
    • A=[0 -20 -14; 3 27 -4; 4 11 -2]
    • method = ‘det’
  • 调用:
    • DetA = matrixAnalysis(A,‘det’)
  1. 求解向量: b b b
  • 输入:

    • A = [1 2 -3 4;4 8 12 -18;2 3 2 1;-3 -1 1 -4];
    • b = [4 6 8 -7]’;
    • method = b
  • 调用:

    • x = matrixAnalysis(A,b)
  • 输入:

    • A = [1 2 -3 4;4 8 12 -18;2 3 2 1;1 2 -3 4];
    • b = [4 6 8 -7]’;
    • method = b
  • 调用:

    • x = matrixAnalysis(A,b)
  • 输入:

    • A = [1 2 -3 4;4 8 12 -18;2 3 2 1;1 2 -3 4];
    • b = [4 6 8 4]’;
    • method = b
  • 调用:

    • x = matrixAnalysis(A,b)

程序

% % LU
% % QR(Gram-Schmidt)
%Orthogonal Reduction
% % Householder Reduction 
% % Givens reduction)
% % URV
% %程序实现,要求如下:
% 
% 1、一个综合程序,根据选择参数的不同,实现不同的矩阵分解;在此基础上,实现Ax=b方程组的求解,以及计算A的行列式;
% 
% 2、可以用matlab、Python等编写程序,需附上简单的程序说明,比如参数代表什么意思,输入什么,输出什么等等,附上相应的例子;
% 
% 3、一定是可执行文件,例如 .m文件等,不能是word或者txt文档。附上源代码,不能为直接调用matlab等函数库;
function varargout = matrixAnalysis(A,method)
    A
    [m,n] = size(A);
    if isnumeric(method) 
        b = method
        [~,Q1,R1] =  Hous(A);
        [~,~,R2] =  Hous([A b]);
        R1 = roundn(R1,-10);
        R2 = roundn(R2,-10);
        R1(all(R1==0,2),:) = [];
        R2(all(R2==0,2),:) = [];
        
        if(size(R1,1)~=size(R2,1))
            fprintf("方程无解");
            varargout{1} = [];
            return;
            
        elseif(size(R1,1)==size(R2,1)&&size(R2,1)==n)
            R1contrary = contraryTra(R1);
            fprintf("·······方程有唯一解为:\n");
            x = R1contrary*Q1'*b;
            varargout{1} = x;
        else
%             
            R3= [A b];
            P1 = eye(m);
            for i=1:m-1
                [~,currentMaxIndex] = max(abs(R3(i:m,i)));%寻找主元
                P1([i currentMaxIndex+i-1],:)=P1([currentMaxIndex+i-1 i],:);%主元行变换
                R3([i currentMaxIndex+i-1],:)=R3([currentMaxIndex+i-1 i],:);%主元行变换

                for j=i+1:m
                    k = (R3(j,i)/R3(i,i));
                    R3(j,:) = R3(j,:)-k*R3(i,:);
                    P1(j,:) = P1(j,:)-k*P1(i,:);   
                end
            end
            R3;
            % U
            R3(all(abs(R3)<=1e-10,2),:) = [];
            [m1,~] = size(R3);

            [~,Ind]=max(R3~=0 , [] , 2);%z主元位置
            for i=1:m1
                R3(i,:) = R3(i,:)/R3(i,Ind(i));
                for j=1:i-1
                    k = (R3(j,Ind(i))/R3(i,Ind(i)));
                    R3(j,:) = R3(j,:) - R3(i,:)*k;
                    P1(j,:) = P1(j,:) - P1(i,:)*k;
                end
            end
            R3;
            %U = [A(:,Ind) P1(m1+1:m,:)'];

            % R

            funSol = zeros(n,n-m1);
            a=1:n;
            [c i]=setdiff(a,Ind);
            t=a(sort(i));

            funSol(1:m1,:) = -R3(:,t);
            fprintf("·······方程有无穷多解,基础解系为:\n");
            funSol(m1+1:n,:) = eye(n-length(Ind))
            fprintf("·······方程有无穷多解,其特解为:\n");
            praSol = [R3(:,m+1);zeros(1,n-size(R2,1))]
            x = [funSol praSol]; 
            varargout{1} = x;
        end
        
    else
        switch method
            case "LU"
                [~,P,Q,R] = LU(A);
                varargout{1} = P;
                varargout{2} = Q;
                varargout{3} = R;
            case "QR-古典型施密特"
                [P,Q,R] = smiClass(A);
                varargout{1} = Q;
                varargout{2} = R;
            case "QR-改进型施密特"
                [P,Q,R] = smiImpr(A);
                varargout{1} = Q;
                varargout{2} = R;

            case "GivensReduction"
                [P,Q,R] = Givens(A);
                varargout{1} = Q;
                varargout{2} = R;
            case "HouseholderReduction"    
                [P,Q,R] = Hous(A);
                varargout{1} = Q;
                varargout{2} = R;
            case "URV1"
                [U,V,R] = URV1(A);
                varargout{1} = U;
                varargout{2} = V;
                varargout{3} = R;
            case 'URV2'
                [U,V,R] = URV2(A);
                varargout{1} = U;
                varargout{2} = V;
                varargout{3} = R;
            case 'det'
                [P,Q,R,Det] = ourDet(A);
                varargout{1} = Det;
            
        end
    end
end
    

function [count,P,Q,R] = LU(A)
    [m,n] = size(A);
    if m~=n
        error("······您输入的不是方阵,无法进行LU分解或行列式计算·······");
    end
    count=0;
    R = A;
    P = eye(n);
    Q = eye(n);
    for i=1:n-1
        a =eye(n);%初始化P0矩阵
        b = a;%初始化M矩阵
        [~,currentMaxIndex] = max(abs(R(i:n,i)));%寻找主元
        if((currentMaxIndex+i-1)~=i)
            count=count+1;
        end
        a([i currentMaxIndex+i-1],i:n)=a([currentMaxIndex+i-1 i],i:n);%主元行变换
        %逐步计算 P M
        P0{i} = a;
        R = P0{i}*R;
        M{i} = b;
        for j=i+1:n
            M{i}(j,i) = -(R(j,i)/R(i,i));
        end
        R = M{i}*R;%迭代变换
        P = P0{i}*P;
        Q = P0{i}*Q/(P0{i})*inv(M{i});
    end
%     P = roundn(P,-3);
%     Q = roundn(Q,-3);
%     R = roundn(R,-3);
end

function [P,Q,R] = smiClass(A)
    [m,n] = size(A);
    if m

你可能感兴趣的:(矩阵,matlab,线性代数)