Ori*_*ber 5 matlab matrix linear-algebra svd eigenvector
我正在尝试编写一个获取A任意大小矩阵的程序,并且SVD将其分解:
A = U * S * V'
Run Code Online (Sandbox Code Playgroud)
A用户输入的矩阵在哪里,U正交矩阵由特征值的特征向量组成A * A',S是奇异值的对角矩阵,并且V是特征向量的正交矩阵A' * A.
问题是:MATLAB函数eig有时会返回错误的特征向量.
这是我的代码:
function [U,S,V]=badsvd(A)
W=A*A';
[U,S]=eig(W);
max=0;
for i=1:size(W,1) %%sort
for j=i:size(W,1)
if(S(j,j)>max)
max=S(j,j);
temp_index=j;
end
end
max=0;
temp=S(temp_index,temp_index);
S(temp_index,temp_index)=S(i,i);
S(i,i)=temp;
temp=U(:,temp_index);
U(:,temp_index)=U(:,i);
U(:,i)=temp;
end
W=A'*A;
[V,s]=eig(W);
max=0;
for i=1:size(W,1) %%sort
for j=i:size(W,1)
if(s(j,j)>max)
max=s(j,j);
temp_index=j;
end
end
max=0;
temp=s(temp_index,temp_index);
s(temp_index,temp_index)=s(i,i);
s(i,i)=temp;
temp=V(:,temp_index);
V(:,temp_index)=V(:,i);
V(:,i)=temp;
end
s=sqrt(s);
end
Run Code Online (Sandbox Code Playgroud)
我的代码返回正确的s矩阵,也"几乎"正确U和V矩阵.但有些列乘以-1.显然,如果t是一个特征向量,那么也是-t一个特征向量,但标志反转(对于一些列,而不是所有),我没有得到A = U * S * V'.
有没有什么办法解决这一问题?
示例:对于矩阵,A=[1,2;3,4]我的函数返回:
U=[0.4046,-0.9145;0.9145,0.4046]
Run Code Online (Sandbox Code Playgroud)
并且内置的MATLAB svd函数返回:
u=[-0.4046,-0.9145;-0.9145,0.4046]
Run Code Online (Sandbox Code Playgroud)
Amr*_*mro 12
请注意,特征向量不是唯一的.乘以任何常数,包括-1(只是改变符号),给出另一个有效的特征向量.鉴于特征向量的定义,这一点很清楚:
A·v = ?·v
Run Code Online (Sandbox Code Playgroud)
MATLAB 选择将特征向量归一化为1.0的范数,符号是任意的:
因为
eig(A),特征向量被缩放,使得每个的范数为1.0.对于eig(A,B),,eig(A,'nobalance')和eig(A,B,flag),特征向量未标准化
如您所知,SVD和特征分解是相关的.下面是一些测试这个事实的代码.注意svd并eig以不同的顺序返回结果(一个从高到低排序,另一个在反向排序):
% some random matrix
A = rand(5);
% singular value decomposition
[U,S,V] = svd(A);
% eigenvectors of A'*A are the same as the right-singular vectors
[V2,D2] = eig(A'*A);
[D2,ord] = sort(diag(D2), 'descend');
S2 = diag(sqrt(D2));
V2 = V2(:,ord);
% eigenvectors of A*A' are the same as the left-singular vectors
[U2,D2] = eig(A*A');
[D2,ord] = sort(diag(D2), 'descend');
S3 = diag(sqrt(D2));
U2 = U2(:,ord);
% check results
A
U*S*V'
U2*S2*V2'
Run Code Online (Sandbox Code Playgroud)
我得到非常相似的结果(忽略小的浮点错误):
>> norm(A - U*S*V')
ans =
7.5771e-16
>> norm(A - U2*S2*V2')
ans =
3.2841e-14
Run Code Online (Sandbox Code Playgroud)
为了获得一致的结果,人们通常采用要求每个特征向量中的第一个元素具有特定符号的约定.这样,如果你得到一个不遵循这个规则的特征向量,你可以将它乘以-1翻转符号......