latmio_und.m 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. function [Rlatt,Rrp,ind_rp,eff] = latmio_und(R,ITER,D)
  2. %LATMIO_UND Lattice with preserved degree distribution
  3. %
  4. % [Rlatt,Rrp,ind_rp,eff] = latmio_und(R,ITER,D);
  5. %
  6. % This function "latticizes" an undirected network, while preserving the
  7. % degree distribution. The function does not preserve the strength
  8. % distribution in weighted networks.
  9. %
  10. % Input: R, undirected (binary/weighted) connection matrix
  11. % ITER, rewiring parameter
  12. % (each edge is rewired approximately ITER times)
  13. % D, distance-to-diagonal matrix
  14. %
  15. % Output: Rlatt, latticized network in original node ordering
  16. % Rrp, latticized network in node ordering used for
  17. % latticization
  18. % ind_rp, node ordering used for latticization
  19. % eff, number of actual rewirings carried out
  20. %
  21. % References: Maslov and Sneppen (2002) Science 296:910
  22. % Sporns and Zwi (2004) Neuroinformatics 2:145
  23. %
  24. % 2007-2012
  25. % Mika Rubinov, UNSW
  26. % Jonathan Power, WUSTL
  27. % Olaf Sporns, IU
  28. % Modification History:
  29. % Jun 2007: Original (Mika Rubinov)
  30. % Apr 2008: Edge c-d is flipped with 50% probability, allowing to explore
  31. % all potential rewirings (Jonathan Power)
  32. % Feb 2012: limit on number of attempts, distance-to-diagonal as input,
  33. % count number of successful rewirings (Olaf Sporns)
  34. % Feb 2012: permute node ordering on each run, to ensure lattices are
  35. % shuffled across mutliple runs (Olaf Sporns)
  36. n=size(R,1);
  37. % randomly reorder matrix
  38. ind_rp = randperm(n);
  39. R = R(ind_rp,ind_rp);
  40. % create 'distance to diagonal' matrix
  41. if nargin<3 %if D is not specified by user
  42. D=zeros(n);
  43. u=[0 min([mod(1:n-1,n);mod(n-1:-1:1,n)])];
  44. for v=1:ceil(n/2)
  45. D(n-v+1,:)=u([v+1:n 1:v]);
  46. D(v,:)=D(n-v+1,n:-1:1);
  47. end
  48. end
  49. %end create
  50. [i,j]=find(tril(R));
  51. K=length(i);
  52. ITER=K*ITER;
  53. % maximal number of rewiring attempts per 'iter'
  54. maxAttempts= round(n*K/(n*(n-1)/2));
  55. % actual number of successful rewirings
  56. eff = 0;
  57. for iter=1:ITER
  58. att=0;
  59. while (att<=maxAttempts) %while not rewired
  60. while 1
  61. e1=ceil(K*rand);
  62. e2=ceil(K*rand);
  63. while (e2==e1)
  64. e2=ceil(K*rand);
  65. end
  66. a=i(e1); b=j(e1);
  67. c=i(e2); d=j(e2);
  68. if all(a~=[c d]) && all(b~=[c d])
  69. break %all four vertices must be different
  70. end
  71. end
  72. if rand>0.5
  73. i(e2)=d; j(e2)=c; %flip edge c-d with 50% probability
  74. c=i(e2); d=j(e2); %to explore all potential rewirings
  75. end
  76. %rewiring condition
  77. if ~(R(a,d) || R(c,b))
  78. %lattice condition
  79. 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))
  80. R(a,d)=R(a,b); R(a,b)=0;
  81. R(d,a)=R(b,a); R(b,a)=0;
  82. R(c,b)=R(c,d); R(c,d)=0;
  83. R(b,c)=R(d,c); R(d,c)=0;
  84. j(e1) = d; %reassign edge indices
  85. j(e2) = b;
  86. eff = eff+1;
  87. break;
  88. end %lattice condition
  89. end %rewiring condition
  90. att=att+1;
  91. end %while not rewired
  92. end %iterations
  93. % lattice in node order used for latticization
  94. Rrp = R;
  95. % reverse random permutation of nodes
  96. [~,ind_rp_reverse] = sort(ind_rp);
  97. Rlatt = Rrp(ind_rp_reverse,ind_rp_reverse);