【问题标题】:MATLAB eig returns inverted signs sometimesMATLAB eig 有时会返回倒号
【发布时间】:2013-08-11 16:51:13
【问题描述】:

我正在尝试编写一个程序来获取任意大小的矩阵A,然后 SVD 将其分解:

A = U * S * V'

其中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

我的代码返回正确的s 矩阵,以及“几乎”正确的UV 矩阵。但是有些列乘以-1。显然如果t 是一个特征向量,那么-t 也是一个特征向量,但是符号倒置(对于某些列,不是全部)我没有得到A = U * S * V'

有没有办法解决这个问题?

示例:对于矩阵A=[1,2;3,4],我的函数返回:

U=[0.4046,-0.9145;0.9145,0.4046]

以及内置的 MATLAB svd 函数返回:

u=[-0.4046,-0.9145;-0.9145,0.4046]

【问题讨论】:

标签: matlab matrix linear-algebra svd eigenvector


【解决方案1】:

请注意,特征向量不是唯一的。乘以任何常数,包括-1(它只是改变符号),得到另一个有效的特征向量。考虑到特征向量的definition,这一点很清楚:

A·v = λ·v

MATLAB chooses 将特征向量归一化为范数为 1.0,符号是任意的:

对于eig(A),特征向量被缩放,使得每个的范数为 1.0。 对于eig(A,B)eig(A,'nobalance')eig(A,B,flag),特征向量未归一化

现在你知道,SVD 和特征分解是related。下面是一些代码来测试这个事实。请注意,svdeig 返回结果的顺序不同(一个从高到低排序,另一个反向排序):

% 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'

我得到非常相似的结果(忽略小的浮点错误):

>> norm(A - U*S*V')
ans =
   7.5771e-16
>> norm(A - U2*S2*V2')
ans =
   3.2841e-14

编辑:

为了获得一致的结果,通常采用要求每个特征向量中的第一个元素具有特定符号的约定。这样,如果你得到一个不遵循这个规则的特征向量,你将它乘以-1 来翻转符号...

【讨论】:

  • 规范不会有太大变化,在我的代码中也是如此。但是 U2*S2*V2 和 A 之间的区别太大了,不容忽视。我知道如果 t 是一个特征向量,那么 -t 也是一个特征向量,但是我需要特定的符号才能使它恰好是 A。如何在我的代码中解决这个问题?
  • @OriaGruber:查看我对符号约定的编辑。我不确定 MATLAB 在符号方面遵循什么约定..
  • 另一件事:eigsvd 以不同的顺序返回特征值(和相应的特征向量)和主值。我不确定eig,但svd 方便地将它们“按降序”返回。
  • @horchler: 是的,svd 肯定按降序排序(根据文档),而 eig 似乎按升序排序(文档没有明确提到这一点),所以fliplr 也可能有效。无论哪种方式,我都在上面的代码中明确地对eig 的特征值和相应的特征向量进行排序。这是一个相关的问题:stackoverflow.com/a/3293855/97160
  • @OriaGruber:关于符号约定,您可能对这些提交感兴趣:eigenshuffleeigenshuffle2。这里也有一些相关的讨论:mathworks.com/matlabcentral/newsreader/view_thread/77590mathworks.com/matlabcentral/newsreader/view_thread/306717。您可以通过快速搜索找到更多...
猜你喜欢
  • 2012-11-22
  • 2021-09-03
  • 1970-01-01
  • 2023-03-11
  • 2015-11-19
  • 2012-07-26
  • 1970-01-01
  • 1970-01-01
  • 2014-04-27
相关资源
最近更新 更多