SVD Matlab实现

Ana*_*a M 4 matlab svd

我试着编写将矩阵分解为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'
Run Code Online (Sandbox Code Playgroud)

U*sigma*V'似乎以-1的系数返回:

ans =

-2.0000   -4.0000   -1.0000   -3.0000
0.0000    0.0000   -2.0000   -1.0000
Run Code Online (Sandbox Code Playgroud)

导致它的代码或"理论"中的错误是什么?

zee*_*eez 6

特征向量不是唯一的(因为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)];
Run Code Online (Sandbox Code Playgroud)

事实上,A == U*sigma*V'特别是U这里发现的确U与您的算法一致.

  • @AnaM 不,因为`norm(v) == norm(-v)`,并且使用`n` 个特征向量,您就有`2^n` 个正交向量组合。 (2认同)