-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfunc_sym_qr.m
63 lines (58 loc) · 1.12 KB
/
func_sym_qr.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
function [D] = func_sym_qr(A, tol)
% FUNC_SYM_QR QR methods to compute eigenvalues of symmetrix matrix A.
% --------------------
% Usage
% [D] = FUNC_SYM_JACOBI(A)
% --------------------
% Input
% A: (n,n) double
% symmetirx matrix
% tol: double
% tolerance
% --------------------
% Output
% D: (n,n) double
% eigenvalues
n = max(size(A));
A = func_householder_tridiag(A);
A = tril(A);
A = A + diag(diag(A, -1), 1);
D = A;
q = 0;
while q < n
for i = 1:n - 1
if abs(D(i+1, i)) <= tol * (abs(D(i, i))+abs(D(i+1, i+1)))
D(i+1, i) = 0;
end
[p, q] = select_index(D);
if q < n
D(p+1:n - q, p+1:n - q) = func_wilkinson_shift(D(p+1:n - q, p+1:n - q));
end
end
end
end
function [p,q] = select_index(D)
n = max(size(D));
q = 0;
n_p_q = 0;
flag = 0;
for i=n-1:-1:1
if flag == 0 && D(i+1,i) ~= 0
flag = 1;
n_p_q = 1;
end
if flag == 1 && D(i+1,i) == 0
break;
end
if flag == 0
q = q+1;
end
if flag==1
n_p_q = n_p_q+1;
end
end
if q == n-1 && n_p_q == 0
q = n;
end
p = n-n_p_q - q;
end