def logm(A,disp=1): """Matrix logarithm, inverse of expm.""" # Compute using general funm but then use better error estimator and # make one step in improving estimate using a rotation matrix. A = mat(asarray(A)) F, errest = funm(A,log,disp=0) errtol = 1000*eps # Only iterate if estimate of error is too large. if errest >= errtol: # Use better approximation of error errest = norm(expm(F)-A,1) / norm(A,1) if not isfinite(errest) or errest >= errtol: N,N = A.shape X,Y = ogrid[1:N+1,1:N+1] R = mat(orth(eye(N,dtype='d')+X+Y)) F, dontcare = funm(R*A*R.H,log,disp=0) F = R.H*F*R if (norm(imag(F),1)<=1000*errtol*norm(F,1)): F = mat(real(F)) E = mat(expm(F)) temp = mat(solve(E.T,(E-A).T)) F = F - temp.T errest = norm(expm(F)-A,1) / norm(A,1) if disp: if not isfinite(errest) or errest >= errtol: print "Result may be inaccurate, approximate err =", errest return F else: return F, errest
def logm(A,disp=1): """Compute matrix logarithm. The matrix logarithm is the inverse of expm: expm(logm(A)) == A Parameters ---------- A : array, shape(M,M) Matrix whose logarithm to evaluate disp : boolean Print warning if error in the result is estimated large instead of returning estimated error. (Default: True) Returns ------- logA : array, shape(M,M) Matrix logarithm of A (if disp == False) errest : float 1-norm of the estimated error, ||err||_1 / ||A||_1 """ # Compute using general funm but then use better error estimator and # make one step in improving estimate using a rotation matrix. A = mat(asarray(A)) F, errest = funm(A,log,disp=0) errtol = 1000*eps # Only iterate if estimate of error is too large. if errest >= errtol: # Use better approximation of error errest = norm(expm(F)-A,1) / norm(A,1) if not isfinite(errest) or errest >= errtol: N,N = A.shape X,Y = ogrid[1:N+1,1:N+1] R = mat(orth(eye(N,dtype='d')+X+Y)) F, dontcare = funm(R*A*R.H,log,disp=0) F = R.H*F*R if (norm(imag(F),1)<=1000*errtol*norm(F,1)): F = mat(real(F)) E = mat(expm(F)) temp = mat(solve(E.T,(E-A).T)) F = F - temp.T errest = norm(expm(F)-A,1) / norm(A,1) if disp: if not isfinite(errest) or errest >= errtol: print "Result may be inaccurate, approximate err =", errest return F else: return F, errest