smallHubNetwork

PURPOSE ^

SMALLHUBNETWORK create Watts & Strogatz small world network with hubs.

SYNOPSIS ^

function [ network ] = smallHubNetwork( nNode, rewireProb, seedNumber, nEdge, nHub, hubStyle )

DESCRIPTION ^

 SMALLHUBNETWORK create Watts & Strogatz small world network with hubs.

   [ network ] = smallHubNetwork( nNode, rewireProb, seedNumber, nEdge, nHub, hubStyle )
   This function not only create Watts & Strogatz small world network but also
   replace nHub nodes by hubs (provincial, connect or kinless determined by
   hubStyle). The degrees of hubs are determined from tail of exponetial
   distribution (its mean is nEdge - 1). Remaining degrees would be uniformly
   and randomly distributed to each non-hub nodes.
   The input argument hubStyle control the connection mechanism of hubs.
   3 different mechanisms would let most of hubs be classifed into the specific
   kinds of hubs. Below is the mechanism:
   Provincial: 100% connections link with neighbour nodes of ring lattice.
   Kinless: 100% connections link with random nodes.
   Connector: 80% connections link with neighbours and 20% connections link
       with random nodes.

   Input:
       nNode: number of node of this network
       rewireProb: rewiring rewireProb
       seedNumber: seed number of random
       nEdge: number of edge of each node
       nHub: number of hubs
       hubStyle: provincial, connector or kinless

    Output:
        network: a network structure

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function [ network ] = smallHubNetwork( nNode, rewireProb, seedNumber, nEdge, nHub, hubStyle )
0002 % SMALLHUBNETWORK create Watts & Strogatz small world network with hubs.
0003 %
0004 %   [ network ] = smallHubNetwork( nNode, rewireProb, seedNumber, nEdge, nHub, hubStyle )
0005 %   This function not only create Watts & Strogatz small world network but also
0006 %   replace nHub nodes by hubs (provincial, connect or kinless determined by
0007 %   hubStyle). The degrees of hubs are determined from tail of exponetial
0008 %   distribution (its mean is nEdge - 1). Remaining degrees would be uniformly
0009 %   and randomly distributed to each non-hub nodes.
0010 %   The input argument hubStyle control the connection mechanism of hubs.
0011 %   3 different mechanisms would let most of hubs be classifed into the specific
0012 %   kinds of hubs. Below is the mechanism:
0013 %   Provincial: 100% connections link with neighbour nodes of ring lattice.
0014 %   Kinless: 100% connections link with random nodes.
0015 %   Connector: 80% connections link with neighbours and 20% connections link
0016 %       with random nodes.
0017 %
0018 %   Input:
0019 %       nNode: number of node of this network
0020 %       rewireProb: rewiring rewireProb
0021 %       seedNumber: seed number of random
0022 %       nEdge: number of edge of each node
0023 %       nHub: number of hubs
0024 %       hubStyle: provincial, connector or kinless
0025 %
0026 %    Output:
0027 %        network: a network structure
0028 
0029 %   ---------
0030 %   Yen-Nan Lin, NTHU, 2010-2014, Matlab 2012a
0031 
0032 RATIO_RAND = 0.20;
0033 if nargin < 4
0034     error('No sufficient input arguments.')
0035 end
0036 
0037 network = struct('size', nNode, 'rewireProb', rewireProb, ...
0038     'seed', seedNumber, 'nEdge', nEdge);
0039 rand('seed', seedNumber);
0040 network.matrix = sparse(nNode, nNode);
0041 
0042 % classify hub types
0043 isProvincial = false;
0044 isConnector = false;
0045 isKinless = false;
0046 if strcmpi(hubStyle, 'provincial') == true
0047     isProvincial = true;
0048 elseif strcmpi(hubStyle, 'connector') == true
0049     isConnector = true;
0050 elseif strcmpi(hubStyle, 'kinless') == true
0051     isKinless = true;
0052 else
0053     error(['no ' hubStyle ' this kind of hubStyle.']);
0054 end
0055 
0056 % assign degree to each nodes
0057 nNonHub = nNode - nHub;
0058 outDegList = round(exprnd(nEdge - 1, 1, nNode)) + 1;
0059 [tmpSort, tmpSortIx] = sort(outDegList, 'descend');
0060 hubIxList = tmpSortIx(1:nHub);
0061 nonHubIxList = tmpSortIx((nHub + 1):end);
0062 remainSumDeg = nNode * nEdge - sum(outDegList(hubIxList));
0063 nEdgeNonHub = floor(remainSumDeg / nNonHub);
0064 outDegList(nonHubIxList) = nEdgeNonHub;
0065 if mod(remainSumDeg, nNonHub) > 0
0066     tmpRandIx = randperm(nNonHub);
0067     tmpRandIx = tmpRandIx(1:mod(remainSumDeg, nNonHub));
0068     tmpRandIx = tmpRandIx + nHub;
0069     outDegList(tmpSortIx(tmpRandIx)) = outDegList(tmpSortIx(tmpRandIx)) + 1;
0070 end
0071 
0072 % sort hub to last entry of outDegList
0073 if isKinless == true
0074     outDegList = horzcat(outDegList, outDegList(hubIxList));
0075     outDegList(hubIxList) = [];
0076     [tmpSort, tmpSortIx] = sort(outDegList, 'descend');
0077     hubIxList = (nNode - nHub + 1):nNode;
0078     nonHubIxList = 1:(nNode - nHub);
0079 end
0080 
0081 % build connection
0082 for iNode = 1:numel(tmpSortIx)
0083     nodeIx = tmpSortIx(iNode);
0084 
0085     isHub = false;
0086     if ~isempty(find(hubIxList == nodeIx, 1))
0087         isHub = true;
0088     end
0089 
0090     % if already exist some link to hub
0091     tmpExistOutLink = find(network.matrix(nodeIx, :) > 0);
0092     if ~isempty(tmpExistOutLink)
0093         tmpOutDeg = outDegList(nodeIx) - numel(tmpExistOutLink);
0094     else
0095         tmpOutDeg = outDegList(nodeIx);
0096     end
0097 
0098     % part of connector hub link to neighbor, the other link to random nodes
0099     if isConnector == true && isHub == true
0100         tmpRandOutDeg = round(tmpOutDeg * RATIO_RAND);
0101         tmpOutDeg = tmpOutDeg - tmpRandOutDeg;
0102     end
0103 
0104     % create array of relative neighbor index
0105     radius = floor(tmpOutDeg / 2);
0106     neighbor = [-radius:-1, 1:radius];
0107     if mod(tmpOutDeg, 2) == 1
0108         if rand() > 0.5
0109             neighbor = [neighbor, radius + 1];
0110         else
0111             neighbor = [-(radius + 1), neighbor];
0112         end
0113     end
0114 
0115     % kinless hub don't link to neighbor
0116     if isKinless == true && isHub == true
0117         neighbor = [];
0118     end
0119 
0120     % link to neighbor
0121     for jNeighbor = 1:numel(neighbor)
0122         connectIx = nodeIx + neighbor(jNeighbor);
0123 
0124         if isKinless == true
0125             connectIx = ringIndex(connectIx, nNode - nHub);
0126         else
0127             connectIx = ringIndex(connectIx, nNode);
0128         end
0129 
0130         while network.matrix(nodeIx, connectIx) == 1
0131             if neighbor(jNeighbor) > 0
0132                 neighbor(jNeighbor) = neighbor(jNeighbor) + 1;
0133             else
0134                 neighbor(jNeighbor) = neighbor(jNeighbor) - 1;
0135             end
0136 
0137             connectIx = nodeIx + neighbor(jNeighbor);
0138             if isKinless == true
0139                 connectIx = ringIndex(connectIx, nNode - nHub);
0140             else
0141                 connectIx = ringIndex(connectIx, nNode);
0142             end
0143         end
0144 
0145         network.matrix(nodeIx, connectIx) = 1;
0146         % create reciprocal link due to high in and out degree of hub
0147         if isHub == true
0148             network.matrix(connectIx, nodeIx) = 1;
0149         end
0150     end
0151 
0152     if (isKinless == true || isConnector == true) && isHub == true
0153         tmpExistOutLink = find(network.matrix(nodeIx, :) > 0);
0154         tmpOutDeg = outDegList(nodeIx) - numel(tmpExistOutLink);
0155         tmpExistInLink = find(network.matrix(:, nodeIx) > 0);
0156         tmpInDeg = outDegList(nodeIx) - numel(tmpExistInLink);
0157 
0158         % link to random nodes
0159         tmpValidIx = 1:nNode;
0160         tmpValidIx([tmpExistOutLink, nodeIx, tmpSortIx(1:iNode)]) = [];
0161         tmpValidIx = tmpValidIx(randperm(numel(tmpValidIx)));
0162         tmpValidIx = tmpValidIx(1:tmpOutDeg);
0163         network.matrix(nodeIx, tmpValidIx) = 1;
0164 
0165         % link from random nodes
0166         tmpValidIx = 1:nNode;
0167         tmpValidIx([tmpExistInLink; nodeIx; tmpSortIx(1:iNode)']) = [];
0168         tmpValidIx = tmpValidIx(randperm(numel(tmpValidIx)));
0169         tmpValidIx = tmpValidIx(1:tmpInDeg);
0170         network.matrix(tmpValidIx, nodeIx) = 1;
0171     end
0172 end
0173 
0174 % check the node with in/out degree = 0 exist or not
0175 tmpConnectMat = randomRewire(rewireProb, network.matrix, nNode, hubIxList);
0176 while(~isempty(find(sum(tmpConnectMat, 1) == 0, 1)) || ...
0177         ~isempty(find(sum(tmpConnectMat, 2) == 0, 1)))
0178     disp('Exist a node with 0 degree');
0179     tmpConnectMat = ...
0180         randomRewire(rewireProb, network.matrix, nNode, hubIxList);
0181 end
0182 network.matrix = tmpConnectMat;
0183 network.label = 1:nNode;
0184 network.HubLabel = hubIxList;
0185 end
0186 
0187 function [ matrix ] = randomRewire( rewireProb, matrix, nNode, hubIxList )
0188 % check neurons can be rewired or not
0189 if ~isempty(find(sum(matrix, 1) > (nNode - 1), 1))
0190     error({'Exist a neuron which connect all other neurons.', ...
0191         'Cannot rewire its connection.'});
0192 end
0193 
0194 [rowIxList, colIxList] = find(matrix > 0);
0195 for iConnect = 1:numel(rowIxList)
0196     if rand() > rewireProb
0197         continue;
0198     end
0199 
0200     rowIx = rowIxList(iConnect);
0201     colIx = colIxList(iConnect);
0202 
0203     % don't rewire hub's connections
0204     if ~isempty(find(hubIxList == rowIx, 1)) || ...
0205             ~isempty(find(hubIxList == colIx, 1))
0206         continue;
0207     end
0208 
0209     % change source node
0210     if rand() > 0.5
0211         newRowIx = randi(nNode);
0212         newColIx = colIx;
0213         while matrix(newRowIx, newColIx) == 1 || newRowIx == newColIx
0214             newRowIx = randi(nNode);
0215         end
0216     % change destination node
0217     else
0218         newRowIx = rowIx;
0219         newColIx = randi(nNode);
0220         while matrix(newRowIx, newColIx) == 1 || newRowIx == newColIx
0221             newColIx = randi(nNode);
0222         end
0223     end
0224 
0225     matrix(rowIx, colIx) = 0;
0226     matrix(newRowIx, newColIx) = 1;
0227 end
0228 end
0229 
0230 function [ ringIx ] = ringIndex( ix, nNode )
0231 while ix > nNode
0232     ix = ix - nNode;
0233 end
0234 while ix <= 0
0235     ix = ix + nNode;
0236 end
0237 ringIx = ix;
0238 end

Generated on Thu 30-Jan-2014 00:00:07 by m2html © 2005