Last active
August 29, 2015 14:07
-
-
Save wanirepo/3a65657e1cc77a3cf25e to your computer and use it in GitHub Desktop.
This function conduct the greedy agglomerative algorithm to find community structure that maximizes the network's modularity (Q)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function [max_z, max_q, outinfo] = community_modularity(A, varargin) | |
% function [z, q, outinfo] = community_modularity(A, optional_inputs) | |
% | |
% feature: This function conduct the greedy agglomerative algorithm to find | |
% community structure that maximizes the network's modularity (Q). | |
% | |
% input: A adjacency matrix | |
% | |
% output: max_z a vector of community membership that maximize Q | |
% max_q the maximum modularity value | |
% outinfo saves max_z,max_q, and z and q for each merging step | |
% | |
% options: 'vis', 'visualize' visualizes the network using the webweb | |
% tool (http://danlarremore.com/webweb/) | |
% | |
% example: | |
% A = [0 1 1 0 0 0; 1 0 1 0 0 0; 1 1 0 1 0 0; 0 0 1 0 1 1; ... | |
% 0 0 0 1 0 1; 0 0 0 1 1 0]; | |
% [z, q, outinfo] = greedy_agglo(A) % returns max z and q, and info | |
% [z, q, outinfo] = greedy_agglo(A, 'vis') | |
% | |
% All calculations are based on the lecture note of Aaron Clauset's Network | |
% analysis and modeling class (Fall 2014). | |
% see http://tuvalu.santafe.edu/~aaronc/courses/5352/ | |
dovis = false; | |
dogiven = false; | |
% Parse the optional inputs | |
for i = 1:length(varargin) | |
if ischar(varargin{i}) | |
switch varargin{i} | |
case {'vis', 'visualize'} % visualize the network (using Webweb) | |
dovis = true; | |
originalA = A; % keep the original A for its visualization | |
case {'given_solution', 'given'} % visualize the known category | |
dogiven = true; | |
z_given = varargin{i+1}; | |
end | |
end | |
end | |
m = sum(sum(A))./2; | |
%% 1. initialize z, q values | |
z = 1:size(A,1); % Each vertex is in its own group. | |
q = modularity_wani(A, z); % Calculate the initial Q value | |
%% delta_q function handle | |
delta_q = @(A,m) A./m - 2.*(sum(A)'*sum(A)) .* (A~=0) ./ ((2*m)^2); | |
% Eq.(8) of Lecture note 5. In this implementation, | |
% A./m is 2*e_ij in Eq.(8), and ki./(2*m) is a_i. | |
% Multiplying (A~=0) is added because this calculation | |
% should be conducted only on the existing pairs. | |
% This value has been validated using a test against | |
% diff(q). They were same. | |
%% 2. greedy agglomeration | |
i = 1; | |
while size(A,1) > 2 | |
dq = delta_q(A,m); | |
dq(eye(size(dq))~=0)=-Inf; | |
% get the indices for the pair that has the maximum delta q | |
[~, idx] = max(dq); | |
[~, idx2] = max(max(dq)); | |
q_delta(i) = max(max(dq)); | |
% merge the network: see the subfunction "merge" | |
[A, z(i,:)] = merge(A, z(i-1,:), sort([idx(idx2) idx2])); | |
q(i+1) = q(i) + q_delta(i); | |
% calculate the modularity of the merged network. | |
i = i + 1; | |
end | |
[max_q, maxidx] = max(q); | |
max_z = z(maxidx,:); | |
% save output values | |
outinfo.max_z = max_z; | |
outinfo.max_q = max_q; | |
outinfo.z = z; | |
outinfo.q = q; | |
outinfo.q_delta = q_delta; | |
%% 3. visualization using webweb (optional) | |
if dovis | |
webwebdir = '/Users/clinpsywoo/Documents/MATLAB/network_tools/webweb_v3.2'; | |
try | |
cd(webwebdir); | |
catch | |
disp('Please specify the directory that includes the Webweb tool in the code.'); | |
return | |
end | |
dis.w = 300; | |
dis.h = 300; | |
% Increase the charge and the gravity | |
dis.c = 40; | |
dis.g = 0.05; | |
dis.l = 13; | |
dis.r = 4; | |
% Give the file a name | |
dis.name = 'community_structure_modularity'; | |
% Name the nodes | |
for i=1:size(originalA,1) | |
dis.nodeNames{i} = num2str(i); | |
end | |
nets.net.adj = originalA; | |
nets.net.labels.greedy_agglo.type = 'categorical'; | |
nets.net.labels.greedy_agglo.values = max_z; | |
if dogiven | |
nets.net.labels.given.type = 'categorical'; | |
nets.net.labels.given.values = z_given; | |
end | |
webweb(dis,nets); | |
end | |
end | |
% ------------------------- SUBFUNCTION ------------------------- | |
function [mA, mz] = merge(A,z,ij) | |
% This subfunction is merging the vertex pairs that has the largest | |
% q_delta value. | |
i = ij(1); | |
j = ij(2); | |
mA = A; | |
mA(i,:) = mA(i,:) + mA(j,:); mA(j,:) = []; | |
mA(:,i) = mA(:,i) + mA(:,j); mA(:,j) = []; | |
z2 = unique(z); | |
ii = z2(i); | |
jj = z2(j); | |
mz = z; | |
mz(z == jj) = mz(ii); | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
added more documentation.