[SciPy-user] Matrix sign function
Pearu Peterson
pearu at scipy.org
Thu Sep 25 06:00:33 EDT 2003
On Wed, 24 Sep 2003, Nils Wagner wrote:
> I have used linalg.signm with a defective matrix.
The current algorithm in linalg.funm is not suitable for
defective matrices. Btw, both Matlab and Octave funm functions
have the same problem. See for instance the corresponding thread in
Octave mailing list:
http://www.octave.org/octave-lists/archive/bug-octave.2001/msg00063.html
> The results do not fulfill the properties of a certain projector.
> Please find enclosed my test program.
> Any comments or suggestions for a further improvement of signm ?
Higham in his Matlab Matrix Computation Toolbox uses similar algorithm to
linalg.funm (with certain steps changed for stability) so that I doubt
that it would resolve the problem for defective matrices (correct me if I
am wrong).
But using iterative method (from the references you gave), please test the
following signm function with your matrices:
#---------------
feps = linalg.matfuncs.feps
eps = linalg.matfuncs.eps
_array_precision = linalg.matfuncs._array_precision
norm = linalg.norm
def signm3(a):
"""matrix sign"""
def rounded_sign(x):
rx = real(x)
mx = amax(absolute(x)) # XXX: amax segfaults on complex input
if rx.typecode()=='f':
c = 1e3*feps*mx
else:
c = 1e3*eps*mx
return sign( (absolute(rx) > c) * rx )
result,err = funm(a, rounded_sign, disp=0)
tol = {0:feps, 1:eps}[_array_precision[result.typecode()]]
if err < 1000*tol:
return result
S0 = result + 0.5*identity(result.shape[0])/norm(result,1)
for i in range(20):
iS0 = linalg.inv(S0)
alpha = beta = 0.5
S0 = alpha*S0 + beta*iS0
Pp=0.5*(dot(S0,S0)+S0)
eps1 = norm(dot(Pp,Pp)-Pp)
if eps1 < 1e3*tol:
break
return S0
#--------------
Pearu
More information about the SciPy-User
mailing list