latmio_dir_connected.m 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. function [Rlatt,Rrp,ind_rp,eff] = latmio_dir_connected(R,ITER,D)
  2. %LATMIO_DIR_CONNECTED Lattice with preserved in/out degree distribution
  3. %
  4. % [Rlatt,Rrp,ind_rp,eff] = latmio_dir_connected(R,ITER,D);
  5. %
  6. % This function "latticizes" a directed network, while preserving the in-
  7. % and out-degree distributions. In weighted networks, the function
  8. % preserves the out-strength but not the in-strength distributions. The
  9. % function also ensures that the randomized network maintains
  10. % connectedness, the ability for every node to reach every other node in
  11. % the network. The input network for this function must be connected.
  12. %
  13. % Input: R, directed (binary/weighted) connection matrix
  14. % ITER, rewiring parameter
  15. % (each edge is rewired approximately ITER times)
  16. % D, distance-to-diagonal matrix
  17. %
  18. % Output: Rlatt, latticized network in original node ordering
  19. % Rrp, latticized network in node ordering used for
  20. % latticization
  21. % ind_rp, node ordering used for latticization
  22. % eff, number of actual rewirings carried out
  23. %
  24. % References: Maslov and Sneppen (2002) Science 296:910
  25. % Sporns and Zwi (2004) Neuroinformatics 2:145
  26. %
  27. % Mika Rubinov, UNSW, 2007-2010
  28. % Olaf Sporns, Indiana University, 2012
  29. n=size(R,1);
  30. % randomly reorder matrix
  31. ind_rp = randperm(n);
  32. R = R(ind_rp,ind_rp);
  33. % create 'distance to diagonal' matrix
  34. if nargin<3 %if D is not specified by user
  35. D=zeros(n);
  36. u=[0 min([mod(1:n-1,n);mod(n-1:-1:1,n)])];
  37. for v=1:ceil(n/2)
  38. D(n-v+1,:)=u([v+1:n 1:v]);
  39. D(v,:)=D(n-v+1,n:-1:1);
  40. end
  41. end
  42. %end create
  43. [i,j]=find(R);
  44. K=length(i);
  45. ITER=K*ITER;
  46. % maximal number of rewiring attempts per 'iter'
  47. maxAttempts= round(n*K/(n*(n-1)));
  48. % actual number of successful rewirings
  49. eff = 0;
  50. for iter=1:ITER
  51. att=0;
  52. while (att<=maxAttempts) %while not rewired
  53. rewire=1;
  54. while 1
  55. e1=ceil(K*rand);
  56. e2=ceil(K*rand);
  57. while (e2==e1)
  58. e2=ceil(K*rand);
  59. end
  60. a=i(e1); b=j(e1);
  61. c=i(e2); d=j(e2);
  62. if all(a~=[c d]) && all(b~=[c d])
  63. break %all four vertices must be different
  64. end
  65. end
  66. %rewiring condition
  67. if ~(R(a,d) || R(c,b))
  68. %lattice condition
  69. if (D(a,b)*R(a,b)+D(c,d)*R(c,d))>=(D(a,d)*R(a,b)+D(c,b)*R(c,d))
  70. %connectedness condition
  71. if ~(any([R(a,c) R(d,b) R(d,c)]) && any([R(c,a) R(b,d) R(b,a)]))
  72. P=R([a c],:);
  73. P(1,b)=0; P(1,d)=1;
  74. P(2,d)=0; P(2,b)=1;
  75. PN=P;
  76. PN(1,a)=1; PN(2,c)=1;
  77. while 1
  78. P(1,:)=any(R(P(1,:)~=0,:),1);
  79. P(2,:)=any(R(P(2,:)~=0,:),1);
  80. P=P.*(~PN);
  81. PN=PN+P;
  82. if ~all(any(P,2))
  83. rewire=0;
  84. break
  85. elseif any(PN(1,[b c])) && any(PN(2,[d a]))
  86. break
  87. end
  88. end
  89. end %connectedness testing
  90. if rewire %reassign edges
  91. R(a,d)=R(a,b); R(a,b)=0;
  92. R(c,b)=R(c,d); R(c,d)=0;
  93. j(e1) = d; %reassign edge indices
  94. j(e2) = b;
  95. eff = eff+1;
  96. break;
  97. end %edge reassignment
  98. end %lattice condition
  99. end %rewiring condition
  100. att=att+1;
  101. end %while not rewired
  102. end %iterations
  103. % lattice in node order used for latticization
  104. Rrp = R;
  105. % reverse random permutation of nodes
  106. [~,ind_rp_reverse] = sort(ind_rp);
  107. Rlatt = Rrp(ind_rp_reverse,ind_rp_reverse);