Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

get components and components sizes without implementing the Dulmage-Mendelsohn decomposition from scratch #1

Closed
pausz opened this issue Nov 23, 2013 · 1 comment

Comments

@pausz
Copy link

pausz commented Nov 23, 2013

Hello,

A week or so ago I'd started translating some functions from BCT into Python and I came across your repo yesterday.
One of the functions I was interested in using was the get_components. Then I saw it was not implemented yet.

My first thought to find a solution was using networkx connected components.
This function returns, for the time being, the size of the largest component.
I think that using networkx.connected_components_subgraph you could actually
get the nodes of each individual graph.

Ideally, I'd like to have BCT only with nump and scipy, but maybe it'd be a good idea to use networkx as well.
https://github.com/networkx

By the way I tested this against the matlab version using the 998 connectivity matrix presented in:

Honey CJ, Sporns O, Cammoun L, Gigandet X, Thiran JP, Meuli R, Hagmann P (2009) Predicting human resting-state functional connectivity from structural connectivity. Proc Natl Acad Sci U S A 106: 2035–2040.

and I got the same results.

import numpy
import networkx

def get_components_sizes(A):
"""
Get connected components sizes.
Returns the size of the largest component of an undirected graph specified by the binary and
undirected connection matrix A.

Parameters
----------

A : array
         binary undirected (BU) connectivity matrix.

Returns
-------

largest component : float 
        size  of the largest component

Raises
-------
      Value Error
          If A is not square.


.. warning:: requires networkx 
.. author:: Paula Sanz Leon

"""


# Just to preserve the original code. Check if the input matrix is square.
# Further checks should include: check if it's binary for the functions that require so
# and check that is undirected. 

# Check if it is square
if A.shape[0] != A.shape[1]:
    raise ValueError('The input matrix is not square')
else:
    pass

# Binarize without modifying the original matrix (in case A is weighted)
temp_A = A.copy()
temp_A[temp_A > 0] = 1.0    

# Set diagonal elements to one
if numpy.diag(A).sum() != A.shape[0]:
   numpy.fill_diagonal(temp_A, 1.0)

# build a networkx graph to get largest connected component.
components = networkx.connected_components(networkx.from_numpy_matrix(numpy.matrix(temp_A)))
# For the time being returns the size of the largest component
component_sizes = [len(x) for x in components][0]
return component_sizes
@aestrivex
Copy link
Owner

Fantastic! Thanks.

It should be fine to have networkx dependencies; if its only imported in one function, it's strictly better than having nothing at all.

aestrivex pushed a commit that referenced this issue Oct 28, 2015
Bringing main maintainer's bug fixes into my fork
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants