Skip to content

Commit

Permalink
🆕 First Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
GiulioRossetti committed Dec 1, 2018
1 parent 5c6fbee commit 4317cc8
Show file tree
Hide file tree
Showing 17 changed files with 266 additions and 16 deletions.
5 changes: 5 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[run]
omit =
setup.py
scripts/NDQL_execute.py
scripts/NDQL_translate.py
27 changes: 11 additions & 16 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Created by .ignore support plugin (hsz.mobi)
### Python template
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
Expand All @@ -8,6 +10,7 @@ __pycache__/

# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
Expand All @@ -23,7 +26,6 @@ wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
Expand All @@ -43,9 +45,8 @@ htmlcov/
.cache
nosetests.xml
coverage.xml
*.cover
*,cover
.hypothesis/
.pytest_cache/

# Translations
*.mo
Expand All @@ -54,7 +55,6 @@ coverage.xml
# Django stuff:
*.log
local_settings.py
db.sqlite3

# Flask stuff:
instance/
Expand All @@ -78,27 +78,22 @@ target/
# celery beat schedule file
celerybeat-schedule

# SageMath parsed files
*.sage.py

# Environments
# dotenv
.env

# virtualenv
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site
#docs

# mypy
.mypy_cache/
docs/_build
docs/_static
docs/_templates
20 changes: 20 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
language: python
python:
- "2.7"
- "3.4"
- "3.5"
- "3.6"

before_install:
- pip install pytest pytest-cov
- pip install coveralls

install:
- pip install .
- pip install -r requirements.txt

script:
- py.test --cov=./ --cov-config=.coveragerc

after_success:
- coveralls
23 changes: 23 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
Copyright (c) 2016, Giulio Rossetti
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1 change: 1 addition & 0 deletions _config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
theme: jekyll-theme-minimal
Empty file added nclib/__init__.py
Empty file.
Empty file added nclib/models/__init__.py
Empty file.
28 changes: 28 additions & 0 deletions nclib/models/map_equation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import infomap as map
import networkx as nx
from collections import defaultdict
from wurlitzer import pipes


def infomap(g):

g1 = nx.convert_node_labels_to_integers(g, label_attribute="name")
name_map = nx.get_node_attributes(g1, 'name')
coms_to_node = defaultdict(list)

with pipes():
im = map.Infomap()
network = im.network()
for e in g1.edges():
network.addLink(e[0],e[1])
im.run()

for node in im.iterTree():
if node.isLeaf():
nid = node.physicalId
module = node.moduleIndex()
nm = name_map[nid]
coms_to_node[module].append(nm)

coms_infomap = [tuple(c) for c in coms_to_node.values()]
return coms_infomap
28 changes: 28 additions & 0 deletions nclib/models/modularity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import community as louvain_modularity
import leidenalg
import igraph as ig
from collections import defaultdict


def louvain(g, weight='weight', resolution=1., randomize=False):

coms = louvain_modularity.best_partition(g, weight=weight, resolution=resolution, randomize=randomize)

# Reshaping the results
coms_to_node = defaultdict(list)
for n, c in coms.items():
coms_to_node[c].append(n)

coms_louvain = [tuple(c) for c in coms_to_node.values()]
return coms_louvain


def leiden(g):
gi = ig.Graph(directed=False)
gi.add_vertices(list(g.nodes()))
gi.add_edges(list(g.edges()))

part = leidenalg.find_partition(gi, leidenalg.ModularityVertexPartition)
coms = [gi.vs[x]['name'] for x in part]
return coms

33 changes: 33 additions & 0 deletions nclib/models/node_centric.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import demon as d
import angel as an
import networkx as nx
import os
from nclib.utils import suppress_stdout


def demon(g, epsilon, min_com_size=3):
"""
:param g:
:param epsilon:
:param min_com_size:
:param filename:
:return:
"""

with suppress_stdout():
dm = d.Demon(graph=g, epsilon=epsilon, min_community_size=min_com_size)
coms = dm.execute()

return coms


def angel(g, threshold, min_community_size=3):

nx.write_edgelist(g, "temp.ncol")
with suppress_stdout():
a = an.Angel("temp.ncol", min_comsize=min_community_size, threshold=threshold, save=False)
coms = a.execute()
os.remove("temp.ncol")

return coms
Empty file added nclib/test/__init__.py
Empty file.
39 changes: 39 additions & 0 deletions nclib/test/community_discovery_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import unittest
from nclib.models.node_centric import demon, angel
from nclib.models.modularity import louvain, leiden
from nclib.models.map_equation import infomap
import networkx as nx
import os


class NodeCentricTests(unittest.TestCase):

def test_demon(self):
g = nx.karate_club_graph()
coms = demon(g, epsilon=0.25)
self.assertEqual(len(coms), 2)

def test_angel(self):
g = nx.karate_club_graph()
coms = angel(g, threshold=0.25)
self.assertEqual(len(coms), 1)

def test_louvain(self):
g = nx.karate_club_graph()
coms = louvain(g)
self.assertEqual(len(coms), 4)

def test_leiden(self):
g = nx.karate_club_graph()
coms = leiden(g)
self.assertEqual(len(coms), 4)

def test_infomap(self):
g = nx.karate_club_graph()
coms = infomap(g)
self.assertEqual(len(coms), 3)
os.remove(".tree")


if __name__ == '__main__':
unittest.main()
17 changes: 17 additions & 0 deletions nclib/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from contextlib import contextmanager
import sys
import os


@contextmanager
def suppress_stdout():
with open(os.devnull, "w") as devnull:
old_stdout = sys.stdout
old_stderr = sys.stderr
sys.stdout = devnull
sys.stderr = devnull
try:
yield
finally:
sys.stdout = old_stdout
sys.stderr = old_stderr
Empty file added nclib/viz/__init__.py
Empty file.
9 changes: 9 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
mock==2.0.0
sphinx_rtd_theme==0.4.2
numpy==1.15.2
future==0.16.0
networkx==2.2
matplotlib==2.2.2
python-igraph
leidenalg
wurlitzer
4 changes: 4 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[bdist_wheel]
# This flag says that the code is written to work on both Python 2 and Python
# 3. If at all possible, it is good practice to do this. If you cannot, you
# will need to generate wheels for each Python version that you support.
48 changes: 48 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from setuptools import setup, find_packages
from codecs import open
from os import path

__author__ = 'Giulio Rossetti'
__license__ = "BSD-2-Clause"
__email__ = "[email protected]"

here = path.abspath(path.dirname(__file__))

# Get the long description from the README file
with open(path.join(here, 'README.md'), encoding='utf-8') as f:
long_description = f.read()


setup(name='nclib',
version='0.0.1',
license='BSD-Clause-2',
description='Network Community Library',
url='https://github.com/GiulioRossetti/nclib',
author='Giulio Rossetti',
author_email='[email protected]',
use_2to3=True,
classifiers=[
# How mature is this project? Common values are
# 3 - Alpha
# 4 - Beta
# 5 - Production/Stable
'Development Status :: 3 - Alpha',

# Indicate who your project is intended for
'Intended Audience :: Developers',
'Topic :: Software Development :: Build Tools',

# Pick your license as you wish (should match "license" above)
'License :: OSI Approved :: BSD License',

"Operating System :: OS Independent",

# Specify the Python versions you support here. In particular, ensure
# that you indicate whether you support Python 2, Python 3 or both.
'Programming Language :: Python',
'Programming Language :: Python :: 3'
],
keywords='epidemics opinion-dynamics simulator complex-networks',
install_requires=['numpy', 'networkx', 'scipy', 'future', ''],
packages=find_packages(exclude=["*.test", "*.test.*", "test.*", "test", "nclib.test", "nclib.test.*"]),
)

0 comments on commit 4317cc8

Please sign in to comment.