2016-02-27 73 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

解決了它。謝謝 –