1
- function spy(H )
1
+ function spy(H , variant )
2
2
% SPY Inspect the rank structure of H.
3
3
%
4
4
% SPY(H) draw a plot displaying the low-rank structure in the off-diagonal
5
5
% blocks of H.
6
+ %
7
+ % SPY(H, 'svd') also plots bars representing the singular values of the
8
+ % low-rank blocks, to indicate the decay present in those blocks.
9
+
10
+ if ~exist(' variant' , ' var' )
11
+ variant = ' standard' ;
12
+ end
6
13
7
14
m = size(H , 1 );
8
15
n = size(H , 2 );
@@ -16,15 +23,16 @@ function spy(H)
16
23
axis([ 0 n 0 m ]);
17
24
hold on ;
18
25
19
- spy_draw_block(H , 0 , 0 , hodlrrank(H ));
26
+ spy_draw_block(H , 0 , 0 , hodlrrank(H ), variant );
20
27
21
28
hold off ;
22
29
23
30
end
24
31
25
- function spy_draw_block(H , xoffset , yoffset , rk )
32
+ function spy_draw_block(H , xoffset , yoffset , rk , variant )
26
33
diag_color = [ 0.1 , 0.3 , 0.95 ];
27
34
offdiag_color = [ 0.95 , 0.95 , 1.0 ];
35
+ svd_color = [1.0 , 0.3 , 0.4 ];
28
36
29
37
if is_leafnode(H )
30
38
mm = size(H , 1 );
@@ -35,10 +43,10 @@ function spy_draw_block(H, xoffset, yoffset, rk)
35
43
36
44
fill(xb , yb , diag_color );
37
45
else
38
- spy_draw_block(H .A11 , xoffset , yoffset , rk );
46
+ spy_draw_block(H .A11 , xoffset , yoffset , rk , variant );
39
47
mm = size(H .A11 , 1 );
40
48
nn = size(H .A11 , 2 );
41
- spy_draw_block(H .A22 , xoffset + nn , yoffset + mm , rk );
49
+ spy_draw_block(H .A22 , xoffset + nn , yoffset + mm , rk , variant );
42
50
43
51
mm2 = size(H .A22 , 1 );
44
52
nn2 = size(H .A22 , 2 );
@@ -48,21 +56,54 @@ function spy_draw_block(H, xoffset, yoffset, rk)
48
56
xoffset + nn + nn2 , xoffset + nn ];
49
57
yb = [yoffset , yoffset , yoffset + mm , yoffset + mm ];
50
58
thisrk = size(H .U12 , 2 );
51
-
59
+
52
60
fill(xb , yb , offdiag_color );
61
+
62
+ if strcmp(variant , ' svd' )
63
+ % Draw the SVD plot of the block in the background
64
+ [~ , R ] = qr(H .U12 , 0 ); [~ , S ] = qr(H .V12 , 0 );
65
+ s = log(svd(R * S ' ));
66
+ nsvd = length(s );
67
+ for j = 1 : nsvd
68
+ sjm = (s(1 ) - s(j )) / (s(1 ) - s(end )) * mm ;
69
+ xbj = [xoffset + nn + nn2 * (j - 1 )/nsvd , xoffset + nn + nn2 * j / nsvd , ...
70
+ xoffset + nn + nn2 * j / nsvd , xoffset + nn + nn2 * (j - 1 )/nsvd ];
71
+ ybj = [yoffset + sjm , yoffset + sjm , yoffset + mm , yoffset + mm ];
72
+ fill(xbj , ybj , svd_color , ' LineStyle' ,' none' );
73
+ end
74
+ end
75
+
53
76
text(xoffset + nn + nn2 / 2 , yoffset + mm / 2 , ...
54
77
sprintf(' %d ' , thisrk ), ...
55
78
' HorizontalAlignment' , ' center' );
56
-
79
+
57
80
% Low rank block (2, 1)
58
81
xb = [xoffset , xoffset + nn , xoffset + nn , xoffset ];
59
82
yb = [yoffset + mm , yoffset + mm , ...
60
83
yoffset + mm + mm2 , yoffset + mm + mm2 ];
61
84
thisrk = size(H .U21 , 2 );
62
85
63
86
fill(xb , yb , offdiag_color );
87
+
88
+ if strcmp(variant , ' svd' )
89
+ % Draw the SVD plot of the block in the background
90
+ [~ , R ] = qr(H .U21 , 0 ); [~ , S ] = qr(H .V21 , 0 );
91
+ s = log(svd(R * S ' ));
92
+ nsvd = length(s );
93
+ for j = 1 : nsvd
94
+ sjm = (s(1 ) - s(j )) / (s(1 ) - s(end )) * mm2 ;
95
+ xbj = [xoffset + nn * (j - 1 )/nsvd , xoffset + nn * j / nsvd , ...
96
+ xoffset + nn * j / nsvd , xoffset + nn * (j - 1 )/nsvd ];
97
+ ybj = [yoffset + mm + sjm , yoffset + mm + sjm , yoffset + mm + mm2 , yoffset + mm + mm2 ];
98
+ fill(xbj , ybj , svd_color , ' LineStyle' ,' none' );
99
+ end
100
+ end
101
+
64
102
text(xoffset + nn / 2 , yoffset + mm + mm2 / 2 , ...
65
103
sprintf(' %d ' , thisrk ), ...
66
104
' HorizontalAlignment' , ' center' );
67
105
end
106
+ end
107
+
108
+ function spy_draw_svd_block()
68
109
end
0 commit comments