R
為什麼我不能通過 XX' 和 X’X 的特徵值分解獲得 X 的有效 SVD?
我正在嘗試手動進行 SVD:
m<-matrix(c(1,0,1,2,1,1,1,0,0),byrow=TRUE,nrow=3) U=eigen(m%*%t(m))$vector V=eigen(t(m)%*%m)$vector D=sqrt(diag(eigen(m%*%t(m))$values)) U1=svd(m)$u V1=svd(m)$v D1=diag(svd(m)$d) U1%*%D1%*%t(V1) U%*%D%*%t(V)
但是最後一行沒有返回
m
。為什麼?它似乎與這些特徵向量的符號有關……還是我誤解了程序?
問題分析
矩陣的 SVD 從來都不是唯一的。讓矩陣有尺寸並讓它的 SVD 為
為矩陣具有正交列,對角線矩陣具有非負條目,以及矩陣與正交列。
現在任意選擇任何對角線矩陣有s 在對角線上,所以是個身份. 然後
也是一個SVD因為
演示具有正交列,類似的計算表明具有正交列。此外,由於和是對角線的,他們通勤,從哪裡來節目仍然有非負條目。 代碼中實現的查找 SVD 的方法找到了對角化
同樣,一個對角化 它繼續計算根據在中找到的特徵值. 問題是這不能保證列的一致匹配與列.
一個解法
相反,在找到這樣一個和這樣一個, 用它們來計算
直接有效。 這個的對角線值不一定是積極的。 (那是因為對角化的過程也沒有要么這將保證,因為這兩個過程是分開進行的。)通過選擇沿對角線的條目使它們為正等於條目的符號, 以便具有所有正值。通過右乘來補償這一點經過:
那是一個SVD。
例子
讓和. SVD 是
和,, 和.
如果你對角化你自然會選擇和. 同樣,如果你對角化你會選擇. 很遺憾,
相反,計算 因為這是負數,所以設置. 這調整到和到. 你已經獲得這是兩個可能的 SVD 之一(但與原始的不同!)。
代碼
這是修改後的代碼。它的輸出證實
- 該方法
m
正確地重新創建。- 和真的還是正交的。
- 但結果與返回的 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