backbone_wu.m 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. function [CIJtree,CIJclus] = backbone_wu(CIJ,avgdeg)
  2. %BACKBONE_WU Backbone
  3. %
  4. % [CIJtree,CIJclus] = backbone_wu(CIJ,avgdeg)
  5. %
  6. % The network backbone contains the dominant connections in the network
  7. % and may be used to aid network visualization. This function computes
  8. % the backbone of a given weighted and undirected connection matrix CIJ,
  9. % using a minimum-spanning-tree based algorithm.
  10. %
  11. % input: CIJ, connection/adjacency matrix (weighted, undirected)
  12. % avgdeg, desired average degree of backbone
  13. % output:
  14. % CIJtree, connection matrix of the minimum spanning tree of CIJ
  15. % CIJclus, connection matrix of the minimum spanning tree plus
  16. % strongest connections up to an average degree 'avgdeg'
  17. %
  18. % NOTE: nodes with zero strength are discarded.
  19. % NOTE: CIJclus will have a total average degree exactly equal to
  20. % (or very close to) 'avgdeg'.
  21. % NOTE: 'avgdeg' backfill is handled slightly differently than in Hagmann
  22. % et al 2008.
  23. %
  24. % Reference: Hidalgo et al. (2007) Science 317, 482.
  25. % Hagmann et al. (2008) PLoS Biol
  26. %
  27. % Olaf Sporns, Indiana University, 2007/2008/2010/2012
  28. N = size(CIJ,1);
  29. CIJtree = zeros(N);
  30. % find strongest edge (note if multiple edges are tied, only use first one)
  31. [i,j,s] = find(max(max(CIJ))==CIJ); %#ok<*ASGLU>
  32. im = [i(1) i(2)];
  33. jm = [j(1) j(2)];
  34. % copy into tree graph
  35. CIJtree(im,jm) = CIJ(im,jm);
  36. in = im;
  37. out = setdiff(1:N,in);
  38. % repeat N-2 times
  39. for n=1:N-2
  40. % find strongest link between 'in' and 'out',ignore tied ranks
  41. [i,j,s] = find(max(max(CIJ(in,out)))==CIJ(in,out));
  42. im = in(i(1));
  43. jm = out(j(1));
  44. % copy into tree graph
  45. CIJtree(im,jm) = CIJ(im,jm); CIJtree(jm,im) = CIJ(jm,im);
  46. in = [in jm]; %#ok<AGROW>
  47. out = setdiff(1:N,in);
  48. end;
  49. % now add connections back, with the total number of added connections
  50. % determined by the desired 'avgdeg'
  51. CIJnotintree = CIJ.*~CIJtree;
  52. [a,b] = sort(nonzeros(CIJnotintree),'descend');
  53. cutoff = avgdeg*N - 2*(N-1);
  54. thr = a(cutoff);
  55. CIJclus = CIJtree + CIJnotintree.*(CIJnotintree>=thr);