def svd(a,full_matrices=1,compute_uv=1,overwrite_a=0): """Compute singular value decomposition (SVD) of matrix a. Description: Singular value decomposition of a matrix a is a = u * sigma * v^H, where v^H denotes conjugate(transpose(v)), u,v are unitary matrices, sigma is zero matrix with a main diagonal containing real non-negative singular values of the matrix a. Inputs: a -- An M x N matrix. compute_uv -- If zero, then only the vector of singular values is returned. Outputs: u -- An M x M unitary matrix [compute_uv=1]. s -- An min(M,N) vector of singular values in descending order, sigma = diagsvd(s). vh -- An N x N unitary matrix [compute_uv=1], vh = v^H. """ # A hack until full_matrices == 0 support is fixed here. if full_matrices == 0: import numpy.linalg return numpy.linalg.svd(a, full_matrices=0, compute_uv=compute_uv) a1 = asarray_chkfinite(a) if len(a1.shape) != 2: raise ValueError, 'expected matrix' m,n = a1.shape overwrite_a = overwrite_a or (_datanotshared(a1,a)) gesdd, = get_lapack_funcs(('gesdd',),(a1,)) if gesdd.module_name[:7] == 'flapack': lwork = calc_lwork.gesdd(gesdd.prefix,m,n,compute_uv)[1] u,s,v,info = gesdd(a1,compute_uv = compute_uv, lwork = lwork, overwrite_a = overwrite_a) else: # 'clapack' raise NotImplementedError,'calling gesdd from %s' % (gesdd.module_name) if info>0: raise LinAlgError, "SVD did not converge" if info<0: raise ValueError,\ 'illegal value in %-th argument of internal gesdd'%(-info) if compute_uv: return u,s,v else: return s
def svd(a, full_matrices=True, compute_uv=True, overwrite_a=False): """ Singular Value Decomposition. Factorizes the matrix a into two unitary matrices U and Vh, and a 1-D array s of singular values (real, non-negative) such that ``a == U*S*Vh``, where S is a suitably shaped matrix of zeros with main diagonal s. Parameters ---------- a : ndarray Matrix to decompose, of shape ``(M,N)``. full_matrices : bool, optional If True, `U` and `Vh` are of shape ``(M,M)``, ``(N,N)``. If False, the shapes are ``(M,K)`` and ``(K,N)``, where ``K = min(M,N)``. compute_uv : bool, optional Whether to compute also `U` and `Vh` in addition to `s`. Default is True. overwrite_a : bool, optional Whether to overwrite `a`; may improve performance. Default is False. Returns ------- U : ndarray Unitary matrix having left singular vectors as columns. Of shape ``(M,M)`` or ``(M,K)``, depending on `full_matrices`. s : ndarray The singular values, sorted in non-increasing order. Of shape (K,), with ``K = min(M, N)``. Vh : ndarray Unitary matrix having right singular vectors as rows. Of shape ``(N,N)`` or ``(K,N)`` depending on `full_matrices`. For ``compute_uv = False``, only `s` is returned. Raises ------ LinAlgError If SVD computation does not converge. See also -------- svdvals : Compute singular values of a matrix. diagsvd : Construct the Sigma matrix, given the vector s. Examples -------- >>> from scipy import linalg >>> a = np.random.randn(9, 6) + 1.j*np.random.randn(9, 6) >>> U, s, Vh = linalg.svd(a) >>> U.shape, Vh.shape, s.shape ((9, 9), (6, 6), (6,)) >>> U, s, Vh = linalg.svd(a, full_matrices=False) >>> U.shape, Vh.shape, s.shape ((9, 6), (6, 6), (6,)) >>> S = linalg.diagsvd(s, 6, 6) >>> np.allclose(a, np.dot(U, np.dot(S, Vh))) True >>> s2 = linalg.svd(a, compute_uv=False) >>> np.allclose(s, s2) True """ a1 = asarray_chkfinite(a) if len(a1.shape) != 2: raise ValueError('expected matrix') m, n = a1.shape overwrite_a = overwrite_a or (_datacopied(a1, a)) gesdd, = get_lapack_funcs(('gesdd', ), (a1, )) if gesdd.module_name[:7] == 'flapack': lwork = calc_lwork.gesdd(gesdd.prefix, m, n, compute_uv)[1] u, s, v, info = gesdd(a1, compute_uv=compute_uv, lwork=lwork, full_matrices=full_matrices, overwrite_a=overwrite_a) else: # 'clapack' raise NotImplementedError('calling gesdd from %s' % gesdd.module_name) if info > 0: raise LinAlgError("SVD did not converge") if info < 0: raise ValueError('illegal value in %d-th argument of internal gesdd' % -info) if compute_uv: return u, s, v else: return s
def svd(a, full_matrices=True, compute_uv=True, overwrite_a=False): """Singular Value Decomposition. Factorizes the matrix a into two unitary matrices U and Vh and an 1d-array s of singular values (real, non-negative) such that a == U S Vh if S is an suitably shaped matrix of zeros whose main diagonal is s. Parameters ---------- a : array, shape (M, N) Matrix to decompose full_matrices : boolean If true, U, Vh are shaped (M,M), (N,N) If false, the shapes are (M,K), (K,N) where K = min(M,N) compute_uv : boolean Whether to compute also U, Vh in addition to s (Default: true) overwrite_a : boolean Whether data in a is overwritten (may improve performance) Returns ------- U: array, shape (M,M) or (M,K) depending on full_matrices s: array, shape (K,) The singular values, sorted so that s[i] >= s[i+1]. K = min(M, N) Vh: array, shape (N,N) or (K,N) depending on full_matrices For compute_uv = False, only s is returned. Raises LinAlgError if SVD computation does not converge Examples -------- >>> from scipy import random, linalg, allclose, dot >>> a = random.randn(9, 6) + 1j*random.randn(9, 6) >>> U, s, Vh = linalg.svd(a) >>> U.shape, Vh.shape, s.shape ((9, 9), (6, 6), (6,)) >>> U, s, Vh = linalg.svd(a, full_matrices=False) >>> U.shape, Vh.shape, s.shape ((9, 6), (6, 6), (6,)) >>> S = linalg.diagsvd(s, 6, 6) >>> allclose(a, dot(U, dot(S, Vh))) True >>> s2 = linalg.svd(a, compute_uv=False) >>> allclose(s, s2) True See also -------- svdvals : return singular values of a matrix diagsvd : return the Sigma matrix, given the vector s """ # A hack until full_matrices == 0 support is fixed here. if full_matrices == 0: import numpy.linalg return numpy.linalg.svd(a, full_matrices=0, compute_uv=compute_uv) a1 = asarray_chkfinite(a) if len(a1.shape) != 2: raise ValueError('expected matrix') m, n = a1.shape overwrite_a = overwrite_a or (_datanotshared(a1, a)) gesdd, = get_lapack_funcs(('gesdd', ), (a1, )) if gesdd.module_name[:7] == 'flapack': lwork = calc_lwork.gesdd(gesdd.prefix, m, n, compute_uv)[1] u, s, v, info = gesdd(a1, compute_uv=compute_uv, lwork=lwork, overwrite_a=overwrite_a) else: # 'clapack' raise NotImplementedError('calling gesdd from %s' % gesdd.module_name) if info > 0: raise LinAlgError("SVD did not converge") if info < 0: raise ValueError('illegal value in %d-th argument of internal gesdd' % -info) if compute_uv: return u, s, v else: return s
def svd(a, full_matrices=True, compute_uv=True, overwrite_a=False): """ Singular Value Decomposition. Factorizes the matrix a into two unitary matrices U and Vh, and a 1-D array s of singular values (real, non-negative) such that ``a == U*S*Vh``, where S is a suitably shaped matrix of zeros with main diagonal s. Parameters ---------- a : ndarray Matrix to decompose, of shape ``(M,N)``. full_matrices : bool, optional If True, `U` and `Vh` are of shape ``(M,M)``, ``(N,N)``. If False, the shapes are ``(M,K)`` and ``(K,N)``, where ``K = min(M,N)``. compute_uv : bool, optional Whether to compute also `U` and `Vh` in addition to `s`. Default is True. overwrite_a : bool, optional Whether to overwrite `a`; may improve performance. Default is False. Returns ------- U : ndarray Unitary matrix having left singular vectors as columns. Of shape ``(M,M)`` or ``(M,K)``, depending on `full_matrices`. s : ndarray The singular values, sorted in non-increasing order. Of shape (K,), with ``K = min(M, N)``. Vh : ndarray Unitary matrix having right singular vectors as rows. Of shape ``(N,N)`` or ``(K,N)`` depending on `full_matrices`. For ``compute_uv = False``, only `s` is returned. Raises ------ LinAlgError If SVD computation does not converge. See also -------- svdvals : Compute singular values of a matrix. diagsvd : Construct the Sigma matrix, given the vector s. Examples -------- >>> from scipy import linalg >>> a = np.random.randn(9, 6) + 1.j*np.random.randn(9, 6) >>> U, s, Vh = linalg.svd(a) >>> U.shape, Vh.shape, s.shape ((9, 9), (6, 6), (6,)) >>> U, s, Vh = linalg.svd(a, full_matrices=False) >>> U.shape, Vh.shape, s.shape ((9, 6), (6, 6), (6,)) >>> S = linalg.diagsvd(s, 6, 6) >>> np.allclose(a, np.dot(U, np.dot(S, Vh))) True >>> s2 = linalg.svd(a, compute_uv=False) >>> np.allclose(s, s2) True """ a1 = asarray_chkfinite(a) if len(a1.shape) != 2: raise ValueError('expected matrix') m,n = a1.shape overwrite_a = overwrite_a or (_datacopied(a1, a)) gesdd, = get_lapack_funcs(('gesdd',), (a1,)) if gesdd.module_name[:7] == 'flapack': lwork = calc_lwork.gesdd(gesdd.prefix, m, n, compute_uv)[1] u,s,v,info = gesdd(a1,compute_uv = compute_uv, lwork = lwork, full_matrices=full_matrices, overwrite_a = overwrite_a) else: # 'clapack' raise NotImplementedError('calling gesdd from %s' % gesdd.module_name) if info > 0: raise LinAlgError("SVD did not converge") if info < 0: raise ValueError('illegal value in %d-th argument of internal gesdd' % -info) if compute_uv: return u, s, v else: return s
def svd(a, full_matrices=True, compute_uv=True, overwrite_a=False): """Singular Value Decomposition. Factorizes the matrix a into two unitary matrices U and Vh and an 1d-array s of singular values (real, non-negative) such that a == U S Vh if S is an suitably shaped matrix of zeros whose main diagonal is s. Parameters ---------- a : array, shape (M, N) Matrix to decompose full_matrices : boolean If true, U, Vh are shaped (M,M), (N,N) If false, the shapes are (M,K), (K,N) where K = min(M,N) compute_uv : boolean Whether to compute also U, Vh in addition to s (Default: true) overwrite_a : boolean Whether data in a is overwritten (may improve performance) Returns ------- U: array, shape (M,M) or (M,K) depending on full_matrices s: array, shape (K,) The singular values, sorted so that s[i] >= s[i+1]. K = min(M, N) Vh: array, shape (N,N) or (K,N) depending on full_matrices For compute_uv = False, only s is returned. Raises LinAlgError if SVD computation does not converge Examples -------- >>> from scipy import random, linalg, allclose, dot >>> a = random.randn(9, 6) + 1j*random.randn(9, 6) >>> U, s, Vh = linalg.svd(a) >>> U.shape, Vh.shape, s.shape ((9, 9), (6, 6), (6,)) >>> U, s, Vh = linalg.svd(a, full_matrices=False) >>> U.shape, Vh.shape, s.shape ((9, 6), (6, 6), (6,)) >>> S = linalg.diagsvd(s, 6, 6) >>> allclose(a, dot(U, dot(S, Vh))) True >>> s2 = linalg.svd(a, compute_uv=False) >>> allclose(s, s2) True See also -------- svdvals : return singular values of a matrix diagsvd : return the Sigma matrix, given the vector s """ # A hack until full_matrices == 0 support is fixed here. if full_matrices == 0: import numpy.linalg return numpy.linalg.svd(a, full_matrices=0, compute_uv=compute_uv) a1 = asarray_chkfinite(a) if len(a1.shape) != 2: raise ValueError('expected matrix') m,n = a1.shape overwrite_a = overwrite_a or (_datacopied(a1, a)) gesdd, = get_lapack_funcs(('gesdd',), (a1,)) gesdd_info = get_func_info(gesdd) if gesdd_info.module_name[:7] == 'flapack': lwork = calc_lwork.gesdd(gesdd_info.prefix, m, n, compute_uv)[1] u,s,v,info = gesdd(a1,compute_uv = compute_uv, lwork = lwork, overwrite_a = overwrite_a) else: # 'clapack' raise NotImplementedError('calling gesdd from %s' % gesdd_info.module_name) if info > 0: raise LinAlgError("SVD did not converge") if info < 0: raise ValueError('illegal value in %d-th argument of internal gesdd' % -info) if compute_uv: return u, s, v else: return s
def svd(a, full_matrices=True, compute_uv=True, overwrite_a=False, check_finite=True, returns="U, S, V"): """ Singular Value Decomposition. Factorizes the matrix a into two unitary matrices U and Vh, and a diagonal matrix S of suitable shape with non-negative real numbers on the diagonal. . Parameters ---------- a : (M, N) array_like Matrix to decompose. full_matrices : bool, optional If True, `U` and `Vh` are of shape ``(M,M)``, ``(N,N)``. If False, the shapes are ``(M,K)`` and ``(K,N)``, where ``K = min(M,N)``. overwrite_a : bool, optional Whether to overwrite `a`; may improve performance. Default is False. check_finite : boolean, optional Whether to check that the input matrix contains only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. returns: string, optional Select the returned values, among ``U``, ``S``, ``s``, ``V`` and ``Vh``,. Default is ``"U, S, Vh"``. Returns ------- The selection of return values is configurable by the ``returns`` parameter. U : ndarray Unitary matrix having left singular vectors as columns. Of shape ``(M,M)`` or ``(M,K)``, depending on `full_matrices`. S : ndarray A matrix with the singular values of ``a``, sorted in non-increasing order, in the main diagonal and zeros elsewhere. Of shape ``(M,N)`` or ``(K,K)``, depending on `full_matrices`. V : ndarray Unitary matrix having right singular vectors as columns. Of shape ``(N,N)`` or ``(N, K)`` depending on `full_matrices`. s : ndarray, not returned by default The singular values, sorted in non-increasing order. Of shape (K,), with ``K = min(M, N)``. Vh : ndarray Unitary matrix having right singular vectors as rows. Of shape ``(N,N)`` or ``(N, K)`` depending on `full_matrices`. Raises ------ LinAlgError If SVD computation does not converge. Examples -------- >>> import numpy as np >>> from wish.examples import svd >>> a = np.random.randn(9, 6) + 1.j*np.random.randn(9, 6) >>> U, S, V = svd(a) >>> U.shape, S.shape, V.shape ((9, 9), (9, 6), (6, 6)) >>> U, S, Vh = svd(a, full_matrices=False, returns="U, S, Vh") >>> U.shape, S.shape, Vh.shape ((9, 9), (9, 6), (6, 6)) >>> np.allclose(a, np.dot(U, np.dot(S, Vh))) True >>> s = svd(a, returns="s") >>> np.allclose(s, np.diagonal(S)) True """ wishlist = wish.make(returns) for name in wishlist: if name not in ["U", "S", "V", "s", "Vh"]: error = "unexpected return value {name!r}" raise TypeError(error.format(name=name)) if check_finite: a1 = asarray_chkfinite(a) else: a1 = asarray(a) if len(a1.shape) != 2: raise ValueError('expected matrix') m,n = a1.shape overwrite_a = overwrite_a or (_datacopied(a1, a)) gesdd, = get_lapack_funcs(('gesdd',), (a1,)) lwork = calc_lwork.gesdd(gesdd.typecode, m, n, compute_uv)[1] compute_uv = "U" in wishlist or "V" in wishlist or "Vh" in wishlist U,s,Vh,info = gesdd(a1,compute_uv=compute_uv, lwork=lwork, full_matrices=full_matrices, overwrite_a=overwrite_a) if info > 0: raise LinAlgError("SVD did not converge") if info < 0: raise ValueError('illegal value in %d-th argument of internal gesdd' % -info) if "V" in wishlist: V = Vh.transpose().conjugate() if "S" in wishlist: S = _diagsvd(s, U.shape[1], Vh.shape[0]) # f**k, maybe not computed. Use shape of A. # Interaction with full_matrices? return wishlist.grant()