Skip to content

Commit 07ff476

Browse files
authored
Committed GLL package v2.1
changes in v2.1 - demo_artificial_data_on_grid.m and additional functions to run this script are added
1 parent aa8fdca commit 07ff476

10 files changed

+434
-4
lines changed

README.txt

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Graph Laplacian Learning (GLL) Package v2.0.
1+
Graph Laplacian Learning (GLL) Package v2.1
22

33
This MATLAB package includes implementations of graph learning algorithms presented in [1]-[2].
44

@@ -17,10 +17,19 @@ This MATLAB package includes implementations of graph learning algorithms presen
1717

1818
To install the package:
1919
(1) Download the source files.
20-
(2) Run script 'start_graph_learning.m'
20+
(2) Run the script 'start_graph_learning.m'
2121

2222
The demo script 'demo_animals.m' shows the usage of functions used to estimate three different graph Laplacian matrices discussed in [1].
2323

2424
The demo script 'demo_us_temperature.m' shows the usage of functions used to estimate combinatorial Laplacian matrices from smooth signals discussed in [2]. The code regenerates Fig.7(e) in [2].
2525

26+
The demo script 'demo_artificial_data_on_grid.m' implements the following steps:
27+
- generates a grid graph with random edges and a $\beta$-hop filter
28+
- generates an artificial dataset based on the graph system, which is specified by the generated graph and filter
29+
- runs the iterative algorithm described in [2].
30+
- shows ground truth and estimated graphs as well as returns the estimated $\beta$
31+
32+
33+
34+
2635

demo_artificial_data_on_grid.m

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
clear
2+
clc
3+
close all
4+
5+
%% Simulation parameters
6+
my_eps_outer = 10^(-4); my_eps_inner = 10^(-6);
7+
max_iterations = 20;
8+
9+
%% Generate model
10+
% generate random 8x8 grid graph
11+
BS = 8;
12+
load(['Grid_' num2str(BS) 'x' num2str(BS) '.mat']);
13+
A_connectivity = grid_Con4; A_mask = A_connectivity;
14+
[Ltrue,~,~] = generateRandomGraphFromConnectivity(A_connectivity,3,0,'uniform');
15+
num_vertices = size(A_connectivity,2);
16+
17+
% generate filter
18+
filter_type = 'hop'; beta = 3; % beta-hop filter with true beta parameter is set here
19+
graph_filter_ideal = @(x)(graph_filter_fwd(x,beta,filter_type) );
20+
21+
% generate graph system
22+
[h_L,h_L_sqrMatrix] = generateFilteredModel(Ltrue,graph_filter_ideal);
23+
24+
25+
%% Generate data samples based on h_L
26+
S_data_cell = generateRandomDataFromSqrtM(h_L_sqrMatrix,30); % creates data with 30 samples per vertex
27+
S_data = S_data_cell{1}; S_data = 0.5*(S_data + S_data');
28+
29+
30+
%% Algorithm implementation
31+
beta_current = 1; % initialize beta
32+
% Eigendecompose data
33+
[U,sigma_sq_C] = createBasis(S_data,'descend');
34+
sigma_sq_C(sigma_sq_C <= 10^-10) = 0;
35+
for repeat=1:max_iterations
36+
disp(['-- Iteration ' num2str(repeat) '--']);
37+
% Step I: Prefiltering step
38+
lambdas_current = graph_filter_inv(sigma_sq_C,beta_current,filter_type);
39+
current_sigmas = 1./lambdas_current;
40+
current_sigmas(current_sigmas==Inf)=0;
41+
% construct unfiltered S
42+
S_prefiltered = U * diag(abs(current_sigmas)) * U';
43+
S_prefiltered = 0.5*(S_prefiltered + S_prefiltered'); % symmetrize (in case of numerical inaccuracies)
44+
max_eig_of_S_data = max(current_sigmas);
45+
S_prefiltered = S_prefiltered/max_eig_of_S_data; % normalize
46+
47+
% Step II: Graph learning step
48+
Laplacian = estimate_cgl(S_prefiltered,ones(num_vertices),eps,my_eps_outer,my_eps_inner,max_iterations);
49+
Laplacian = Laplacian/max_eig_of_S_data; % normalize
50+
51+
% Step III: Parameter estimation step
52+
estimated_lambdas = diag(U' * Laplacian * U); estimated_lambdas(estimated_lambdas <= 10^-10) = 0;
53+
estimated_sigmas = graph_filter_fwd(estimated_lambdas,repeat,filter_type);
54+
h_L_current = U * diag(estimated_sigmas) * U'; h_L_current = 0.5*(h_L_current + h_L_current');
55+
error_est(repeat) = norm(S_data-h_L_current,'fro')/norm(S_data,'fro');
56+
% convergence criterion
57+
if repeat > 1 && abs(error_est(repeat-1) - error_est(repeat)) > 0.2
58+
disp('*** Algorithm has converged ***');
59+
break;
60+
end
61+
beta_current = beta_current + 1;
62+
end
63+
64+
65+
disp(['Estimated beta = ' num2str(beta_current) ]);
66+
disp(' Figure 1 shows the ground truth graph');
67+
disp(' Figure 2 shows the estimated graph');
68+
69+
f1=figure(1);
70+
draw_grid_graph(laplacianToAdjacency(Ltrue,eps),BS);
71+
axis square
72+
movegui(f1,'west');
73+
74+
f2=figure(2);
75+
draw_grid_graph(laplacianToAdjacency(Laplacian,eps),BS);
76+
axis square
77+
movegui(f2,'east');
78+
79+
80+
81+
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
% Function for generating random data given square root matrix assoc. with graph
2+
%
3+
% (C) Hilmi Egilmez
4+
5+
function [S_cell,D_cell] = generateRandomDataFromSqrtM(SquareRootMatrix,k_over_n_list)
6+
num_covars = length(k_over_n_list);
7+
S_cell = cell(1,num_covars); % cell of covariance matrices
8+
D_cell = cell(1,num_covars); % cell of sample distance matrices
9+
num_vertices = size(SquareRootMatrix,2);
10+
degree_of_freedom = num_vertices; %num_vertices*(num_vertices-1)/2;
11+
% degree_of_freedom = num_vertices*(num_vertices-1)/2;
12+
nSamplesList = int32(round(degree_of_freedom*k_over_n_list)); % number of data samples
13+
14+
y_samples = SquareRootMatrix*randn(num_vertices,max(nSamplesList));
15+
16+
for i=1:length(k_over_n_list)
17+
y_selected = y_samples(:,1:nSamplesList(i));
18+
S_temp = cov(y_selected',1);
19+
S_cell{i} = S_temp;
20+
end
21+
22+
end
23+
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
% Function for generating random data given
2+
%
3+
% (C) Hilmi Egilmez May 2016
4+
5+
function [Ltrue,S_true,S_sqrt_matrix] = generateRandomGraphFromConnectivity(A_connectivity,edge_weight_par,vertex_weight_par,type_weighting)
6+
7+
if nargin < 4
8+
type_weighting = 'uniform';
9+
if nargin < 3
10+
vertex_weight_par = edge_weight_par;
11+
end
12+
end
13+
14+
num_vertices = size(A_connectivity,2);
15+
16+
random_Seed = 'shuffle';
17+
num_edges = sum(A_connectivity(:))/2;
18+
rng(random_Seed); % seed random number generator
19+
% apply random weights depending on weight_var
20+
if isequal(type_weighting,'gaussian')
21+
% Gaussian random
22+
weights = abs(randn(1,num_edges)*sqrt(edge_weight_par))+0.1; %0.01 + exprnd(weight_var,1,num_edges); % abs(randn(1,num_edges)*sqrt(weight_var));
23+
vertex_weights = abs(randn(1,num_vertices)*sqrt(vertex_weight_par))+0.1; % 0.01 + exprnd(weight_var,1,num_vertices); %abs(randn(1,num_vertices)*sqrt(weight_var));
24+
elseif isequal(type_weighting,'uniform')
25+
% Uniform
26+
weights = (rand(1,num_edges)*(edge_weight_par-0.1))+0.1; %0.01 + exprnd(weight_var,1,num_edges); % abs(randn(1,num_edges)*sqrt(weight_var));
27+
vertex_weights = (rand(1,num_vertices)*(vertex_weight_par-0.1))+0.1; % 0.01 + exprnd(weight_var,1,num_vertices); %abs(randn(1,num_vertices)*sqrt(weight_var));
28+
else
29+
error('Wrong input: type_weighting')
30+
end
31+
% create Laplacian
32+
B = convertAdjToIncidence(A_connectivity);
33+
if vertex_weight_par == 0
34+
Ltrue = B * diag(weights) * B';
35+
else
36+
Ltrue = B * diag(weights) * B' + diag(vertex_weights);
37+
end
38+
% Create DataSamples
39+
[U,E] = eig(Ltrue);
40+
41+
% scale graph values when it has too large/small e.vals
42+
d_e = diag(E);
43+
44+
%%% added to avoid determinant < 1 case for vassilis algorithm
45+
d_e(d_e < 10^-10)=1;
46+
det_L = prod(d_e);
47+
if det_L < 1
48+
E = E*(det_L^(-1/num_vertices)+eps);
49+
d_e = d_e*(det_L^(-1/num_vertices)+eps);
50+
end
51+
52+
emin = min(d_e); emax = max(d_e);
53+
scaling = 1;
54+
if det_L == Inf || det_L==0
55+
scales = linspace(emin,emax,10);
56+
for i=1:length(scales)
57+
s = scales(i);
58+
det_L = prod(d_e./s);
59+
if det_L ~= Inf && det_L~=0
60+
scaling = s;
61+
break;
62+
end
63+
end
64+
end
65+
66+
if det_L == Inf || det_L == 0
67+
error(['Function generateRandomGraphFromConnectivity : Determinant of Laplacian is equal to ' ...
68+
num2str(det_L) ' -- try different parameters to generate random graph weights' ]);
69+
end
70+
71+
Ltrue = Ltrue/scaling;
72+
E = E/scaling;
73+
E(E<=10^(-10)) = 0;
74+
idx = E>10^(-10);
75+
E(idx) = abs(1./E(idx));
76+
S_true = U* E *U';
77+
%%% outputs
78+
S_sqrt_matrix = U*(E.^(0.5));
79+
S_true = 0.5*S_true + 0.5*S_true'; % symmetrize
80+
Ltrue = 0.5*Ltrue + 0.5*Ltrue';% symmetrize
81+
82+
end

misc/Grid_8x8.mat

750 Bytes
Binary file not shown.

misc/convertAdjToIncidence.m

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
2+
% Input:
3+
% Adj: 0/1 adjacency matrix (no self loops) given the *undirected* graph connection pattern
4+
% Output:
5+
% Incidence : Incidence matrix
6+
% fromNodes : list of *from* nodes
7+
% toNodes : list of *to* nodes
8+
function [Incidence,fromNodes,toNodes] = convertAdjToIncidence(Adj)
9+
10+
% take lower triangular part
11+
upper = ~logical(tril(Adj));
12+
Adj(upper) = 0;
13+
14+
% Find edges to design
15+
[fromNodes,toNodes] = find(Adj==1);
16+
nNodes = size(Adj,1);
17+
nLinks = length(fromNodes);
18+
19+
% create Incidence Matrix
20+
Incidence = zeros(nNodes,nLinks);
21+
for l=1:nLinks
22+
i=fromNodes(l); j=toNodes(l);
23+
Incidence(i,l) = 1; Incidence(j,l) = -1;
24+
end
25+
26+
end

misc/draw_grid_graph.m

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
%% Draw a grid graph with link weights having different colors
2+
% Inputs: A: Adjacency matrix
3+
% BS: block size
4+
function draw_grid_graph(A,BS)
5+
load ColorMatrix;
6+
for i=1:BS
7+
for j=1:BS
8+
pixel = i+(j-1)*BS;
9+
graph_points(pixel,2)= -i; % height
10+
graph_points(pixel,1)= j; % width
11+
end
12+
end
13+
14+
colors = colormap(Fire/255);
15+
wgPlot_grid(A,graph_points,'edgeColorMap',colors,'edgeWidth',2,'vertexColorMap',255*[1 1 1]);
16+
set(gcf,'color','w');
17+
% wgPlot(A,graph_points,'edgeColorMap',jet);
18+
% set(gcf,'color','w');

misc/laplacianToAdjacency.m

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
function A = laplacianToAdjacency(L,epsilon)
2+
3+
sizeMat = size(L);
4+
offDiag = ones(sizeMat) - eye(sizeMat); offDiag = offDiag == 1;
5+
A = zeros(sizeMat); A(offDiag) = -L(offDiag);
6+
A(A<epsilon) = 0;
7+
8+
end

0 commit comments

Comments
 (0)