def norm(x, ord=2): """ norm(x, ord=2) -> n Matrix and vector norm. Inputs: x -- a rank-1 (vector) or rank-2 (matrix) array ord -- the order of norm. Comments: For vectors ord can be any real number including Inf or -Inf. ord = Inf, computes the maximum of the magnitudes ord = -Inf, computes minimum of the magnitudes ord is finite, computes sum(abs(x)**ord)**(1.0/ord) For matrices ord can only be + or - 1, 2, Inf. ord = 2 computes the largest singular value ord = -2 computes the smallest singular value ord = 1 computes the largest column sum of absolute values ord = -1 computes the smallest column sum of absolute values ord = Inf computes the largest row sum of absolute values ord = -Inf computes the smallest row sum of absolute values ord = 'fro' computes the frobenius norm sqrt(sum(diag(X.H * X))) """ x = asarray_chkfinite(x) nd = len(x.shape) Inf = scipy_base.Inf if nd == 1: if ord == Inf: return scipy_base.amax(abs(x)) elif ord == -Inf: return scipy_base.amin(abs(x)) else: return scipy_base.sum(abs(x)**ord)**(1.0/ord) elif nd == 2: if ord == 2: return scipy_base.amax(decomp.svd(x,compute_uv=0)) elif ord == -2: return scipy_base.amin(decomp.svd(x,compute_uv=0)) elif ord == 1: return scipy_base.amax(scipy_base.sum(abs(x))) elif ord == Inf: return scipy_base.amax(scipy_base.sum(abs(x),axis=1)) elif ord == -1: return scipy_base.amin(scipy_base.sum(abs(x))) elif ord == -Inf: return scipy_base.amin(scipy_base.sum(abs(x),axis=1)) elif ord in ['fro','f']: val = real((conjugate(x)*x).flat) return sqrt(add.reduce(val)) else: raise ValueError, "Invalid norm order for matrices." else: raise ValueError, "Improper number of dimensions to norm."
def pinv2(a, cond=None, rcond=None): """Compute the (Moore-Penrose) pseudo-inverse of a matrix. Calculate a generalized inverse of a matrix using its singular-value decomposition and including all 'large' singular values. Parameters ---------- a : array, shape (M, N) Matrix to be pseudo-inverted cond, rcond : float or None Cutoff for 'small' singular values. Singular values smaller than rcond*largest_singular_value are considered zero. If None or -1, suitable machine precision is used. Returns ------- B : array, shape (N, M) Raises LinAlgError if SVD computation does not converge Examples -------- >>> from numpy import * >>> a = random.randn(9, 6) >>> B = linalg.pinv2(a) >>> allclose(a, dot(a, dot(B, a))) True >>> allclose(B, dot(B, dot(a, B))) True """ a = asarray_chkfinite(a) u, s, vh = decomp.svd(a) t = u.dtype.char if rcond is not None: cond = rcond if cond in [None, -1]: cond = {0: feps * 1e3, 1: eps * 1e6}[_array_precision[t]] m, n = a.shape cutoff = cond * numpy.maximum.reduce(s) psigma = zeros((m, n), t) for i in range(len(s)): if s[i] > cutoff: psigma[i, i] = 1.0 / conjugate(s[i]) # XXX: use lapack/blas routines for dot return transpose(conjugate(dot(dot(u, psigma), vh)))
def pinv2(a, cond=None, rcond=None): """Compute the (Moore-Penrose) pseudo-inverse of a matrix. Calculate a generalized inverse of a matrix using its singular-value decomposition and including all 'large' singular values. Parameters ---------- a : array, shape (M, N) Matrix to be pseudo-inverted cond, rcond : float or None Cutoff for 'small' singular values. Singular values smaller than rcond*largest_singular_value are considered zero. If None or -1, suitable machine precision is used. Returns ------- B : array, shape (N, M) Raises LinAlgError if SVD computation does not converge Examples -------- >>> from numpy import * >>> a = random.randn(9, 6) >>> B = linalg.pinv2(a) >>> allclose(a, dot(a, dot(B, a))) True >>> allclose(B, dot(B, dot(a, B))) True """ a = asarray_chkfinite(a) u, s, vh = decomp.svd(a) t = u.dtype.char if rcond is not None: cond = rcond if cond in [None, -1]: cond = {0: feps * 1e3, 1: eps * 1e6}[_array_precision[t]] m, n = a.shape cutoff = cond * numpy.maximum.reduce(s) psigma = zeros((m, n), t) for i in range(len(s)): if s[i] > cutoff: psigma[i, i] = 1.0 / conjugate(s[i]) #XXX: use lapack/blas routines for dot return transpose(conjugate(dot(dot(u, psigma), vh)))
def signm(a,disp=1): """matrix sign""" def rounded_sign(x): rx = real(x) if rx.dtype.char=='f': c = 1e3*feps*amax(x) else: c = 1e3*eps*amax(x) return sign( (absolute(rx) > c) * rx ) result,errest = funm(a, rounded_sign, disp=0) errtol = {0:1e3*feps, 1:1e3*eps}[_array_precision[result.dtype.char]] if errest < errtol: return result # Handle signm of defective matrices: # See "E.D.Denman and J.Leyva-Ramos, Appl.Math.Comp., # 8:237-250,1981" for how to improve the following (currently a # rather naive) iteration process: a = asarray(a) #a = result # sometimes iteration converges faster but where?? # Shifting to avoid zero eigenvalues. How to ensure that shifting does # not change the spectrum too much? vals = svd(a,compute_uv=0) max_sv = sb.amax(vals) #min_nonzero_sv = vals[(vals>max_sv*errtol).tolist().count(1)-1] #c = 0.5/min_nonzero_sv c = 0.5/max_sv S0 = a + c*sb.identity(a.shape[0]) prev_errest = errest for i in range(100): iS0 = inv(S0) S0 = 0.5*(S0 + iS0) Pp=0.5*(dot(S0,S0)+S0) errest = norm(dot(Pp,Pp)-Pp,1) if errest < errtol or prev_errest==errest: break prev_errest = errest if disp: if not isfinite(errest) or errest >= errtol: print "Result may be inaccurate, approximate err =", errest return S0 else: return S0, errest
def pinv2(a, cond=None): """ pinv2(a, cond=None) -> a_pinv Compute the generalized inverse of A using svd. """ a = asarray_chkfinite(a) u, s, vh = decomp.svd(a) t = u.typecode() if cond in [None,-1]: cond = {0: feps*1e3, 1: eps*1e6}[_array_precision[t]] m,n = a.shape cutoff = cond*scipy_base.maximum.reduce(s) psigma = zeros((m,n),t) for i in range(len(s)): if s[i] > cutoff: psigma[i,i] = 1.0/conjugate(s[i]) #XXX: use lapack/blas routines for dot return transpose(conjugate(dot(dot(u,psigma),vh)))
def norm(x, ord=None): """ norm(x, ord=None) -> n Matrix or vector norm. Inputs: x -- a rank-1 (vector) or rank-2 (matrix) array ord -- the order of the norm. Comments: For arrays of any rank, if ord is None: calculate the square norm (Euclidean norm for vectors, Frobenius norm for matrices) For vectors ord can be any real number including Inf or -Inf. ord = Inf, computes the maximum of the magnitudes ord = -Inf, computes minimum of the magnitudes ord is finite, computes sum(abs(x)**ord,axis=0)**(1.0/ord) For matrices ord can only be one of the following values: ord = 2 computes the largest singular value ord = -2 computes the smallest singular value ord = 1 computes the largest column sum of absolute values ord = -1 computes the smallest column sum of absolute values ord = Inf computes the largest row sum of absolute values ord = -Inf computes the smallest row sum of absolute values ord = 'fro' computes the frobenius norm sqrt(sum(diag(X.H * X),axis=0)) For values ord < 0, the result is, strictly speaking, not a mathematical 'norm', but it may still be useful for numerical purposes. """ x = asarray_chkfinite(x) if ord is None: # check the default case first and handle it immediately return sqrt(add.reduce(real((conjugate(x)*x).ravel()))) nd = len(x.shape) Inf = numpy.Inf if nd == 1: if ord == Inf: return numpy.amax(abs(x)) elif ord == -Inf: return numpy.amin(abs(x)) elif ord == 1: return numpy.sum(abs(x),axis=0) # special case for speedup elif ord == 2: return sqrt(numpy.sum(real((conjugate(x)*x)),axis=0)) # special case for speedup else: return numpy.sum(abs(x)**ord,axis=0)**(1.0/ord) elif nd == 2: if ord == 2: return numpy.amax(decomp.svd(x,compute_uv=0)) elif ord == -2: return numpy.amin(decomp.svd(x,compute_uv=0)) elif ord == 1: return numpy.amax(numpy.sum(abs(x),axis=0)) elif ord == Inf: return numpy.amax(numpy.sum(abs(x),axis=1)) elif ord == -1: return numpy.amin(numpy.sum(abs(x),axis=0)) elif ord == -Inf: return numpy.amin(numpy.sum(abs(x),axis=1)) elif ord in ['fro','f']: return sqrt(add.reduce(real((conjugate(x)*x).ravel()))) else: raise ValueError, "Invalid norm order for matrices." else: raise ValueError, "Improper number of dimensions to norm."
def norm(x, ord=None): """Matrix or vector norm. Parameters ---------- x : array, shape (M,) or (M, N) ord : number, or {None, 1, -1, 2, -2, inf, -inf, 'fro'} Order of the norm: ===== ============================ ========================== ord norm for matrices norm for vectors ===== ============================ ========================== None Frobenius norm 2-norm 'fro' Frobenius norm -- inf max(sum(abs(x), axis=1)) max(abs(x)) -inf min(sum(abs(x), axis=1)) min(abs(x)) 1 max(sum(abs(x), axis=0)) as below -1 min(sum(abs(x), axis=0)) as below 2 2-norm (largest sing. value) as below -2 smallest singular value as below other -- sum(abs(x)**ord)**(1./ord) ===== ============================ ========================== Returns ------- n : float Norm of the matrix or vector Notes ----- For values ord < 0, the result is, strictly speaking, not a mathematical 'norm', but it may still be useful for numerical purposes. """ x = asarray_chkfinite(x) if ord is None: # check the default case first and handle it immediately return sqrt(add.reduce(real((conjugate(x) * x).ravel()))) nd = len(x.shape) Inf = numpy.Inf if nd == 1: if ord == Inf: return numpy.amax(abs(x)) elif ord == -Inf: return numpy.amin(abs(x)) elif ord == 1: return numpy.sum(abs(x), axis=0) # special case for speedup elif ord == 2: return sqrt(numpy.sum(real((conjugate(x) * x)), axis=0)) # special case for speedup else: return numpy.sum(abs(x)**ord, axis=0)**(1.0 / ord) elif nd == 2: if ord == 2: return numpy.amax(decomp.svd(x, compute_uv=0)) elif ord == -2: return numpy.amin(decomp.svd(x, compute_uv=0)) elif ord == 1: return numpy.amax(numpy.sum(abs(x), axis=0)) elif ord == Inf: return numpy.amax(numpy.sum(abs(x), axis=1)) elif ord == -1: return numpy.amin(numpy.sum(abs(x), axis=0)) elif ord == -Inf: return numpy.amin(numpy.sum(abs(x), axis=1)) elif ord in ['fro', 'f']: return sqrt(add.reduce(real((conjugate(x) * x).ravel()))) else: raise ValueError, "Invalid norm order for matrices." else: raise ValueError, "Improper number of dimensions to norm."
def norm(x, ord=None): """Matrix or vector norm. Parameters ---------- x : array, shape (M,) or (M, N) ord : number, or {None, 1, -1, 2, -2, inf, -inf, 'fro'} Order of the norm: ===== ============================ ========================== ord norm for matrices norm for vectors ===== ============================ ========================== None Frobenius norm 2-norm 'fro' Frobenius norm -- inf max(sum(abs(x), axis=1)) max(abs(x)) -inf min(sum(abs(x), axis=1)) min(abs(x)) 1 max(sum(abs(x), axis=0)) as below -1 min(sum(abs(x), axis=0)) as below 2 2-norm (largest sing. value) as below -2 smallest singular value as below other -- sum(abs(x)**ord)**(1./ord) ===== ============================ ========================== Returns ------- n : float Norm of the matrix or vector Notes ----- For values ord < 0, the result is, strictly speaking, not a mathematical 'norm', but it may still be useful for numerical purposes. """ x = asarray_chkfinite(x) if ord is None: # check the default case first and handle it immediately return sqrt(add.reduce(real((conjugate(x)*x).ravel()))) nd = len(x.shape) Inf = numpy.Inf if nd == 1: if ord == Inf: return numpy.amax(abs(x)) elif ord == -Inf: return numpy.amin(abs(x)) elif ord == 1: return numpy.sum(abs(x),axis=0) # special case for speedup elif ord == 2: return sqrt(numpy.sum(real((conjugate(x)*x)),axis=0)) # special case for speedup else: return numpy.sum(abs(x)**ord,axis=0)**(1.0/ord) elif nd == 2: if ord == 2: return numpy.amax(decomp.svd(x,compute_uv=0)) elif ord == -2: return numpy.amin(decomp.svd(x,compute_uv=0)) elif ord == 1: return numpy.amax(numpy.sum(abs(x),axis=0)) elif ord == Inf: return numpy.amax(numpy.sum(abs(x),axis=1)) elif ord == -1: return numpy.amin(numpy.sum(abs(x),axis=0)) elif ord == -Inf: return numpy.amin(numpy.sum(abs(x),axis=1)) elif ord in ['fro','f']: return sqrt(add.reduce(real((conjugate(x)*x).ravel()))) else: raise ValueError, "Invalid norm order for matrices." else: raise ValueError, "Improper number of dimensions to norm."
def signm(a,disp=1): """Matrix sign function. Extension of the scalar sign(x) to matrices. Parameters ---------- A : array, shape(M,M) Matrix at which to evaluate the sign function disp : boolean Print warning if error in the result is estimated large instead of returning estimated error. (Default: True) Returns ------- sgnA : array, shape(M,M) Value of the sign function at A (if disp == False) errest : float 1-norm of the estimated error, ||err||_1 / ||A||_1 Examples -------- >>> from scipy.linalg import signm, eigvals >>> a = [[1,2,3], [1,2,1], [1,1,1]] >>> eigvals(a) array([ 4.12488542+0.j, -0.76155718+0.j, 0.63667176+0.j]) >>> eigvals(signm(a)) array([-1.+0.j, 1.+0.j, 1.+0.j]) """ def rounded_sign(x): rx = real(x) if rx.dtype.char=='f': c = 1e3*feps*amax(x) else: c = 1e3*eps*amax(x) return sign( (absolute(rx) > c) * rx ) result,errest = funm(a, rounded_sign, disp=0) errtol = {0:1e3*feps, 1:1e3*eps}[_array_precision[result.dtype.char]] if errest < errtol: return result # Handle signm of defective matrices: # See "E.D.Denman and J.Leyva-Ramos, Appl.Math.Comp., # 8:237-250,1981" for how to improve the following (currently a # rather naive) iteration process: a = asarray(a) #a = result # sometimes iteration converges faster but where?? # Shifting to avoid zero eigenvalues. How to ensure that shifting does # not change the spectrum too much? vals = svd(a,compute_uv=0) max_sv = np.amax(vals) #min_nonzero_sv = vals[(vals>max_sv*errtol).tolist().count(1)-1] #c = 0.5/min_nonzero_sv c = 0.5/max_sv S0 = a + c*np.identity(a.shape[0]) prev_errest = errest for i in range(100): iS0 = inv(S0) S0 = 0.5*(S0 + iS0) Pp=0.5*(dot(S0,S0)+S0) errest = norm(dot(Pp,Pp)-Pp,1) if errest < errtol or prev_errest==errest: break prev_errest = errest if disp: if not isfinite(errest) or errest >= errtol: print "Result may be inaccurate, approximate err =", errest return S0 else: return S0, errest