我们先看看《数值计算方法》这本书上关于古典雅可比方法的例题:
%author FoddcusL FAFU
%The Jacobi For root
%输入:目标矩阵(input);目标接近的特征值(charnum)、迭代上限(aimnum)、目标误差(errorS)
%输出:目标特征值(output);xform、zfrom,包含x、z特征向量的值。
%input输入矩阵,包括系数和参数
%inputC 用于分解LU矩阵的合成矩阵
%oringinData保留的初始矩阵
%output 输出答案,对应X的各个值
%Toutput:修正顺序后的答案,对应输入数据的X顺序
%rememberdet:行列变化中介值
%remember:行列变化记录矩阵
%xnum,ynum 输入矩阵的尺寸
%Lneed 消元中,主式需要乘的变量
%keepnum 保留小数位数
%
clear all%启用模块化后需要注释该句
input=[2,-1,0;
-1,2,-1;
0,-1,2];%输入矩阵
errorS=10^(-20);
%%
oringinData=input;
error1='the condition are not meet for using this algorithm' ;
keepnum=-10;%设置保留n位小数,记得加负号表示小数位
[ynum,xnum]=size(input);%获取输入矩阵大小
if ynum~=xnum
disp(error1)
end
dealdet=input;
knum=1000;
R3det=[];
ddet=[];
%%
for k=1:knum%迭代次数knum
%挑选i值和j值
absfator=0;
id=0;
jd=0;
for i=1:xnum
for j=1:ynum
if i~=j
if absfator<roundn(abs(dealdet(j,i)),keepnum)
absfator=abs(dealdet(j,i));
id=i;%++列
jd=j;%++行
end
end
end
end
%计算旋转矩阵
a=(dealdet(jd,jd)-dealdet(id,id))/(2*dealdet(jd,id));
fiv=acot(a)/2;
b=tan(fiv);
c=cos(fiv);
d=sin(fiv);
%V值
V=eye(ynum);
V(id,id)=c;
V(jd,jd)=c;
V(id,jd)=-d;
V(jd,id)=d;
V3det(:,:,k)=V;
%计算新矩阵
dealdet=V*dealdet*(V');
R3det(:,:,k)=dealdet;
ddet(k,1)=jd;
ddet(k,2)=id;
%计算误差
errorN=0;
for i=1:xnum
for j=1:ynum
if i~=j
errorN=errorN+dealdet(i,j)^2;
end
end
end
errorf(k,1)=errorN;
if errorN<errorS
break
end
end
Vedet=V3det(:,:,1);
for i=1:k-1
Vedet=Vedet*V3det(:,:,k+1-i);
end
for i=1:ynum
disp(["特征向量",num2str(i)]);
Vedet(:,i)
numX(i,1)=R3det(i,i,k);
end
numend=sort(numX(:));
for i=1:ynum
disp(["特征值",num2str(i),num2str(numend(4-i))]);
end
[V,D]=eig(oringinData);
得出结果:
但需要注意的是:古典雅可比方法对于对称矩阵有较好的效果,但是如果矩阵对角线上有元素为0的话,表现的效果则就不好了。