Analiza problemu
SVD matrycy nigdy nie jest unikalne. Niech macierz ma wymiary i niech jej SVD będzieZAn × k
A = UreV.′
dla macierzy z kolumnami ortonormalnymi, diagonalnej macierzy z nieujemnymi wpisami oraz macierzy z kolumnami ortonormalnymi.n × pUp × prek × pV.
Teraz wybrać, dowolnie każdy diagonalny macierzy o s po przekątnej, tak, jest tożsamość . Następniep × pS.± 1S.2)= Jap × pjap
A = UreV.′= UjaD IV.′= U(S.2)) D (S.2))V.′= ( US.) ( SD S.) ( VS.)′
jest SVD ponieważ pokazuje ma ortonormalnych kolumny i podobne obliczenia pokazują, że ma kolumny ortonormalne. Ponadto, ponieważ i są ukośne, dojeżdżają do pracy, skąd pokazuje, że nadal ma nieujemne wpisy.ZA
( US.)′( US.) =S.′U′US.=S.′japS.=S.′S.=S.2)=jap
US.V.S.S.reS.D S.= D.S.2)= D.
re
Metoda zaimplementowana w kodzie w celu znalezienia SVD znajduje która przekątna i podobnie która przekątna Kontynuuje obliczanie w oparciu o wartości własne znalezione w . Problemem jest to nie zapewnia spójną dopasowanie kolumn z kolumnami .U
ZAZA′= ( UreV.′) ( UreV.′)′= UreV.′V.re′U′= Ure2)U′
V.ZA′A = V.re2)V.′.
rere2)UV.
Rozwiązanie
Zamiast tego, po znalezieniu takiego i takiego , użyj ich do obliczeniaUV.
U′V=U′( UreV.′) V.= (U′U) D (V.′V.) = D
bezpośrednio i skutecznie. Wartości diagonalne tego niekoniecznie są dodatnie. re (Jest tak, ponieważ nie ma nic w procesie diagonalizacji lub który to zagwarantuje, ponieważ te dwa procesy zostały przeprowadzone osobno.) Ustaw je pozytywnie, wybierając wpisy wzdłuż przekątnej wyrównać znaki wpisów , aby miała wszystkie wartości dodatnie. Zrekompensuj to, mnożąc odpowiednio przez :ZA′ZAZAZA′S.reS.reUS.
A = UreV.′= ( US.) ( SD )V.′.
To jest SVD.
Przykład
Niech z . SVD jestn = p = k = 1A = ( - 2 )
( - 2 ) = ( 1 ) ( 2 ) ( - 1 )
z , i .U= ( 1 )D=(2)V=(−1)
Jeśli przekątna naturalnie wybrałbyś i . Podobnie, jeśli przekątna , wybierzesz . Niestety, Zamiast tego oblicz Ponieważ jest to ujemne, ustaw . To dostosowuje do i do . Otrzymałeś który jest jednym z dwóch możliwych SVD (ale nie takim samym jak oryginał!).A′A=(4)U=(1)D=(4–√)=(2)AA′=(4)V=(1)
UDV′=(1)(2)(1)=(2)≠A.
D=U′AV=(1)′(−2)(1)=(−2).
S=(−1)UUS=(1)(−1)=(−1)DSD=(−1)(−2)=(2)A=(−1)(2)(1),
Kod
Oto zmodyfikowany kod. Jego wydajność potwierdza
- Metoda odtwarza się
m
poprawnie.
- U i nadal są ortonormalne.V
- Ale wynik nie jest tym samym SVD zwróconym przez
svd
. (Oba są jednakowo ważne.)
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