comparison mftoolbox/signm_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,k] = signm_newton(A,scal)
2 %SIGNM_NEWTON Matrix sign function by Newton iteration.
3 % [S,k] = SIGNM_NEWTON(A,SCAL) computes the matrix sign
4 % function S of A using the scaled Newton iteration, with
5 % scale factors specified by SCAL:
6 % SCAL = 0: no scaling.
7 % SCAL = 1: determinantal scaling (default).
8 % SCAL = 2: spectral scaling.
9 % SCAL = 3: norm scaling.
10 % k is the number of iterations.
11
12 if nargin < 2, scal = 1; end
13
14 tol = mft_tolerance(A);
15 accel_tol = 1e-2; % Precise value not important.
16 need_accel = 1;
17 n = length(A);
18 maxit = 16;
19
20 X = A;
21 reldiff = inf;
22
23 for k = 1:maxit
24
25 Xold = X;
26 Xinv = inv(X);
27 if need_accel && scal > 0
28 % In practice should estimate spectral radius and 2-norms;
29 % here they are computed exactly.
30 switch scal
31 case 1
32 g = abs(det(X))^(-1/n);
33 case 2
34 s1 = max(abs(eig(Xinv)));
35 s2 = max(abs(eig(X)));
36 g = sqrt(s1/s2);
37 case 3
38 g = sqrt( norm(Xinv) / (norm(X)) );
39 end
40 X = g*X; Xinv = Xinv/g;
41 end
42 X = 0.5*(X + Xinv);
43 diff_F = norm(X-Xold,'fro');
44 reldiff_old = reldiff;
45 reldiff = diff_F/norm(X,'fro');
46
47 if need_accel && (reldiff < accel_tol), need_accel = false; end
48 cged = (diff_F <= sqrt( tol*norm(X)/norm(Xinv) ) || ...
49 reldiff > reldiff_old/2 && ~need_accel);
50 if cged, return, end
51
52 end
53 error('Not converged after %2.0f iterations', maxit)