-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsinglegraph_bss_gen_problem.m
142 lines (113 loc) · 2.64 KB
/
singlegraph_bss_gen_problem.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
130
131
132
133
134
135
136
137
138
139
140
141
142
function [truth, model, y] = singlegraph_bss_gen_problem(params)
data_distribution = DataDistribution.Normal;
shift_operator = ShiftOperator.Adjacency;
if ~exist('params', 'var')
params = struct;
end
if ~isfield(params, 'verbose')
params.verbose = false;
end
if isfield(params, 'numFilters')
R = params.numFilters;
else
R = 2;
end
% Number of filter coefficients.
if isfield(params, 'L')
L = params.L;
else
L = 3;
end
% Number of nodes.
if isfield(params, 'N')
N = params.N;
else
N = 50;
end
% Number of non-zero input nodes.
if isfield(params, 'S')
S = params.S;
else
S = 1;
end
% Edge existence probability.
p = 0.1;
% Adjacency matrix.
model.G.W = generate_connected_ER(N, p);
% Graph Laplacian.
model.G.L = diag(sum(model.G.W))-model.G.W;
assert(issymmetric(model.G.W))
assert(issymmetric(model.G.L))
switch shift_operator
case ShiftOperator.Adjacency
model.G.S = model.G.W;
case ShiftOperator.Laplacian
model.G.S = model.G.L;
end
[model.G.V, Lambda, model.G.U] = eig(model.G.S);
model.G.lambda = diag(Lambda);
% Filter coefficients.
truth.h = zeros(L, R);
switch data_distribution
case DataDistribution.Normal
truth.h = randn(L, R);
truth.h = truth.h ./ repmat(norms(truth.h, 2, 1), L, 1);
case DataDistribution.Uniform
truth.h = rand(L, R);
truth.h = truth.h ./ repmat(norms(truth.h, 2, 1), L, 1);
end
model.Psi = repmat(model.G.lambda, 1, L).^repmat([0:L-1], N, 1);
% Build filter matrices.
truth.H = zeros(N, N * R);
for i = 1:R
Hi = truth.h(1, i)*eye(N);
for l = 1:L-1
Hi = Hi + truth.h(l+1, i)*model.G.S^l;
end
Hi*randn(N, 1)
truth.H(:, N*(i-1)+1:N*i) = Hi;
end
% Input signals.
truth.xSupport = zeros(R, S);
for i = 1:R
truth.xSupport(i, :) = randperm(N, S);
end
if params.verbose
found_overlap = false;
i = 1;
while i <= R && ~found_overlap
for j = i+1:R
if ~isempty(intersect(truth.xSupport(i, :), truth.xSupport(j, :)))
found_overlap = true;
break
end
end
i = i + 1;
end
if found_overlap
fprintf('The input signals overlap.\n')
else
fprintf('The input signals do not overlap.\n')
end
end
truth.x = zeros(N, R);
switch data_distribution
case DataDistribution.Normal
for i = 1:R
truth.x(truth.xSupport(i, :), i) = randn(S, 1);
truth.x(:, i) = truth.x(:, i) ./ norm(truth.x(:, i));
end
case DataDistribution.Uniform
for i = 1:R
truth.x(truth.xSupport(i, :), i) = rand(S, 1);
truth.x(:, i) = truth.x(:, i) ./ norm(truth.x(:, i));
end
end
y = truth.H*truth.x(:);
model.A = kr(model.Psi', model.G.U)';
truth.Zsum = zeros(N, L);
for i = 1:R
truth.Z{i} = truth.x(:, i)*truth.h(:, i)';
truth.Zsum = truth.Zsum + truth.Z{i};
end
end