comparison mftoolbox/rootpm_schur_newton.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
comparison
equal deleted inserted replaced
-1:000000000000 0:8f23314345f4
1 function [X,Y] = rootpm_schur_newton(A,p)
2 %ROOTPM_SCHUR_NEWTON Matrix pth root by Schur-Newton method.
3 % [X,Y] = ROOTPM_SCHUR_NEWTON(A,p) computes the principal pth root
4 % X of the real matrix A using the Schur-Newton algorithm.
5 % It also returns Y = INV(X).
6
7 if norm(imag(A),1), error('A must be real.'), end
8 A = real(A); % Discard any zero imaginary part.
9 [Q,R] = schur(A,'real'); % Quasitriangular R.
10
11 e = eig(R);
12 if any (e(find(e == real(e))) < 0 )
13 error('A has a negative real eigenvalue: principal pth root not defined')
14 end
15
16 f = factor(p);
17 k0 = length(find(f == 2)); % Number of factors 2.
18 q = p/2^(k0);
19 k1 = k0;
20 if q > 1
21
22 emax = max(abs(e)); emin = min(abs(e));
23 if emax > emin % Avoid log(0).
24 k1 = max(k1, ceil( log2( log2(emax/emin) ) ));
25 end
26
27 max_arg = norm(angle(e),inf);
28 if max_arg > pi/8
29 k3 = 1;
30 if max_arg > pi/2
31 k3 = 3;
32 elseif max_arg > pi/4
33 k3 = 2;
34 end
35 k1 = max(k1,k3);
36 end
37
38 end
39
40 for i = 1:k1, R = sqrtm_real(R); end
41
42
43 if q ~= 1
44 pw = 2^(-k1); emax = emax^pw; emin = emin^pw;
45 if ~any(imag(e))
46 % Real eigenvalues.
47 if emax > emin
48 alpha = emax/emin;
49 c = ( (alpha^(1/q)*emax-emin)/( (alpha^(1/q)-1)*(q+1) ) )^(1/q);
50 else
51 c = emin^(1/q);
52 end
53 else
54 % Complex eigenvalues.
55 c = (( emax+emin)/2 )^(1/q);
56 end
57
58 X = rootpm_newton(R,q,c);
59 for i = 1:k1-k0
60 X = X*X;
61 end
62 else
63 X = R;
64 end
65 Y = Q*(X\Q'); % Return inverse pth root, too.
66 X = Q*X*Q';