Mercurial > matrix-functions
diff mftoolbox/logm_frechet_pade.m @ 0:8f23314345f4 draft
Create local repository for matrix toolboxes. Step #0 done.
author | Antonio Pino Robles <data.script93@gmail.com> |
---|---|
date | Wed, 06 May 2015 14:56:53 +0200 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mftoolbox/logm_frechet_pade.m Wed May 06 14:56:53 2015 +0200 @@ -0,0 +1,47 @@ +function L = logm_frechet_pade(A,E) +%LOGM_FRECHET_PADE Frechet derivative of matrix logarithm via Pade approx. +% L = LOGM_FRECHET_PADE(A,E) evaluates the Frechet +% derivative of the matrix logarithm at A in the direction E via the +% inverse scaling and squaring and a Pade approximant of the function +% tanh(x)/x. A must have no eigenvalues on the negative real axis. + +real_data = isreal(A) && isreal(E); +% Form complex Schur form if A not already upper triangular. +use_Schur = false; +if ~isequal(A,triu(A)) + use_Schur = true; + [Q,T] = schur(A,'complex'); A = T; E = Q'*E*Q; +end + +I = eye(size(A)); +B = A; +for i = 0:inf + if norm(B-I,1) <= 1-1/exp(1), s = i; break, end + B = sqrtm(B); + Aroot{i+1} = B; +end + +% Positive zeros of p8 and q8 in r8 = p8/q8 Pade approximant. +load tau_r8_zeros +% Zeros come in \pm pairs. +a = complex(0, [pzero; -pzero]); +b = complex(0, [qzero; -qzero]); + +E = 2^s*E; +for i = 1:s + E = sylvsol(Aroot{i},Aroot{i},E); +end + +G = sylvsol(B,B,E); + +X = logm(B); + +for i=8:-1:1 + rhs = (I + X/b(i)) * G + G * (I - X/b(i)); + AA = I + X/a(i); BB = I - X/a(i); + G = sylvsol(AA, BB, rhs); +end + +L = 2*G; +if use_Schur, L = Q*L*Q'; end +if real_data, L = real(L); end