{"id":18877824,"url":"https://github.com/filipinascimento/rmodularity","last_synced_at":"2025-04-14T18:31:54.497Z","repository":{"id":44687675,"uuid":"411505436","full_name":"filipinascimento/RModularity","owner":"filipinascimento","description":"Small utility to calculate the robustness modularity, information modularity and modularity difference.","archived":false,"fork":false,"pushed_at":"2024-07-31T21:09:22.000Z","size":936,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-28T07:11:15.236Z","etag":null,"topics":["complex-networks","modularity","networks","robustness-modularity","sbm"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/filipinascimento.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-09-29T02:35:44.000Z","updated_at":"2024-08-29T20:46:10.000Z","dependencies_parsed_at":"2024-11-08T06:36:37.225Z","dependency_job_id":null,"html_url":"https://github.com/filipinascimento/RModularity","commit_stats":{"total_commits":14,"total_committers":1,"mean_commits":14.0,"dds":0.0,"last_synced_commit":"82898a007db802c92f356b35a21c5eeed94bbffe"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/filipinascimento%2FRModularity","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/filipinascimento%2FRModularity/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/filipinascimento%2FRModularity/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/filipinascimento%2FRModularity/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/filipinascimento","download_url":"https://codeload.github.com/filipinascimento/RModularity/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248936775,"owners_count":21186105,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["complex-networks","modularity","networks","robustness-modularity","sbm"],"created_at":"2024-11-08T06:22:07.228Z","updated_at":"2025-04-14T18:31:54.019Z","avatar_url":"https://github.com/filipinascimento.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Robustness Modularity\nSmall utility to calculate the robustness modularity, information modularity\nand modularity difference.\n\n## License\nThe software is distributed under the [MIT license](LICENSE.md).\n  \n## Authors\n  * Filipi N. Silva \u003cfilsilva@iu.edu\u003e\n  * Santo Fortunato \u003csanto@iu.edu\u003e\n\n## Dependencies\nRobustness Modularity requires the following dependencies:\n  \n  * [Python 3.6+](https://www.python.org/downloads/)\n  * [Numpy](http://www.numpy.org/)\n  * [graph-tool](https://graph-tool.skewed.de)\n  * [louvain](https://pypi.org/project/louvain/)\n  * [python-igraph](https://igraph.org/python/)\n\nExcept for `graph-tool` all the other packages can be installed using pip:\n```bash\npip install -r requirements.txt\n```\n\nTo install `graph-tool` follow the instructions in the [graph-tool documentation](https://git.skewed.de/count0/graph-tool/-/wikis/installation-instructions).\n\nWe recommend to install it using [conda](https://conda.io/):\n```bash\nconda install -c conda-forge graph-tool\n```\n\n## Installation\nAfter installing `graph-tool` dependency, the tool can be installed using pip:\n\n```bash\npip install python-igraph louvain RModularity\n```\n\nor from source:\n```bash\npip install python-igraph louvain git+https://github.com/filipinascimento/RModularity.git\n```\n\n## Usage\nWe provide three networks for testing in the `SampleNetworks` folder.\nA full usage example can be found in `example.py`.\n\nFirst import the `RModularity` module:\n```python\nimport RModularity\n```\n\nFor this example we will be using `igraph` to load the sample networks and\n`pathlib` to deal with the paths:\n```python\nimport igraph as ig\nfrom pathlib import Path\n```\n\nWhen multiprocessing is enabled, the all the calculations need to be done\nin the main process, thus use `if __name__ == '__main__':`. Let's load a\nnetwork from the `SampleNetworks` folder and define some paths:\n```python\nif __name__ == '__main__':\n    networkName = \"road-euroroad\"\n    # networkName = \"LFR_mu0.1\"\n    # networkName = \"LFR_mu1.0\"\n    \n    outputSuffix = \"\"\n    figurePath = Path(\"Figures\")\n    figurePath.mkdir(parents=True, exist_ok=True)\n\n    g = ig.Graph.Read_GML(str(Path(\"SampleNetworks\")/(\"%s.gml\" % networkName)))\n```\n\nYou can calculate the approximated robustness modularity using the `RModularityFast` function, which implements the fast Monte-Carlo algorithm.\n```python\n    Q_rA = RModularity.RModularityFast(\n        g.vcount(), # Number of nodes\n        g.get_edgelist(), # Edges list\n        g.is_directed(), # Directed or not\n        )\n    print(\"Q_rA = \", Q_rA)\n```\n\nYou can use the `RModularity` function to calculate the robustness modularity without approximations:\n```python\n    Q_r, probabilities, TPRCurve, \\\n     DLCurvesTrivial, DLCurvesDetected = RModularity.RModularity(\n         g.vcount(), # Number of nodes\n         g.get_edgelist(), # Edges list\n         g.is_directed(), # Directed or not\n         outputCurves=True,\n         )\n\n    print(\"Q_r = \", Q_r)\n```\nBy setting `outputCurves` to `True`, the Trivial Partition Ratio (TPR) and the description lengths of the detected and trivial partitions will be returned.\n\nModularity difference (Q_diff) can be calculated using the `modularityDifference` function:\n```python\n    Q_diff = RModularity.modularityDifference(\n        g.vcount(),\n        g.get_edgelist(),\n        g.is_directed()\n    )\n```\n\nInformation modularity can be calculated using the `informationModularity`\nfunction:\n```python\n    Q_DL = RModularity.informationModularity(\n        g.vcount(),\n        g.get_edgelist(),\n        g.is_directed()\n    )\n    print(\"Q_DL = \", Q_DL)\n```\n\nHere we also illustrate how to generate the TPR and Description lengths plots.\nFirst let's import a few extra packages\n```python\n    import numpy as np\n    import matplotlib.pyplot as plt\n    import matplotlib.patches as mpl_patches\n```\n\nLet's calculate average and std for the curves:\n```python\n    avgDLCurvesTrivial = np.mean(DLCurvesTrivial, axis=1)\n    avgDLCurvesDetected = np.mean(DLCurvesDetected, axis=1)\n    stdDLCurvesTrivial = np.std(DLCurvesTrivial, axis=1)\n    stdDLCurvesDetected = np.std(DLCurvesDetected, axis=1)\n\n    diffDLCurves = (DLCurvesTrivial-DLCurvesDetected) / DLCurvesTrivial\n    avgDiffDLCurves = np.mean(diffDLCurves, axis=1)\n    stdDiffDLCurves = np.std(diffDLCurves, axis=1)\n```\n\nNow let's plot the TPR curve:\n```python\n    fig = plt.figure(figsize=(3*1.61803398875, 3))\n    ax = plt.axes((0.2, 0.2, 0.70, 0.70), facecolor='w')\n    nodeCount = g.vcount()\n    averageDegree = np.mean(g.degree())\n    TPRArea = Q_r\n    trivialRatios = TPRCurve\n    ax.plot(probabilities, trivialRatios, color=\"#262626\", lw=2.0)\n    ax.fill_between(probabilities, trivialRatios, 1, color=\"#E8EAEA\")\n    ax.set_xlabel(\"$p$\")\n    ax.set_ylabel(\"TPR\")\n    ax.set_title(networkName)\n    ax.set_xlim(-0.00, 1.02)\n    ax.set_ylim(-0.020, 1.020)\n    handles = [mpl_patches.Rectangle((0, 0), 1, 1, fc=\"white\", ec=\"white\",\n                                     lw=0, alpha=0)] * 3\n    labels = []\n    labels.append(\"$N$ = %d\" % nodeCount)\n    labels.append(\"$\\\\langle k\\\\rangle$ = %.2f\" % averageDegree)\n    labels.append(\"$Q_{r}$ = %.2f\" % TPRArea)\n\n    ax.legend(handles, labels, loc='best',\n              fancybox=False, framealpha=0,\n              handlelength=0, handletextpad=0)\n    ax.spines['right'].set_visible(False)\n    ax.spines['top'].set_visible(False)\n    for axis in ['bottom', 'left']:\n        ax.spines[axis].set_linewidth(1.5)\n    ax.tick_params(width=1.5)\n    fig.savefig(figurePath/(\"TPR_%s%s.pdf\" % (networkName, outputSuffix)))\n    plt.close(fig)\n```\n\nNow let's plot the description length curve:\n```python\n    fig = plt.figure(figsize=(3*1.61803398875, 3))\n    ax = plt.axes((0.2, 0.2, 0.70, 0.70), facecolor='w')\n    ax.plot(probabilities, avgDLCurvesDetected, lw=2.0, label=\"Detected\")\n    ax.fill_between(probabilities, avgDLCurvesDetected-stdDLCurvesDetected,\n                    avgDLCurvesDetected+stdDLCurvesDetected, alpha=0.2)\n\n    ax.plot(probabilities, avgDLCurvesTrivial, lw=2.0, label=\"Trivial\")\n    ax.fill_between(probabilities, avgDLCurvesTrivial-stdDLCurvesTrivial,\n                    avgDLCurvesTrivial+stdDLCurvesTrivial, alpha=0.2)\n\n    ax.set_xlabel(\"$p$\")\n    ax.set_ylabel(\"DL\")\n    ax.set_title(networkName)\n    ax.set_xlim(-0.00, 1.02)\n\n    ax.legend()\n    ax.spines['right'].set_visible(False)\n    ax.spines['top'].set_visible(False)\n    for axis in ['bottom', 'left']:\n        ax.spines[axis].set_linewidth(1.5)\n    ax.tick_params(width=1.5)\n    fig.savefig(figurePath/(\"DL_%s%s.pdf\" % (networkName, outputSuffix)))\n    plt.close(fig)\n```\n\nAnd finally, let's plot the information modularity along `p`:\n```python\n    fig = plt.figure(figsize=(3*1.61803398875, 3))\n    ax = plt.axes((0.2, 0.2, 0.70, 0.70), facecolor='w')\n    ax.plot(probabilities, avgDiffDLCurves, lw=2.0, label=\"Detected\")\n    ax.fill_between(probabilities, avgDiffDLCurves-stdDiffDLCurves,\n                    avgDiffDLCurves+stdDiffDLCurves, alpha=0.2)\n\n    ax.set_xlabel(\"$p$\")\n    ax.set_ylabel(\"$Q_\\mathrm{DL}$\")\n    ax.set_title(networkName)\n    ax.set_xlim(-0.00, 1.02)\n\n    ax.spines['right'].set_visible(False)\n    ax.spines['top'].set_visible(False)\n    for axis in ['bottom', 'left']:\n        ax.spines[axis].set_linewidth(1.5)\n    ax.tick_params(width=1.5)\n    fig.savefig(figurePath/(\"DLDiff_%s%s.pdf\" % (networkName, outputSuffix)))\n    plt.close(fig)\n```\n\nPlease refer to the next section for more details on how to use this library.\n\n\n## Full API documentation\n\n### \u003ckbd\u003efunction\u003c/kbd\u003e `RModularityFast`\n```python\nRModularity(\n    nodeCount,\n    edges,\n    directed=False,\n    perturbationCount=48,\n    detectionTrials=1,\n    showProgress=True,\n    useMultiprocessing=True,\n    useCoarseStep = True,\n    fineError=0.01,\n    coarseError = 0.02,\n    minSimilarTrials=2,\n)\n```\n\nComputes the approximated Robustness Modularity of a network\nusing a Monte-Carlo approach. Note that this approach can not\nprocude the curves of TPR.\n\nParameters \n  * `nodeCount` : `int`  \n    The number of nodes in the network.\n  * `edges` : list of tuples  \n    A list of the edges in the network.\n  * `directed` : `int`, optional  \n    Whether the network is directed or not.\n  * `perturbationCount` : `int`, optional  \n    The number of perturbations to perform.  (defaults to 25)\n  * `detectionTrials` : `int`, optional  \n    The number of times to perform community  detection for each perturbed network. (defaults to 1)\n  * `rewireResolution` : `int`, optional  \n    The number values points for the rewire  probabilities (from 0 to 1) to calculate  the Trivial Partition Ratio (TPR) curves  and Robustness Modularity. (defaults to 51)\n  * `showProgress` : `bool`, optional  \n    Shows a progress bar if enabled.  (defaults to True)\n  * `useMultiprocessing`: `bool`, optional  \n    Uses parallel processing to calculate  Rmodularity.  (defaults to True)\n  * `useCoarseStep`: `bool`, optional\n    Finds the plateal region using a binary search before applying\n    the Monte-Carlo approach. (defaults to True)\n  * `fineError`: `float`, optional\n    Error tolerance for the fine step. (defaults to 0.01)\n  * `coarseError`: `float`, optional\n      Error tolerance for the coarse step. (defaults to 0.02)\n  * `minSimilarTrials`: `int`, optional\n      The minimum number of similar trials to perform before \n      stopping the Monte-Carlo approach.(defaults to 2)\n\nReturns \n  * `float` if `outputCurves` is `False`  \n    The Robustness Modularity of the network.\n\n\n---\n\n### \u003ckbd\u003efunction\u003c/kbd\u003e `RModularity`\n```python\nRModularity(\n    nodeCount,\n    edges,\n    directed=False,\n    perturbationCount=25,\n    detectionTrials=1,\n    rewireResolution=51,\n    outputCurves=False,\n    showProgress=True,\n    useMultiprocessing=True\n)\n```\n\nComputes the Robustness Modularity of a network. \n\nParameters \n  * `nodeCount` : `int`  \n    The number of nodes in the network.\n  * `edges` : list of tuples  \n    A list of the edges in the network.\n  * `directed` : `int`, optional  \n    Whether the network is directed or not.\n  * `perturbationCount` : `int`, optional  \n    The number of perturbations to perform.  (defaults to 25)\n  * `detectionTrials` : `int`, optional  \n    The number of times to perform community  detection for each perturbed network. (defaults to 1)\n  * `rewireResolution` : `int`, optional  \n    The number values points for the rewire  probabilities (from 0 to 1) to calculate  the Trivial Partition Ratio (TPR) curves  and Robustness Modularity.(defaults to 51)\n  * `outputCurves` : `bool`, optional  \nWhether to save the TPR and DL curves. (defaults to False)\n  * `showProgress` : `bool`, optional  \nShows a progress bar if enabled.  (defaults to True)\n  * `useMultiprocessing`: `bool`, optional  \n    Uses parallel processing to calculate  Rmodularity.  (defaults to True)\n\nReturns \n  * `float` if `outputCurves` is `False`  \n    The Robustness Modularity of the network.\n  * `(float, np.array dim=1, np.array dim=1, np.array dim=2, np.array dim=2)` if `outputCurves` is `True`  \n    Returns a tuple of 4 values containing the Robustness Modularity, the rewire probabilities, the TPR curves, and the Description lenghts for the detected and trivial partitions. \n\n\n---\n\n### \u003ckbd\u003efunction\u003c/kbd\u003e `modularityDifference`\n\n```python\nmodularityDifference(\n    nodeCount,\n    edges,\n    directed=False,\n    detectionTrials=100,\n    nullmodelCount=100,\n    detectionTrialsNullModel=10,\n    showProgress=True,\n    useMultiprocessing=True\n)\n```\n\nComputes the Modularity Difference of a network. \n\nParameters \n  * `nodeCount` : `int`  \n    The number of nodes in the network.\n  * `edges` : list of tuples  \n    A list of the edges in the network.\n  * `directed` : `int`, optional  \n    Whether the network is directed or not.\n  * `detectionTrials` : `int`, optional  \n    The number of times to perform community detection for the input network  (defaults to 100)\n  * `nullmodelCount` : `int`, optional  \n    The number of realizations of the null-model (configuration model) used to calculate the null-model modularity. (defaults to 100)\n  * `detectionTrialsNullModel` : `int`, optional  \n    The number of times to perform community detection for each perturbed network  (defaults to 10)\n  * `showProgress` : `bool`, optional  \nShows a progress bar if enabled.  (defaults to True)\n  * `useMultiprocessing`: `bool`, optional  \n    Uses parallel processing to calculate  Rmodularity.  (defaults to True)\n\nReturns \n  * `float`  \n    The Modularity Difference of the network.\n    \n\n### \u003ckbd\u003efunction\u003c/kbd\u003e `informationModularity`\n\n```python\ninformationModularity(nodeCount, edges, directed=False)\n```\n\nComputes the Information Modularity of a network. \n\nParameters \n  * `nodeCount` : `int`  \n    The number of nodes in the network.\n  * `edges` : list of tuples  \n    A list of the edges in the network.\n  * `directed` : `int`, optional  \n    Whether the network is directed or not.\n\nReturns \n  * `float`  \n    The Information Modularity of the network.\n    \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffilipinascimento%2Frmodularity","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffilipinascimento%2Frmodularity","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffilipinascimento%2Frmodularity/lists"}