#NEWLINE# @ defun #NEWLINE# def svd_c( ctx , A , full_matrices = False , compute_uv = True , overwrite_a = False ) : #NEWLINE# #INDENT# "\n    This routine computes the singular value decomposition of a matrix A.\n    Given A, two unitary matrices U and V are calculated such that\n\n           A = U S V        and        U' U = 1         and         V V' = 1\n\n    where S is a suitable shaped matrix whose off-diagonal elements are zero.\n    Here ' denotes the hermitian transpose (i.e. transposition and complex\n    conjugation). The diagonal elements of S are the singular values of A,\n    i.e. the squareroots of the eigenvalues of A' A or A A'.\n\n    input:\n      A             : a complex matrix of shape (m, n)\n      full_matrices : if true, U and V are of shape (m, m) and (n, n).\n                      if false, U and V are of shape (m, min(m, n)) and (min(m, n), n).\n      compute_uv    : if true, U and V are calculated. if false, only S is calculated.\n      overwrite_a   : if true, allows modification of A which may improve\n                      performance. if false, A is not modified.\n\n    output:\n      U : an unitary matrix: U' U = 1. if full_matrices is true, U is of\n          shape (m, m). ortherwise it is of shape (m, min(m, n)).\n\n      S : an array of length min(m, n) containing the singular values of A sorted by\n          decreasing magnitude.\n\n      V : an unitary matrix: V V' = 1. if full_matrices is true, V is of\n          shape (n, n). ortherwise it is of shape (min(m, n), n).\n\n    return value:\n\n           S          if compute_uv is false\n       (U, S, V)      if compute_uv is true\n\n    overview of the matrices:\n\n      full_matrices true:\n        A           : m*n\n        U           : m*m     U' U  = 1\n        S as matrix : m*n\n        V           : n*n     V  V' = 1\n\n     full_matrices false:\n        A           : m*n\n        U           : m*min(n,m)             U' U  = 1\n        S as matrix : min(m,n)*min(m,n)\n        V           : min(m,n)*n             V  V' = 1\n\n    example:\n      >>> from mpmath import mp\n      >>> A = mp.matrix([[-2j, -1-3j, -2+2j], [2-2j, -1-3j, 1], [-3+1j,-2j,0]])\n      >>> S = mp.svd_c(A, compute_uv = False)\n      >>> print(mp.chop(S - mp.matrix([mp.sqrt(34), mp.sqrt(15), mp.sqrt(6)])))\n      [0.0]\n      [0.0]\n      [0.0]\n\n      >>> U, S, V = mp.svd_c(A)\n      >>> print(mp.chop(A - U * mp.diag(S) * V))\n      [0.0  0.0  0.0]\n      [0.0  0.0  0.0]\n      [0.0  0.0  0.0]\n\n    see also: svd, svd_r\n    " #NEWLINE# ( m , n ) = ( A . rows , A . cols ) #NEWLINE# if ( not compute_uv ) : #NEWLINE# #INDENT# if ( not overwrite_a ) : #NEWLINE# #INDENT# A = A . copy ( ) #NEWLINE# #UNINDENT# S = svd_c_raw ( ctx , A , V = False , calc_u = False ) #NEWLINE# S = S [ : min ( m , n ) ] #NEWLINE# return S #NEWLINE# #UNINDENT# if ( full_matrices and ( n < m ) ) : #NEWLINE# #INDENT# V = ctx . zeros ( m , m ) #NEWLINE# A0 = ctx . zeros ( m , m ) #NEWLINE# A0 [ : , : n ] = A #NEWLINE# S = svd_c_raw ( ctx , A0 , V , calc_u = True ) #NEWLINE# S = S [ : n ] #NEWLINE# V = V [ : n , : n ] #NEWLINE# return ( A0 , S , V ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( not overwrite_a ) : #NEWLINE# #INDENT# A = A . copy ( ) #NEWLINE# #UNINDENT# V = ctx . zeros ( n , n ) #NEWLINE# S = svd_c_raw ( ctx , A , V , calc_u = True ) #NEWLINE# if ( n > m ) : #NEWLINE# #INDENT# if ( full_matrices == False ) : #NEWLINE# #INDENT# V = V [ : m , : ] #NEWLINE# #UNINDENT# S = S [ : m ] #NEWLINE# A = A [ : , : m ] #NEWLINE# #UNINDENT# return ( A , S , V )