MATLAB入门学习-#7-幂法&幂法的加速&反幂法编程练习


这几种求特征值和特征向量的方法,理论讲解可以去看数值分析这门课的课本或者下面这个链接: 【图文】幂法及反幂法_百度文库
另外还有一个讲的很好的幂法相关的文档: 科学网—图说幂法求特征值和特征向量 - 康建的博文
下面就给出我写的程序了,统一用的是先用一个函数检验是否具有使用某一方法的条件,若有条件再调用计算函数,因此每种方法都有两个函数。程序还是有问题的,比如对误差限epsilon,设置好以后会多算一次,就是说程序的顺序还是有问题,最近时间很紧张,我就不再去修改了,就把我第一次写的放上来,把中间一些注意的地方记录到就好了。

1.幂法(power method)

function [lambda,beta]=power_method(A,times,x0,epsilon)
%这个是一个检验A能不能用幂法的函数
%[lambda,beta]=power_method(A,times,x0,epsilon)
%lambda是最后得出的特征值
%beta是最后得到的特征值对应的特征向量
%A是待求矩阵
%times是最大迭代次数
%x0是初始向量
%epsilon是最大误差
format long;
b=eig(A);      %求A的特征值所组成的向量
c=size(b);
d=c(1)*c(2);  % 矩阵元素数量,即特征值的总个数
e=length(unique(b));  % 有几个代表值
if(d==e)
    fprintf('特征值互异,是对角化矩阵\n');  %QUESTION1:fprintf
    [lambda,beta]=power_method_cal(A,times,x0,epsilon)  %再去调用计算函数,代码在下面
else
    error('特征值有重复,不是对角化矩阵\n');
end
function [alpha,x]=power_method_cal(A,times,x0,epsilon)
%[alpha,x]=power_method_cal(A,times,x0,epsilon)
format long;
k=1;
u=0;

[m,n]=size(x0);
y=zeros(m,n);
y=x0;

while k <= times 
    x=A*y;
    alpha=max(x);   %max()求一个矩阵中最大的元素
    y=x./alpha;
    fprintf('第%d次迭代\n',k);   %QUESTON3:%d  %f   %s
    fprintf('alpha=%.8f\n',alpha)
    disp(x);
    disp(y);
    if abs(alpha-u)<epsilon
        break
    else
        k=k+1;
        u=alpha;
    end      %QUESTION2:end

end

QUESTION1:matlab disp、sprintf、fprintft函数 - hengyaha的博客 - CSDN博客
QUESTION2:matlab中,if,while,for这些语句后面都要用end来结束
QUESTION3:

%3d就是说按照长度为3的整型输出,比如10,输出就是“10”,“”代表空格。
%6.2f就是小数点后保留2位,输出总长度为6,比如3.14159,输出后就是“_ _ _3.14”(前面三个空格)
%c就是输出字符串
%s就是输出字符串,和%c是一样的

2.幂法的加速——原点平移法

function [lambda,beta]=origin_displacement_method(A,times,x0,epsilon,lambda0)
%[lambda,beta]=origin_displacement_method(A,times,x0,epsilon,lambda0)
%lambda是最后得出的特征值
%beta是最后得到的特征值对应的特征向量
%A是待求矩阵
%times是最大迭代次数
%x0是初始向量
%epsilon是最大误差
%lambda0就是lambda0

b=eig(A);
c=size(b);
d=c(1)*c(2);  % 矩阵元素数量
e=length(unique(b));  % 有几个代表值
if(d==e)
    fprintf('特征值互异,是对角化矩阵\n');
    [lambda,beta]=origin_displacement_method_cal(A,times,x0,epsilon,lambda0)
else
    error('特征值有重复,不是对角化矩阵\n');
end
function [alpha,x]=origin_displacement_method_cal(A,times,x0,epsilon,lambda0)
%[lambda,beta]=origin_displacement_method_cal(A,times,x0,epsilon,lambda0)

k=1;
u=0;

[m,n]=size(x0);
y=zeros(m,n);
y=x0;
I=eye(m);
A=A-lambda0*I;
while k <= times 
    x=A*y;
    alpha=max(x);
    y=x./alpha;
    fprintf('第%d次迭代\n',k);
    fprintf('alpha=%.8f\n',alpha)
    fprintf('特征值为%.8f\n',alpha+lambda0)
    disp(x);
    disp(y);
    if abs(alpha-u)<epsilon
        break
    else
        k=k+1;
        u=alpha;
    end

end

3.幂法的加速——埃特肯(Aitken)

function [lambda,beta]=power_method_aitken(A,x0,times,epsilon)
%[lambda,beta]=power_method_aitken(A,x0,times,epsilon)
%lambda是最后得出的特征值
%beta是最后得到的特征值对应的特征向量
%A是待求矩阵
%x0是初始向量
%times是最大迭代次数
%epsilon是最大误差
format long;
b=eig(A);
c=size(b);
d=c(1)*c(2);  % 矩阵元素数量
e=length(unique(b));  % 有几个代表值
if(d==e)
    fprintf('特征值互异,是对角化矩阵\n');
    [lambda,beta]=power_method_aitken_cal(A,x0,times,epsilon);
else
    error('特征值有重复,不是对角化矩阵\n');
end
function [lambda,x]=power_method_aitken_cal(A,x0,times,epsilon)
%[alpha,x]=power_method_aitken_cal(A,x0,times,epsilon)
format long;
k=1;
u=1;

[m,n]=size(x0);
y=zeros(m,n);
x=x0;
alpha0=0;
alpha1=0;

while k <= times 
    alpha=max(x);
    y=x./alpha;
    x=A*y;
    alpha2=max(x);
    lambda=alpha0-((alpha1-alpha0)^2)/(alpha2-2*alpha1+alpha0);
    fprintf('第%d次迭代\n',k);
    fprintf('alpha0=%.8f\n',alpha0);
    fprintf('alpha1=%.8f\n',alpha1);
    fprintf('alpha2=%.8f\n',alpha2);
    fprintf('lambda=%.8f\n',lambda);
    disp(x);
    disp(y);
    if abs(lambda-u)<epsilon
        break
    else
        k=k+1;
        u=lambda;
        alpha0=alpha1;
        alpha1=alpha2;
    end

end

4.反幂法(inverse power method)

function [lambda,beta]=inverse_power_method(A,x0,lambda_star,times,epsilon)
%[lambda,beta]=inverse_power_method(A,x0,lambda_star,times,epsilon)
%lambda是最后得出的特征值
%beta是最后得到的特征值对应的特征向量
%A是待求矩阵
%x0是初始向量
%lambda_star是特征值lambda的近似值
%times是最大迭代次数
%epsilon是最大误差
format long;
b=eig(A);
c=size(b);
d=c(1)*c(2);  % 矩阵元素数量
e=length(unique(b));  % 有几个代表值
if(d==e)
    fprintf('特征值互异,是对角化矩阵\n');
    [lambda,beta]=inverse_power_method_cal(A,x0,lambda_star,times,epsilon);
else
    error('特征值有重复,不是对角化矩阵\n');
end

function [lambda,x]=inverse_power_method_cal(A,x0,lambda_star,times,epsilon)
%[lambda,beta]=inverse_power_method_cal(A,x0,lambda_star,times,epsilon)
format long;
k=1;
u=1;

[m,n]=size(x0);
y=zeros(m,n);
x=x0;

I=eye(m);
H=A-lambda_star.*I;
[L,U]=lu(H);     %LU分解函数(matlab自带)
while k <= times 
    beta_b=max(x);
    y=x./beta_b;
    z=L\y;
    x=U\z;
    beta_b=max(x);
    fprintf('第%d次迭代\n',k);
    lambda=lambda_star+1/beta_b;
    fprintf('lambda=%.8f\n',lambda);
    disp(x);
    disp(z);
    if abs(1/beta_b-1/u)<epsilon
        break
    else
        k=k+1;
        u=beta_b;
    end

end
  • 17
    点赞
  • 87
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值