rentian_scaling_3d.m 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. function [N,E] = rentian_scaling_3d(A,XYZ,n,tol)
  2. % RENTIAN_SCALING_3D Rentian scaling for networks embedded in three dimensions.
  3. %
  4. % [N,E] = rentian_scaling_3d(A,XYZ,n,tol)
  5. %
  6. % Physical Rentian scaling (or more simply Rentian scaling) is a property
  7. % of systems that are cost-efficiently embedded into physical space. It is
  8. % what is called a "topo-physical" property because it combines information
  9. % regarding the topological organization of the graph with information
  10. % about the physical placement of connections. Rentian scaling is present
  11. % in very large scale integrated circuits, the C. elegans neuronal network,
  12. % and morphometric and diffusion-based graphs of human anatomical networks.
  13. % Rentian scaling is determined by partitioning the system into cubes,
  14. % counting the number of nodes inside of each cube (N), and the number of
  15. % edges traversing the boundary of each cube (E). If the system displays
  16. % Rentian scaling, these two variables N and E will scale with one another
  17. % in loglog space. The Rent's exponent is given by the slope of log10(E)
  18. % vs. log10(N), and can be reported alone or can be compared to the
  19. % theoretical minimum Rent's exponent to determine how cost efficiently the
  20. % network has been embedded into physical space. Note: if a system displays
  21. % Rentian scaling, it does not automatically mean that the system is
  22. % cost-efficiently embedded (although it does suggest that). Validation
  23. % occurs when comparing to the theoretical minimum Rent's exponent for that
  24. % system.
  25. %
  26. % INPUTS:
  27. %
  28. % A: MxM adjacency matrix.
  29. % Must be unweighted, binary, and symmetric.
  30. % XYZ: Matrix of node placement coordinates.
  31. % Must be in the form of an Mx3 matrix [x y z], where M is
  32. % the number of nodes and x, y, z are column vectors of node
  33. % coordinates.
  34. % n: Number of partitions to compute. Each partition is a data
  35. % point. You want a large enough number to adequately
  36. % estimate the Rent's exponent.
  37. % tol: This should be a small value (for example 1e-6).
  38. % In order to mitigate the effects of boundary conditions due
  39. % to the finite size of the network, we only allow partitions
  40. % that are contained within the boundary of the network. This
  41. % is achieved by first computing the volume of the convex
  42. % hull of the node coordinates (V). We then ensure that the
  43. % volume of the convex hull computed on the original node
  44. % coordinates plus the coordinates of the randomly generated
  45. % partition (Vnew) is within a given tolerance of the
  46. % original (i.e. check abs(V - Vnew) < tol). Thus tol, should
  47. % be a small value in order to make sure the partitions are
  48. % contained largely within the boundary of the network, and
  49. % thus the number of nodes and edges within the box are not
  50. % skewed by finite size effects.
  51. %
  52. % OUTPUTS:
  53. %
  54. % N: nx1 vector of the number of nodes in each of the n partitions.
  55. % E: nx1 vector of the number of edges crossing the boundary of
  56. % each partition.
  57. %
  58. % Subsequent Analysis:
  59. %
  60. % Rentian scaling plots are created by: figure; loglog(E,N,'*');
  61. %
  62. % To determine the Rent's exponent, p, we need to determine
  63. % the slope of E vs. N in loglog space, which is the Rent's
  64. % exponent. There are many ways of doing this with more or less
  65. % statistical rigor. Robustfit in MATLAB is one such option:
  66. %
  67. % [b,stats] = robustfit(log10(N),log10(E))
  68. %
  69. % Then the Rent's exponent is b(1,2) and the standard error of the
  70. % estimation is given by stats.se(1,2).
  71. %
  72. % Note: n=5000 was used in Bassett et al. 2010 in PLoS CB.
  73. %
  74. % Reference:
  75. % Danielle S. Bassett, Daniel L. Greenfield, Andreas Meyer-Lindenberg,
  76. % Daniel R. Weinberger, Simon W. Moore, Edward T. Bullmore. Efficient
  77. % physical embedding of topologically complex information processing
  78. % networks in brains and computer circuits. PLoS Comput Biol, 2010,
  79. % 6(4):e1000748.
  80. %
  81. % Modification History:
  82. %
  83. % 2010: Original (Dani Bassett)
  84. % Dec 2016: Updated code so that both partition centers and partition
  85. % sizes are chosen at random. Also added in a constraint on
  86. % partition placement that prevents boxes from being located
  87. % outside the edges of the network. This helps prevent skewed
  88. % results due to boundary effects arising from the finite size
  89. % of the network. (Lia Papadopoulos)
  90. %
  91. % determine the number of nodes in the system
  92. M = numel(XYZ(:,1));
  93. % rescale coordinates so that they are all greater than unity
  94. XYZn = XYZ - repmat(min(XYZ)-1,M,1);
  95. % compute the area of convex hull (i.e. are of the boundary) of the network
  96. [~,V] = convhull(XYZn(:,1),XYZn(:,2),XYZn(:,3));
  97. % min and max network coordinates
  98. xmin = min(XYZn(:,1));
  99. xmax = max(XYZn(:,1));
  100. ymin = min(XYZn(:,2));
  101. ymax = max(XYZn(:,2));
  102. zmin = min(XYZn(:,3));
  103. zmax = max(XYZn(:,3));
  104. % initialize vectors of number of nodes in box and number of edges crossing
  105. % box
  106. N = zeros(n,1);
  107. E = zeros(n,1);
  108. % create partitions, and count the number of nodes inside the partition (N)
  109. % and the number of edges traversing the boundary of the partition (E)
  110. nPartitions = 0;
  111. % create partitions, and count the number of nodes inside the partition (N)
  112. % and the number of edges traversing the boundary of the partition (E)
  113. while nPartitions<(n+1)
  114. % variable to check if partition center is within network boundary
  115. % OK if inside == 1
  116. inside = 0;
  117. while inside == 0
  118. % pick a random (x,y,z) coordinate to be the center of the box
  119. randx = xmin+(xmax-xmin)*rand(1);
  120. randy = ymin+(ymax-ymin)*rand(1);
  121. randz = zmin+(zmax-zmin)*rand(1);
  122. % make sure the point is inside the convex hull of the network
  123. newCoords = [XYZn; [randx randy randz]];
  124. [~,Vnew] = convhull(newCoords(:,1),newCoords(:,2),newCoords(:,3));
  125. % if the old convex hull area and new convex hull area are equal
  126. % then the box center must be inside the network boundary.
  127. if isequal(V,Vnew)==0
  128. inside = 0;
  129. else
  130. inside = 1;
  131. end
  132. end
  133. % determine the approximate maximum distance the box can extend, given
  134. % the center point and the bounds of the network
  135. deltaX = min(abs(xmax-randx),abs(xmin-randx));
  136. deltaY = min(abs(ymax-randy),abs(ymin-randy));
  137. deltaZ = min(abs(zmax-randz),abs(zmin-randz));
  138. deltaLmin = min([deltaX deltaY deltaZ]);
  139. % variable to check if partition is within network boundary
  140. % OK if inside == 1
  141. inside = 0;
  142. while inside == 0
  143. % pick a random (side length)/2 that is between 0 and the
  144. % max possible
  145. deltaL = deltaLmin*rand(1);
  146. % (x,y,z) coordinates for corners of box
  147. boxCoords = [randx - deltaL randy - deltaL randz - deltaL; ...
  148. randx - deltaL randy - deltaL randz + deltaL; ...
  149. randx - deltaL randy + deltaL randz - deltaL; ...
  150. randx - deltaL randy + deltaL randz + deltaL; ...
  151. randx + deltaL randy - deltaL randz - deltaL;...
  152. randx + deltaL randy - deltaL randz + deltaL; ...
  153. randx + deltaL randy + deltaL randz - deltaL; ...
  154. randx + deltaL randy + deltaL randz + deltaL];
  155. % check if all corners of box are inside the convex hull of the
  156. % network
  157. newCoords = [XYZn; boxCoords];
  158. [~,Vnew] = convhull(newCoords(:,1),newCoords(:,2),newCoords(:,3));
  159. % make sure the new convex hull that includes the partition corners
  160. % is within a certain tolerance of the original convex hull area.
  161. if abs(V-Vnew)>tol
  162. inside = 0;
  163. else
  164. inside = 1;
  165. end
  166. end
  167. % Find nodes inside the box, edges crossing the boundary
  168. L = find(XYZn(:,1)>(randx-deltaL) & XYZn(:,1)<(randx+deltaL) ...
  169. & XYZn(:,2)>(randy-deltaL) & XYZn(:,2)<(randy+deltaL) ...
  170. & XYZn(:,3)>(randz-deltaL) & XYZn(:,3)<(randz+deltaL));
  171. if ~isempty(L) == 1
  172. nPartitions = nPartitions+1;
  173. % count edges crossing the boundary of the cube
  174. E(nPartitions,1) = sum(sum(A(L,setdiff(1:M,L))));
  175. % count nodes inside of the cube
  176. N(nPartitions,1) = numel(L);
  177. end
  178. end
  179. return;