def rq(a,overwrite_a=0,lwork=None): """RQ decomposition of an M x N matrix a. Description: Find an upper-triangular matrix r and a unitary (orthogonal) matrix q such that r * q = a Inputs: a -- the matrix overwrite_a=0 -- if non-zero then discard the contents of a, i.e. a is used as a work array if possible. lwork=None -- >= shape(a)[1]. If None (or -1) compute optimal work array size. Outputs: r, q -- matrices such that r * q = a """ # TODO: implement support for non-square and complex arrays a1 = asarray_chkfinite(a) if len(a1.shape) != 2: raise ValueError, 'expected matrix' M,N = a1.shape if M != N: raise ValueError, 'expected square matrix' if issubclass(a1.dtype.type,complexfloating): raise ValueError, 'expected real (non-complex) matrix' overwrite_a = overwrite_a or (_datanotshared(a1,a)) gerqf, = get_lapack_funcs(('gerqf',),(a1,)) if lwork is None or lwork == -1: # get optimal work array rq,tau,work,info = gerqf(a1,lwork=-1,overwrite_a=1) lwork = work[0] rq,tau,work,info = gerqf(a1,lwork=lwork,overwrite_a=overwrite_a) if info<0: raise ValueError, \ 'illegal value in %-th argument of internal geqrf'%(-info) gemm, = get_blas_funcs(('gemm',),(rq,)) t = rq.dtype.char R = basic.triu(rq) Q = numpy.identity(M,dtype=t) ident = numpy.identity(M,dtype=t) zeros = numpy.zeros k = min(M,N) for i in range(k): v = zeros((M,),t) v[N-k+i] = 1 v[0:N-k+i] = rq[M-k+i,0:N-k+i] H = gemm(-tau[i],v,v,1+0j,ident,trans_b=2) Q = gemm(1,Q,H) return R, Q
def funm(A,func,disp=1): """matrix function for arbitrary callable object func. """ # func should take a vector of arguments (see vectorize if # it needs wrapping. # Perform Shur decomposition (lapack ?gees) A = asarray(A) if len(A.shape)!=2: raise ValueError, "Non-matrix input to matrix function." if A.dtype.char in ['F', 'D', 'G']: cmplx_type = 1 else: cmplx_type = 0 T, Z = schur(A) T, Z = rsf2csf(T,Z) n,n = T.shape F = diag(func(diag(T))) # apply function to diagonal elements F = F.astype(T.dtype.char) # e.g. when F is real but T is complex minden = abs(T[0,0]) # implement Algorithm 11.1.1 from Golub and Van Loan # "matrix Computations." for p in range(1,n): for i in range(1,n-p+1): j = i + p s = T[i-1,j-1] * (F[j-1,j-1] - F[i-1,i-1]) ksl = slice(i,j-1) val = dot(T[i-1,ksl],F[ksl,j-1]) - dot(F[i-1,ksl],T[ksl,j-1]) s = s + val den = T[j-1,j-1] - T[i-1,i-1] if den != 0.0: s = s / den F[i-1,j-1] = s minden = min(minden,abs(den)) F = dot(dot(Z, F),transpose(conjugate(Z))) if not cmplx_type: F = toreal(F) tol = {0:feps, 1:eps}[_array_precision[F.dtype.char]] if minden == 0.0: minden = tol err = min(1, max(tol,(tol/minden)*norm(triu(T,1),1))) if product(ravel(logical_not(isfinite(F))),axis=0): err = Inf if disp: if err > 1000*tol: print "Result may be inaccurate, approximate err =", err return F else: return F, err
def qr_old(a,overwrite_a=0,lwork=None): """QR decomposition of an M x N matrix a. Description: Find a unitary (orthogonal) matrix, q, and an upper-triangular matrix r such that q * r = a Inputs: a -- the matrix overwrite_a=0 -- if non-zero then discard the contents of a, i.e. a is used as a work array if possible. lwork=None -- >= shape(a)[1]. If None (or -1) compute optimal work array size. Outputs: q, r -- matrices such that q * r = a """ 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)) geqrf, = get_lapack_funcs(('geqrf',),(a1,)) if lwork is None or lwork == -1: # get optimal work array qr,tau,work,info = geqrf(a1,lwork=-1,overwrite_a=1) lwork = work[0] qr,tau,work,info = geqrf(a1,lwork=lwork,overwrite_a=overwrite_a) if info<0: raise ValueError,\ 'illegal value in %-th argument of internal geqrf'%(-info) gemm, = get_blas_funcs(('gemm',),(qr,)) t = qr.dtype.char R = basic.triu(qr) Q = numpy.identity(M,dtype=t) ident = numpy.identity(M,dtype=t) zeros = numpy.zeros for i in range(min(M,N)): v = zeros((M,),t) v[i] = 1 v[i+1:M] = qr[i+1:M,i] H = gemm(-tau[i],v,v,1+0j,ident,trans_b=2) Q = gemm(1,Q,H) return Q, R
def qr(a,overwrite_a=0,lwork=None,econ=False,mode='qr'): """QR decomposition of an M x N matrix a. Description: Find a unitary (orthogonal) matrix, q, and an upper-triangular matrix r such that q * r = a Inputs: a -- the matrix overwrite_a=0 -- if non-zero then discard the contents of a, i.e. a is used as a work array if possible. lwork=None -- >= shape(a)[1]. If None (or -1) compute optimal work array size. econ=False -- computes the skinny or economy-size QR decomposition only useful when M>N mode='qr' -- if 'qr' then return both q and r; if 'r' then just return r Outputs: q,r - if mode=='qr' r - if mode=='r' """ a1 = asarray_chkfinite(a) if len(a1.shape) != 2: raise ValueError("expected 2D array") M, N = a1.shape overwrite_a = overwrite_a or (_datanotshared(a1,a)) geqrf, = get_lapack_funcs(('geqrf',),(a1,)) if lwork is None or lwork == -1: # get optimal work array qr,tau,work,info = geqrf(a1,lwork=-1,overwrite_a=1) lwork = work[0] qr,tau,work,info = geqrf(a1,lwork=lwork,overwrite_a=overwrite_a) if info<0: raise ValueError("illegal value in %-th argument of internal geqrf" % -info) if not econ or M<N: R = basic.triu(qr) else: R = basic.triu(qr[0:N,0:N]) if mode=='r': return R if find_best_lapack_type((a1,))[0]=='s' or find_best_lapack_type((a1,))[0]=='d': gor_un_gqr, = get_lapack_funcs(('orgqr',),(qr,)) else: gor_un_gqr, = get_lapack_funcs(('ungqr',),(qr,)) if M<N: # get optimal work array Q,work,info = gor_un_gqr(qr[:,0:M],tau,lwork=-1,overwrite_a=1) lwork = work[0] Q,work,info = gor_un_gqr(qr[:,0:M],tau,lwork=lwork,overwrite_a=1) elif econ: # get optimal work array Q,work,info = gor_un_gqr(qr,tau,lwork=-1,overwrite_a=1) lwork = work[0] Q,work,info = gor_un_gqr(qr,tau,lwork=lwork,overwrite_a=1) else: t = qr.dtype.char qqr = numpy.empty((M,M),dtype=t) qqr[:,0:N]=qr # get optimal work array Q,work,info = gor_un_gqr(qqr,tau,lwork=-1,overwrite_a=1) lwork = work[0] Q,work,info = gor_un_gqr(qqr,tau,lwork=lwork,overwrite_a=1) if info < 0: raise ValueError("illegal value in %-th argument of internal gorgqr" % -info) return Q, R
def funm(A,func,disp=1): """Evaluate a matrix function specified by a callable. Returns the value of matrix-valued function f at A. The function f is an extension of the scalar-valued function func to matrices. Parameters ---------- A : array, shape(M,M) Matrix at which to evaluate the function func : callable Callable object that evaluates a scalar function f. Must be vectorized (eg. using vectorize). disp : boolean Print warning if error in the result is estimated large instead of returning estimated error. (Default: True) Returns ------- fA : array, shape(M,M) Value of the matrix function specified by func evaluated at A (if disp == False) errest : float 1-norm of the estimated error, ||err||_1 / ||A||_1 """ # Perform Shur decomposition (lapack ?gees) A = asarray(A) if len(A.shape)!=2: raise ValueError, "Non-matrix input to matrix function." if A.dtype.char in ['F', 'D', 'G']: cmplx_type = 1 else: cmplx_type = 0 T, Z = schur(A) T, Z = rsf2csf(T,Z) n,n = T.shape F = diag(func(diag(T))) # apply function to diagonal elements F = F.astype(T.dtype.char) # e.g. when F is real but T is complex minden = abs(T[0,0]) # implement Algorithm 11.1.1 from Golub and Van Loan # "matrix Computations." for p in range(1,n): for i in range(1,n-p+1): j = i + p s = T[i-1,j-1] * (F[j-1,j-1] - F[i-1,i-1]) ksl = slice(i,j-1) val = dot(T[i-1,ksl],F[ksl,j-1]) - dot(F[i-1,ksl],T[ksl,j-1]) s = s + val den = T[j-1,j-1] - T[i-1,i-1] if den != 0.0: s = s / den F[i-1,j-1] = s minden = min(minden,abs(den)) F = dot(dot(Z, F),transpose(conjugate(Z))) if not cmplx_type: F = toreal(F) tol = {0:feps, 1:eps}[_array_precision[F.dtype.char]] if minden == 0.0: minden = tol err = min(1, max(tol,(tol/minden)*norm(triu(T,1),1))) if product(ravel(logical_not(isfinite(F))),axis=0): err = Inf if disp: if err > 1000*tol: print "Result may be inaccurate, approximate err =", err return F else: return F, err