Changeset 8023:3a19fbc01ae5


Ignore:
Timestamp:
12/11/07 04:17:47 (5 years ago)
Author:
Mike Hansen <mhansen@…>
Branch:
default
Message:

Added SVD to matrix_complex_double_dense.pyx and numpy SVD to matrix_real_double_dense.pyx

Location:
sage/matrix
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • sage/matrix/matrix_complex_double_dense.pyx

    r7361 r8023  
    175175                for i from 0<=i<self._ncols: 
    176176                    gsl_matrix_complex_set(self._matrix,i,i,z._complex) 
     177                     
    177178    cdef set_unsafe(self, Py_ssize_t i, Py_ssize_t j, value): 
    178179        cdef ComplexDoubleElement z 
     
    826827        return ans 
    827828 
    828  
     829    def SVD(self): 
     830        r""" 
     831        Return the singular value decomposition of this matrix. 
     832 
     833        INPUT: 
     834            A -- a matrix 
     835        OUTPUT: 
     836            U, S, V -- matrices such that A = U * S * V^t, where 
     837                       U and V are orthogonal and S is diagonal. 
     838 
     839 
     840        EXAMPLES: 
     841            sage: m = matrix(CDF,4,range(16)) 
     842            sage: U,S,V = m.SVD() 
     843            sage: U*S*V.transpose()    # slightly random output (due to computer architecture) 
     844            [3.45569519412e-16               1.0               2.0               3.0] 
     845            [4.0               5.0               6.0               7.0] 
     846            [8.0               9.0              10.0              11.0] 
     847            [12.0              13.0              14.0              15.0] 
     848 
     849        A non-square example: 
     850            sage: m = matrix(CDF, 2, range(6)); m 
     851            [  0 1.0 2.0] 
     852            [3.0 4.0 5.0] 
     853            sage: U, S, V = m.SVD() 
     854            sage: U 
     855            [-0.274721127897 -0.961523947641] 
     856            [-0.961523947641  0.274721127897] 
     857            sage: S 
     858            [7.34846922835             0             0] 
     859            [            0           1.0             0] 
     860            sage: V 
     861            [-0.392540507864  0.824163383692  0.408248290464] 
     862            [-0.560772154092  0.137360563949 -0.816496580928] 
     863            [ -0.72900380032 -0.549442255795  0.408248290464] 
     864            sage: U*S*V.transpose()           # random low bits 
     865            [7.62194127257e-17               1.0               2.0] 
     866            [              3.0               4.0               5.0] 
     867            sage: m = matrix(CDF,3,2,range(6)); m 
     868            [  0 1.0] 
     869            [2.0 3.0] 
     870            [4.0 5.0] 
     871            sage: U,S,V = m.SVD() 
     872            sage: U*S*V.transpose()   # random low order bits 
     873            [-8.13151629364e-19                1.0] 
     874            [               2.0                3.0] 
     875            [               4.0                5.0]             
     876 
     877        TESTS: 
     878            sage: m = matrix(CDF, 3, 0, []); m 
     879            [] 
     880            sage: m.SVD() 
     881            ([], [], []) 
     882            sage: m = matrix(CDF, 0, 3, []); m 
     883            []         
     884            sage: m.SVD() 
     885            ([], [], []) 
     886        """ 
     887        if self._nrows == 0 or self._ncols == 0: 
     888            U_t = self.new_matrix(self._nrows, self._ncols) 
     889            S_t = self.new_matrix(self._nrows, self._ncols) 
     890            V_t = self.new_matrix(self._ncols, self._nrows) 
     891            return U_t, S_t, V_t 
     892 
     893        import numpy.linalg 
     894        cdef int i, s_dim 
     895        P = self.parent() 
     896        CDF = P.base_ring() 
     897         
     898        U,_S,V = numpy.linalg.svd(self.numpy()) 
     899 
     900        #Create the inner diagonal matrix 
     901        s_dim = len(_S) 
     902        S = matrix(CDF, self._nrows, self._ncols, 0) 
     903        for i from 0 <= i < s_dim: 
     904            S[(i,i)] = _S[i] 
     905 
     906        return (matrix(U),S,matrix(V).transpose()) 
     907                                  
     908         
  • sage/matrix/matrix_real_double_dense.pyx

    r7361 r8023  
    629629        return trans 
    630630 
    631     def SVD(self): 
     631    def SVD(self, algorithm='gsl'): 
    632632        r""" 
    633633        Return the singular value decomposition of this matrix. 
     
    635635        INPUT: 
    636636            A -- a matrix 
     637            algorithm -- 'numpy' or 'gsl' 
    637638        OUTPUT: 
    638639            U, S, V -- matrices such that A = U * S * V^t, where 
     
    642643        EXAMPLES: 
    643644            sage: m = matrix(RDF,4,range(16)) 
    644             sage: U,S,V = m.SVD() 
     645            sage: U,S,V = m.SVD(algorithm='gsl') 
    645646            sage: U*S*V.transpose()    # slightly random output (due to computer architecture) 
    646647            [3.45569519412e-16               1.0               2.0               3.0] 
     
    653654            [0.0 1.0 2.0] 
    654655            [3.0 4.0 5.0] 
     656            sage: U, S, V = m.SVD(algorithm='numpy') 
     657            sage: U*S*V.transpose()           # random low bits 
     658            [7.62194127257e-17               1.0               2.0] 
     659            [              3.0               4.0               5.0]             
    655660            sage: U, S, V = m.SVD() 
    656661            sage: U 
     
    671676            [2.0 3.0] 
    672677            [4.0 5.0] 
     678            sage: U,S,V = m.SVD(algorithm='numpy') 
     679            sage: U*S*V.transpose()   # random low order bits 
     680            [-8.13151629364e-19                1.0] 
     681            [               2.0                3.0] 
     682            [               4.0                5.0]   
    673683            sage: U,S,V = m.SVD() 
    674684            sage: U*S*V.transpose()   # random low order bits 
    675685            [-8.13151629364e-19                1.0] 
    676686            [               2.0                3.0] 
    677             [               4.0                5.0]             
     687            [               4.0                5.0] 
     688 
    678689 
    679690        TESTS: 
     
    687698            ([], [], []) 
    688699        """ 
     700        if algorithm == 'numpy': 
     701            return self._SVD_numpy() 
     702        elif algorithm == 'gsl': 
     703            return self._SVD_gsl() 
     704        else: 
     705            raise ValueError, "unknown algorithm" 
     706         
     707    def _SVD_gsl(self): 
     708        """ 
     709        Return the singular value decomposition of this matrix 
     710        using GSL.  Note that the matrices the dimensions of the 
     711        matrices that this returns are (m,p), (p,p), and (n, p) 
     712        where p = min(m,n). 
     713 
     714        EXAMPLES: 
     715            sage: def shape(x): return (x.nrows(), x.ncols()) 
     716            sage: m = matrix(RDF, 2, 3, range(6)) 
     717            sage: map(shape, m._SVD_gsl()) 
     718            [(2, 2), (2, 2), (3, 2)] 
     719 
     720        """ 
    689721        if self._ncols > self._nrows: 
    690722            m = self.transpose() 
    691723            V_t,S_t,U_t = m.SVD() 
    692724            return U_t,S_t,V_t 
     725         
    693726        if self._nrows == 0 or self._ncols == 0: 
    694727            U_t = self.new_matrix(self._nrows, self._ncols) 
     
    719752        return A,_S,V 
    720753 
     754    def _SVD_numpy(self): 
     755        """ 
     756        Return the singular value decomposition of this matrix 
     757        using GSL.  Note that the matrices the dimensions of the 
     758        matrices that this returns are (m,m), (m,n), and (n, n). 
     759 
     760        EXAMPLES: 
     761            sage: def shape(x): return (x.nrows(), x.ncols()) 
     762            sage: m = matrix(RDF, 2, 3, range(6)) 
     763            sage: map(shape, m._SVD_numpy()) 
     764            [(2, 2), (2, 3), (3, 3)] 
     765 
     766        """ 
     767        if self._nrows == 0 or self._ncols == 0: 
     768            U_t = self.new_matrix(self._nrows, self._ncols) 
     769            S_t = self.new_matrix(self._nrows, self._ncols) 
     770            V_t = self.new_matrix(self._ncols, self._nrows) 
     771            return U_t, S_t, V_t 
     772 
     773        import numpy.linalg 
     774        cdef int i, s_dim 
     775        P = self.parent() 
     776        CDF = P.base_ring() 
     777         
     778        U,_S,V = numpy.linalg.svd(self.numpy()) 
     779 
     780        #Create the inner diagonal matrix 
     781        s_dim = len(_S) 
     782        S = matrix(CDF, self._nrows, self._ncols, 0) 
     783        for i from 0 <= i < s_dim: 
     784            S[(i,i)] = _S[i] 
     785 
     786        return (matrix(U),S,matrix(V).transpose()) 
     787                                  
     788         
     789 
     790 
     791 
    721792    def QR(self): 
    722793        """ 
Note: See TracChangeset for help on using the changeset viewer.