基于python 和 matlab的矩阵奇异值分解

https://www.cnblogs.com/pinard/p/6251584.html 可参考。 

一个 mxn的矩阵H可以分解为 U(mxm) ,S(mxn) , V(nxn) 三个矩阵的乘积,这就是奇异值分解。S是一个对角矩阵,一般从大到小排列,S的元素值称为奇异值。
Matlab和python均提供奇异值分解的函数:
Matlab:

>> a = [1,2,3,4;2,3,5,3;6,4,1,3]

a =
     1     2     3     4
     2     3     5     3
     6     4     1     3

>> [u,s,v] = svd(a)

u =
   -0.4614    0.4307   -0.7756
   -0.5933    0.5002    0.6307
   -0.6596   -0.7512   -0.0247
s =
   10.7919         0         0         0
         0    4.4799         0         0
         0         0    1.5702         0
v =
   -0.5194   -0.6866    0.2148   -0.4610
   -0.4949   -0.1435    0.1540    0.8431
   -0.4643    0.6790    0.5106   -0.2503
   -0.5193    0.2165   -0.8182   -0.1186

Python:
 

import numpy as np       
def xsvd(H):    
    U, S, V = np.linalg.svd(H)  
    print('U:', U )  
    print('S:', S )  
    print('V:', V )  
    return U , S , V   
    
def UxSxV( U , S, V ) :  
    S1 = np.array( [ [S[0] , 0., 0.,0.] ,  
                     [0. , S[1] , 0.,0.] ,  
                     [0. , 0., S[2] ,0.]   
                    ] )  
    m1 = np.dot( U , S1 )  
    m2 = np.dot( m1 , V )  
    print ( m2 )  
    return m2   

def MxMtran(prom , U ) :
    print ( prom ) 
    Ut = np.transpose( U )
    print( Ut )
    I = np.dot( U , Ut )
    print ( I )
  
def main() :  
    H = np.array( [ [1.,2.,3.,4.],  
                 [2.,3.,5.,3.],  
                 [6.,4.,1.,3.]]  
               )  
    u, s , v = xsvd( H )  
    h = UxSxV ( u , s, v )  
    print( h-H < 0.00001 )
    MxMtran( 'U:' ,  u )
    MxMtran('V:' , v)
  
main()  
U: [[-0.46139677  0.4306905  -0.77564084]
 [-0.59330968  0.50021413  0.63068965]
 [-0.65961855 -0.75119339 -0.02473566]]
S: [10.79190564  4.47986284  1.57022343]
V: [[-0.51943815 -0.4949262  -0.46426993 -0.51931253]
 [-0.68663745 -0.14347541  0.67902721  0.21648525]
 [ 0.21482581  0.15401926  0.51062167 -0.81816469]
 [-0.46104544  0.84305453 -0.25028181 -0.11855454]]
[[1. 2. 3. 4.]
 [2. 3. 5. 3.]
 [6. 4. 1. 3.]]
[[ True  True  True  True]
 [ True  True  True  True]
 [ True  True  True  True]]
U:
[[-0.46139677 -0.59330968 -0.65961855]
 [ 0.4306905   0.50021413 -0.75119339]
 [-0.77564084  0.63068965 -0.02473566]]
[[1.00000000e+00 1.49283451e-16 6.66639328e-17]
 [1.49283451e-16 1.00000000e+00 1.64787722e-16]
 [6.66639328e-17 1.64787722e-16 1.00000000e+00]]
V:
[[-0.51943815 -0.68663745  0.21482581 -0.46104544]
 [-0.4949262  -0.14347541  0.15401926  0.84305453]
 [-0.46426993  0.67902721  0.51062167 -0.25028181]
 [-0.51931253  0.21648525 -0.81816469 -0.11855454]]
[[ 1.00000000e+00  7.26923038e-18  2.55496391e-17  1.26776949e-16]
 [ 7.26923038e-18  1.00000000e+00  3.23831057e-17  2.00324633e-16]
 [ 2.55496391e-17  3.23831057e-17  1.00000000e+00 -1.80240893e-16]
 [ 1.26776949e-16  2.00324633e-16 -1.80240893e-16  1.00000000e+00]]

可以看出,奇异值分解之后再相乘可以还原出原矩阵。与matlab不一样,Python分解出来的S矩阵使用一维数组表示,要矩阵乘的话,需要扩展成代码中的S1 。相应于python ,Matlab出来的V矩阵是转置的。Matlab更符合数学书里的讲法:


可以看出, 公式里的V转置之后作为乘数.所以Matlab导出的是V,而Python导出的是V的转置.

猜你喜欢

转载自blog.csdn.net/brooknew/article/details/80725662