-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathbinary_deletion_dynamical_importance_vertices.m
130 lines (113 loc) · 3.76 KB
/
binary_deletion_dynamical_importance_vertices.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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
function [H, df,remove_order] = binary_deletion_dynamical_importance_vertices(G,b,options)
% Greedy removal of vertices, one vertix at a time.
% input:
% G - sparse undirected matrix
% b - beta
% options:
% options.alg_type - 'first_order' or 'second_order' approximations
% options.timelimit - the maximum number of seconds to run the method.
% When exceeded return NaN.
%
% output:
% H - the graph after the edges are removed
% df - the total sum of the removed edges
%
if ~exist('options','var')
options = struct();
end
if isfield(options,'time_limit')
time_limit = options.time_limit;
else
time_limit = inf;
end
if isfield(options,'alg_type')
alg_type = options.alg_type;
else
alg_type = 'first_order';
end
start_time = tic;
is_sym = issymmetric(G);
[d,i] = get_spectral_sorting(G,is_sym,alg_type);
df = 0;
remove_order = inf(size(G,1),2); % row,col,order
k=0;
fprintf('%s dynamical importance R(G)/beta: ',alg_type);
string_to_print = '';
while abs(d) > b
if time_limit < toc(start_time)
disp('======= time limit reached, stopping! =======');
G = nan;
df = nan;
remove_order = nan;
break;
else
if ~mod(k,10) % display progress towards beta
string_to_print = print_output(string_to_print, abs(d), b, k);
end
if is_sym
k = k+1;
df = df + sum(G(i,:));
df = df + sum(G(:,i));
G(i,:) = 0; % remove incoming edges
G(:,i) = 0; % remove outgoing edges
remove_order(k,1)= i;
remove_order(k,2)= k;
else
k = k+1;
df = df + sum(G(i,:));
df = df + sum(G(:,i));
G(i,:) = 0; % remove incoming edges
G(:,i) = 0; % remove outgoing edges
remove_order(k,1)= i;
remove_order(k,2)= k;
end
[d,i] = get_spectral_sorting(G,is_sym,alg_type); % recalculate the vertices order
end
end
H = G;
print_output(string_to_print, abs(d), b, k);
fprintf('\n');
end
function string_to_print = print_output(former_string, radius, beta, k)
fprintf(repmat('\b',1,length(former_string)));
string_to_print = sprintf('%g ,(%d vertices)', radius/beta,k );
fprintf('%s',string_to_print);
end
function [d,i,j] = get_spectral_sorting(G,is_sym,alg_type)
% We rank the vertices by computing the first or second order approximations
% of vertex removal
%
% ---- note ----
% The gradient should also be normalized by v*u in the
% case of non-symetric graphs but this has no effect on the ordering.
%
switch alg_type
case 'first_order'
if is_sym
[u,d] = eigs(G,1);
ranking = u.*u;
else
[u,d] = eigs(G,1);
[v,~] = eigs(G',1);
ranking = abs(v.*u);
end
case 'second_order'
% error('second_order not supported yet')
if is_sym
[u,d] = eigs(G,1);
edge_sum = sum(G.*G',2);
ranking = (-1 + edge_sum/ d^2) .*u.*u;
ranking = abs(ranking); % is this nessecery ?
else
[u,d] = eigs(G,1);
[v,~] = eigs(G',1);
edge_sum = sum(G.*G',2);
ranking = (-1 + edge_sum/ d^2) .*u.*v;
ranking = abs(ranking);% is this nessecery ?
end
otherwise
error('unkown parameter %s', alg_type);
end
[~, max_ind] = max(ranking);
i = max_ind;
end