การวิเคราะห์ปัญหา
SVD ของเมทริกซ์นั้นไม่ซ้ำใคร ปล่อยให้เมทริกซ์มีมิติและปล่อยให้ SVD เป็นAn×k
A=UDV′
สำหรับเมทริกซ์มีคอลัมน์ orthonormal เป็นเส้นทแยงมุมเมทริกซ์กับรายการที่ไม่เป็นลบและเมทริกซ์กับคอลัมน์ orthonormaln×pUp×pDk×pV
ตอนนี้เลือกโดยพลการใด ๆ ในแนวทแยงเมทริกซ์มี s ในแนวทแยงเพื่อให้เป็นตัวตนI_pแล้วก็p×pS±1S2=Ip×pIp
A=UDV′=UIDIV′=U(S2)D(S2)V′=(US)(SDS)(VS)′
ยังเป็น SVD ของเพราะแสดงให้เห็นว่ามีคอลัมน์ orthonormal และการคำนวณที่คล้ายกันแสดงให้เห็นถึงมีคอลัมน์ orthonormal ยิ่งไปกว่านั้นเนื่องจากและเป็นแนวทแยงพวกเขาเดินทางดังนั้นแสดงว่ายังคงมีรายการที่ไม่เป็นลบA
(US)′(US)=S′U′US=S′IpS=S′S=S2=Ip
USVSSDSDS=DS2=D
D
วิธีการที่ใช้ในรหัสเพื่อค้นหา SVD ค้นหาที่ diagonalizesและในทำนองเดียวกันที่ diagonalizes จะดำเนินการคำนวณในแง่ของค่าลักษณะเฉพาะที่พบใน 2 ปัญหาคือนี้ไม่ได้รับประกันการจับคู่ที่สอดคล้องกันของคอลัมน์ของที่มีคอลัมน์ของVU
AA′=(UDV′)(UDV′)′=UDV′VD′U′=UD2U′
VA′A=VD2V′.
DD2UV
ทางออก
แต่หลังจากค้นหาและดังกล่าวแล้วให้ใช้เพื่อคำนวณUV
U′AV=U′(UDV′)V=(U′U)D(V′V)=D
โดยตรงและมีประสิทธิภาพ ค่าในแนวทแยงของนี้ไม่จำเป็นต้องเป็นค่าบวก D (นั่นเป็นเพราะไม่มีอะไรเกี่ยวกับกระบวนการ diagonalizingหรือที่จะรับประกันได้ว่าเนื่องจากกระบวนการทั้งสองได้ดำเนินการแยกต่างหาก) ทำให้พวกเขาเป็นบวกโดยเลือกรายการตามแนวทแยงมุมของเพื่อให้เท่ากับสัญญาณของรายการเพื่อให้มีค่าบวกทั้งหมด ชดเชยสิ่งนี้โดยการคูณด้วย :A′AAA′SDSDUS
A=UDV′=(US)(SD)V′.
นั่นคือแผนกบริการ
ตัวอย่าง
ให้กับ2) SVD คือn=p=k=1A=(−2)
(−2)=(1)(2)(−1)
กับ ,และ1)U=(1)D=(2)V=(−1)
หากคุณ diagonalizeที่คุณจะเลือกธรรมชาติและ(2) ในทำนองเดียวกันถ้าคุณ diagonalizeคุณจะเลือก(1) น่าเสียดายแทนให้คำนวณ เพราะนี่เป็นลบชุด1) ปรับนี้ไปและเพื่อ(2) คุณได้รับซึ่งเป็นหนึ่งในสอง SVD ที่เป็นไปได้ (แต่ไม่เหมือนเดิม!)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),
รหัส
นี่คือรหัสแก้ไข เอาท์พุทมันยืนยัน
- วิธีการสร้างใหม่
m
อย่างถูกต้อง
- Uและยังคงมีความเหมือนจริง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