问题分析
矩阵的SVD永远都不是唯一的。设矩阵维数为,其SVD为n × k一个Ñ × ķ
A = Ud V′
对于具有正交列的矩阵,具有非负项的对角矩阵和具有正交列的矩阵U p × p D k × p VÑ × püp × pdķ × pV
现在,任意选择对角线上有 s的任何对角线矩阵,使得是身份。然后S ± 1 S 2 = I p × p I pp × p小号± 1小号2= 我p × p一世p
A = Ud V′= U一世d 我V′= U(S2)D (S2)五′= (U小号)(小号D S)(V小号)′
也是一个的SVD因为演示具有正交列相似的计算表明具有正交列。此外,由于和是对角线,所以它们通勤,因此表示仍然具有非负项。(û 小号)'(Ù 小号)= 小号' ü ' Ù 小号= 小号' 我p小号= 小号'小号= 小号2 = 我p Ü 小号V 小号小号d 小号d 小号= d 小号2 = d d一个
(U小号)′(U小号)= S′ü′ü小号= S′一世p小号= S′小号= S2= 我p
ü小号V小号小号d小号D S= D S2= D
d
在代码中找到SVD的方法将找到一个对角化A的,类似地,对角化的 它前进到计算中的特征值方面中发现。 问题在于,这不能确保的列与的列始终匹配。甲甲' = (û d V ')(Û d V ' )' = Ü d V ' V d ' Ù ' = û d 2 ü “ V 甲'甲= V d 2 V '。D D 2 U Vü
A A′= (Ud V′)(Ûd V′)′= Ud V′Vd′ü′= Ud2ü′
V一个′A = Vd2V′。
dd2üV
一个解法
相反,找到这样的和这样的,用它们来计算VüV
ü′一个V= U′(Ud V′)五= (U′ü)D (V′V)= D
直接有效地。 该的对角线值不一定为正。d (这是因为对角化或的过程没有什么可以保证的,因为这两个过程是分别进行的。)通过选择对角线中的项使它们为正等于项的符号,因此具有所有正值。弥补这种由右乘用:甲甲'小号d 小号d ù 小号一个′一个A A′小号d小号dü小号
A = Ud V′= (U小号)(小号d )V′。
那是一个SVD。
例
令且。SVD是n = p = k = 1A = (− 2 )
(− 2 )= (1 )(2 )(− 1 )
其中,和。ü= (1 )D = (2 )V= (− 1 )
如果对角化您自然会选择和。同样,如果将A对角化,则可以选择。不幸的是,相反,计算 因为这是负数,所以设置。这将调整为,将为。您已经获得了它是两个可能的SVD之一(但与原始的不一样!)。一个′A = (4 )ü= (1 )D = (4–√)= (2 )A A′= (4 )V= (1 )
üd V′= (1 )(2 )(1 )= (2 )≠ A 。
D = U′一个V= (1 )′(- 2 )(1 )= (- 2 )。
小号= (− 1 )üü小号= (1 )(− 1 )= (− 1 )d小号D = (− 1 )(− 2 )= (2 )A = (− 1 )(2 )(1 ),
码
这是修改后的代码。其输出确认
- 该方法
m
正确地重新创建。
- ü和实际上仍然是正交的。V
- 但是结果与所返回的SVD不同
svd
。(两者同等有效。)
m <- matrix(c(1,0,1,2,1,1,1,0,0),byrow=TRUE,nrow=3)
U <- eigen(tcrossprod(m))$vector
V <- eigen(crossprod(m))$vector
D <- diag(zapsmall(diag(t(U) %*% m %*% V)))
s <- diag(sign(diag(D))) # Find the signs of the eigenvalues
U <- U %*% s # Adjust the columns of U
D <- s %*% D # Fix up D. (D <- abs(D) would be more efficient.)
U1=svd(m)$u
V1=svd(m)$v
D1=diag(svd(m)$d,n,n)
zapsmall(U1 %*% D1 %*% t(V1)) # SVD
zapsmall(U %*% D %*% t(V)) # Hand-rolled SVD
zapsmall(crossprod(U)) # Check that U is orthonormal
zapsmall(tcrossprod(V)) # Check that V' is orthonormal