2016-02-27 103 views
4

我试图编写一个将矩阵分解为SVD格式的matlab代码。SVD Matlab的实现

“理论”:

要获得U,我发现AA的特征向量”,并获得V,我发现A'A的特征向量。最后,Sigma是与A相同维数的矩阵,特征值在对角线上的根在有序序列中。

但是,它似乎没有正常工作。

A=[2 4 1 3; 0 0 2 1]; 

% Get U, V 
[aatVecs, aatVals] = eig(A*A'); 
[~, aatPermutation] = sort(sum(aatVals), 'descend'); 
U = aatVecs(:, aatPermutation); 

[ataVecs, ataVals] = eig(A'*A); 
[~, ataPermutation] = sort(sum(ataVals), 'descend'); 
V = ataVecs(:, ataPermutation); 

% Get Sigma 
singularValues = sum(aatVals(:, aatPermutation)).^0.5; 
sigma=zeros(size(A)); 
for i=1:nnz(singularValues) 
    sigma(i, i) = singularValues(i); 
end 

A 
U*sigma*V' 

U *西格玛* V”似乎为-1的因子返回:

ans = 

-2.0000 -4.0000 -1.0000 -3.0000 
0.0000 0.0000 -2.0000 -1.0000 

什么代码或‘理论’,导致它的错误呢?

+0

我在去年5月写了这篇文章:[手工计算SVD](http://math.stackexchange.com/a/1805239/339790)。 –

回答

5

特征向量不是唯一的(因为Av==λv的定义,任何wμw==vμ~=0也是一个特征向量)。恰巧,由eig返回的特征向量不匹配正确的SVD(即使它们被归一化)。

但是,我们可以构造U,一旦我们有V,我们将在您的算法中找到A'*A的特征向量。一旦找到V作为排序的特征向量,您必须找到U匹配。由于V是正交的,因此A*V == U*sigma。因此,我们可以设置

U = [A*V(:,1)./singularValues(1) A*V(:,2)./singularValues(2)]; 

而事实上,A == U*sigma*V',特别是这里找到U也正是U有你的算法发现负。

+0

虽然特征向量不是唯一的,但归一化的特征向量应该是,不是? –

+1

@AnaM不,因为'norm(v)== norm(-v)',并且'n'特征向量具有正交向量的2^n'组合。 – zeeMonkeez

+0

解决了它。谢谢 –