Анализ проблемы
СВД матрицы никогда не бывает уникальным. Пусть матрица имеет размерыn × k, и пусть его SVD будетAn×k
A=UDV′
для матрицы U с ортонормированными столбцами, диагональной p × p- матрицы D с неотрицательными элементами и k × p- матрицы V с ортонормированными столбцами.n×pUp×pDk×pV
Теперь произвольно выбираем любую диагональную матрицу S, имеющую ± 1 s на диагонали, так что S 2 = I является тождеством p × p I p . затемp×pS±1S2=Ip×pIp
A=UDV′=UIDIV′=U(S2)D(S2)V′=(US)(SDS)(VS)′
Также СВД из А , потому что ( U S ) ' ( U S ) = S ' U ' U S = S ' Я р S = S ' S = S 2 = я р демонстрирует U S имеет ортонормированные столбцы и аналогичный расчет показывает V S имеет ортонормированные столбцы. Более того, поскольку S и D диагональны, они коммутируют, откудаA
( US)'( US) = S'U'US= S'япS= S'S= S2= Яп
USВSSD показывает, что
D все еще имеет неотрицательные записи.
SD S= D S2= D
D
Метод, реализованный в коде для поиска SVD, находит который диагонализирует A A ′ = ( U D V ′ ) ( U D V ′ ) ′ = U D V ′ V D ′ U ′ = U D 2 U ′ и, аналогично, A V, который диагонализирует A ' A = V D 2 V ' . Он продолжает вычислять DU
A A'= ( UD V') ( UD V')'= UD V'ВD'U'= UD2U'
ВA'A = VD2В',
Dв терминах собственных значений, найденных в
.
Проблема заключается в следующем не гарантирует последовательное согласование столбцов U со столбцами V .D2UВ
Решение
Вместо этого, после нахождения такого и такого V , используйте их для вычисленияUВ
U'A V= U'( UD V') V= ( U'U) D ( V'В) = D
DA'AA A'SDSDUS
A = UD V'= ( US) ( SD ) V',
Это СВД.
пример
n = p = k = 1A = ( - 2 )
( - 2 ) = ( 1 ) ( 2 ) ( - 1 )
U= ( 1 )D = ( 2 )В= ( - 1 )
A'A = ( 4 )U= ( 1 )D = ( 4-√) = ( 2 )A A'= ( 4 )В= ( 1 )
UD V'= ( 1 ) ( 2 ) ( 1 ) = ( 2 ) ≠ .
D = U'A V= ( 1 )'( - 2 ) ( 1 ) = ( - 2 ) .
S= ( - 1 )UUS= ( 1 ) ( - 1 ) = ( - 1 )DSD = ( - 1 ) ( - 2 ) = ( 2 )A = ( - 1 ) ( 2 ) ( 1 ) ,
Код
Вот модифицированный код. Его вывод подтверждает
- Метод воссоздает
m
правильно.
- UВ
- Но результат не тот же 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