diff --git a/.github/workflows/build_wheels.yml b/.github/workflows/build_wheels.yml index 8f5445a..276e34e 100644 --- a/.github/workflows/build_wheels.yml +++ b/.github/workflows/build_wheels.yml @@ -20,7 +20,7 @@ jobs: outputs: message: ${{ steps.commit_message.outputs.message }} steps: - - name: Checkout pyseldon + - name: Checkout pyseldonlib uses: actions/checkout@v4 # Gets the correct commit message for pull request with: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7ca237f..69575f8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,4 +9,4 @@ repos: rev: v0.0.241 hooks: - id: ruff - files: ^tests/|^pyseldon/ \ No newline at end of file + files: ^tests/|^pyseldonlib/ \ No newline at end of file diff --git a/Project.md b/Project.md index 83a251f..9752a4b 100644 --- a/Project.md +++ b/Project.md @@ -1,6 +1,6 @@ -# PySeldon -![pyseldon](https://raw.githubusercontent.com/User-DK/pyseldon/main/res/logotext.png) -PySeldon is a Python Package for Opinion Dynamics Simulation, an extension of the [`Seldon Framework`](https://github.com/seldon-code/seldon). It provides: +# PySeldonlib +![pyseldonlib](https://raw.githubusercontent.com/User-DK/pyseldon/main/res/logotext.png) +PySeldonlib is a Python Package for Opinion Dynamics Simulation, an extension of the [`Seldon Framework`](https://github.com/seldon-code/seldon). It provides: - Tools for the simulation of various Opinion Dynamics Models like the classical DeGroot Model, Deffuant Model, Activity Driven Model, etc. - Tools to create, manipulate, and study complex networks which are either randomly generated or provided by the user. @@ -39,15 +39,15 @@ We can conclude that the agents have reached a consensus after the simulation. ### Usage ```python -import pyseldon +import pyseldonlib pyseldonlib.run_simulation_from_config_file(config_file_path = '/path/to/config/file') ``` ```python -import pyseldon +import pyseldonlib -model = pyseldon.DeGroot_Model(max_iterations=1000, +model = pyseldonlib.DeGroot_Model(max_iterations=1000, convergence_tol=1e-6, rng_seed=120, other_settings=other_settings) diff --git a/README.md b/README.md index 2479c4e..ddb0dc8 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# pyseldon +# pyseldonlib ![](https://raw.githubusercontent.com/User-DK/pyseldon/main/res/logotext.png) ## Python bindings for the Seldon framework diff --git a/bindings_package/__init__.py b/bindings_package/__init__.py index f40a026..ea0c4b9 100644 --- a/bindings_package/__init__.py +++ b/bindings_package/__init__.py @@ -1 +1 @@ -from pyseldon import seldoncore \ No newline at end of file +from pyseldonlib import seldoncore \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py index 8288e7e..5feda68 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,9 +1,9 @@ import os import sys -sys.path.insert(0, os.path.abspath('../pyseldon')) +sys.path.insert(0, os.path.abspath('../pyseldonlib')) -project = 'pyseldon' +project = 'pyseldonlib' copyright = '2024, PySeldon Developers' author = 'Amrita Goswami, Daivik Karbhari, Moritz Sallermann, Rohit Goswami' release = '1.0' @@ -51,10 +51,10 @@ html_theme_options = { "show_toc_level": 2, "icon_links": [ - {"name": "Home Page", "url": "https://github.com/seldon-code/pyseldon", "icon": "fas fa-home"}, + {"name": "Home Page", "url": "https://github.com/seldon-code/pyseldonlib", "icon": "fas fa-home"}, { "name": "GitHub", - "url": "https://github.com/seldon-code/pyseldon", + "url": "https://github.com/seldon-code/pyseldonlib", "icon": "fab fa-github-square", }, ], diff --git a/docs/examples/degrootmodel.ipynb b/docs/examples/degrootmodel.ipynb index be2be3d..8e6282c 100644 --- a/docs/examples/degrootmodel.ipynb +++ b/docs/examples/degrootmodel.ipynb @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "import pyseldon\n", + "import pyseldonlib\n", "import pathlib\n", "import shutil" ] @@ -38,7 +38,7 @@ "metadata": {}, "outputs": [], "source": [ - "other_settings = pyseldon.Other_Settings(n_output_agents=10,\n", + "other_settings = pyseldonlib.Other_Settings(n_output_agents=10,\n", " n_output_network= None, \n", " print_progress= True, \n", " output_initial=True, \n", @@ -106,7 +106,7 @@ } ], "source": [ - "model = pyseldon.DeGroot_Model(max_iterations=1000,\n", + "model = pyseldonlib.DeGroot_Model(max_iterations=1000,\n", " convergence_tol=1e-6,\n", " rng_seed=120, \n", " other_settings=other_settings)\n", diff --git a/docs/examples/network.ipynb b/docs/examples/network.ipynb index a71817c..40cd80a 100644 --- a/docs/examples/network.ipynb +++ b/docs/examples/network.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Example Usage of the Network Class from the pyseldon Package" + "# Example Usage of the Network Class from the pyseldonlib Package" ] }, { @@ -14,7 +14,7 @@ "outputs": [], "source": [ "# Import necessary modules\n", - "import pyseldon" + "import pyseldonlib" ] }, { @@ -24,7 +24,7 @@ "outputs": [], "source": [ "# Initialize the Network object\n", - "network = pyseldon.Network(\n", + "network = pyseldonlib.Network(\n", " model_string=\"DeGroot\",\n", " neighbour_list=[[1, 2], [0, 2], [0, 1], [4], [3]],\n", " weight_list=[[0.5, 0.5], [0.5, 0.5], [0.5, 0.5], [1], [1]],\n", diff --git a/docs/index.rst b/docs/index.rst index 3c42817..83f05de 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,12 +1,12 @@ .. image:: ../res/PySeldon_1.svg :align: left :width: 800px - :alt: PySeldon + :alt: PySeldonlib -PySeldon Documentation -======================= +PySeldonlib Documentation +========================= -Welcome to the **PySeldon** Documentation. PySeldon is a Python Package for Opinion Dynamics Simulation, an extension of the `Seldon Framework `_. +Welcome to the **PySeldonlib** Documentation. PySeldonlib is a Python Package for Opinion Dynamics Simulation, an extension of the `Seldon Framework `_. It provides: - tools for simulation of various Opinion Dynamics Models like the classical DeGroot Model, Deffuant Model, Activity Driven Model, etc. diff --git a/docs/install.rst b/docs/install.rst index c2a41a4..06b07f4 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -7,7 +7,7 @@ You can install the package from PYPI using `pip`: .. code-block:: bash - $ pip install pyseldon + $ pip install pyseldonlib From Source diff --git a/docs/quickstart.rst b/docs/quickstart.rst index 3633a2e..1a48f04 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -1,7 +1,7 @@ Quick Start Guide ================= -This guide will help you get started with the basics of using the `pyseldon` package. +This guide will help you get started with the basics of using the `pyseldonlib` package. Installation ------------ @@ -16,9 +16,9 @@ Usage .. code-block:: python - import pyseldon + import pyseldonlib - pyseldon.run_simulation_from_config_file( + pyseldonlib.run_simulation_from_config_file( config_file_path="path/to/config.toml", agent_file_path="path/to/agent.csv", network_file_path="path/to/network.csv", diff --git a/docs/source/reference/activitydriven.rst b/docs/source/reference/activitydriven.rst index 29f8bde..81ec138 100644 --- a/docs/source/reference/activitydriven.rst +++ b/docs/source/reference/activitydriven.rst @@ -1,7 +1,7 @@ Activity Driven Model ===================== -.. automodule:: pyseldon.ActivityDrivenModel +.. automodule:: pyseldonlib.ActivityDrivenModel :members: True :undoc-members: True :show-inheritance: True diff --git a/docs/source/reference/deffuant.rst b/docs/source/reference/deffuant.rst index 487b093..46fd23a 100644 --- a/docs/source/reference/deffuant.rst +++ b/docs/source/reference/deffuant.rst @@ -1,7 +1,7 @@ Deffuant Model ============== -.. automodule:: pyseldon.DeffuantModel +.. automodule:: pyseldonlib.DeffuantModel :members: True :undoc-members: True :show-inheritance: True diff --git a/docs/source/reference/deffuantvector.rst b/docs/source/reference/deffuantvector.rst index 03ecbed..1b85b84 100644 --- a/docs/source/reference/deffuantvector.rst +++ b/docs/source/reference/deffuantvector.rst @@ -1,7 +1,7 @@ Deffuant Vector Model ====================== -.. automodule:: pyseldon.DeffuantVectorModel +.. automodule:: pyseldonlib.DeffuantVectorModel :members: True :undoc-members: True :show-inheritance: True diff --git a/docs/source/reference/degroot.rst b/docs/source/reference/degroot.rst index 7d729f4..be9c2ad 100644 --- a/docs/source/reference/degroot.rst +++ b/docs/source/reference/degroot.rst @@ -1,7 +1,7 @@ DeGroot Model ============= -.. automodule:: pyseldon.DeGrootModel +.. automodule:: pyseldonlib.DeGrootModel :members: True :undoc-members: True :show-inheritance: True diff --git a/docs/source/reference/index.rst b/docs/source/reference/index.rst index b1c4c97..8543813 100644 --- a/docs/source/reference/index.rst +++ b/docs/source/reference/index.rst @@ -9,4 +9,5 @@ This is the class and function reference of PySeldon. introduction models network + util packagereference diff --git a/docs/source/reference/inertial.rst b/docs/source/reference/inertial.rst index 9f6bfa7..104164f 100644 --- a/docs/source/reference/inertial.rst +++ b/docs/source/reference/inertial.rst @@ -1,7 +1,7 @@ Activity Driven Inertial Model ============================== -.. automodule:: pyseldon.InertialModel +.. automodule:: pyseldonlib.InertialModel :members: True :undoc-members: True :show-inheritance: True diff --git a/docs/source/reference/models.rst b/docs/source/reference/models.rst index 42801f1..b8f86a5 100644 --- a/docs/source/reference/models.rst +++ b/docs/source/reference/models.rst @@ -1,6 +1,6 @@ Models ====== -The following models are available in the `pyseldon` package: +The following models are available in the `pyseldonlib` package: .. toctree:: :maxdepth: 4 diff --git a/docs/source/reference/network.rst b/docs/source/reference/network.rst index 758ff2e..374e7de 100644 --- a/docs/source/reference/network.rst +++ b/docs/source/reference/network.rst @@ -1,7 +1,7 @@ network ======= -.. automodule:: pyseldon.network +.. automodule:: pyseldonlib.network :members: True :undoc-members: True :show-inheritance: True diff --git a/docs/source/reference/packagereference.rst b/docs/source/reference/packagereference.rst index 91773b7..1bcbd2d 100644 --- a/docs/source/reference/packagereference.rst +++ b/docs/source/reference/packagereference.rst @@ -1,7 +1,7 @@ Complete Api Reference ====================== -.. automodule:: pyseldon.__init__ +.. automodule:: pyseldonlib.__init__ :members: True :undoc-members: True :show-inheritance: True diff --git a/docs/source/reference/util.rst b/docs/source/reference/util.rst new file mode 100644 index 0000000..ddcb173 --- /dev/null +++ b/docs/source/reference/util.rst @@ -0,0 +1,8 @@ +util +==== + +.. automodule:: pyseldonlib.utils + :members: True + :undoc-members: True + :show-inheritance: True + :inherited-members: True \ No newline at end of file diff --git a/meson.build b/meson.build index fb8d836..a82663d 100644 --- a/meson.build +++ b/meson.build @@ -1,4 +1,4 @@ -project('pyseldon', 'cpp', +project('pyseldonlib', 'cpp', version: '1.0.0', default_options: ['cpp_std=c++20', 'warning_level=3']) @@ -32,17 +32,19 @@ py.extension_module( py.install_sources( [ - 'pyseldon/__init__.py', - 'pyseldon/_basemodel.py', - 'pyseldon/DeGrootModel.py', - 'pyseldon/DeffuantModel.py', - 'pyseldon/DeffuantVectorModel.py', - 'pyseldon/ActivityDrivenModel.py', - 'pyseldon/InertialModel.py', - 'pyseldon/network.py', - 'pyseldon/_othersettings.py', - 'pyseldon/_run_simulation.py', + 'pyseldonlib/__init__.py', + 'pyseldonlib/_basemodel.py', + 'pyseldonlib/DeGrootModel.py', + 'pyseldonlib/DeffuantModel.py', + 'pyseldonlib/DeffuantVectorModel.py', + 'pyseldonlib/ActivityDrivenModel.py', + 'pyseldonlib/InertialModel.py', + 'pyseldonlib/network.py', + 'pyseldonlib/_othersettings.py', + 'pyseldonlib/_run_simulation.py', + 'pyseldonlib/utils.py', + ], pure: false, # do not install next to compiled extension - subdir: 'pyseldon' + subdir: 'pyseldonlib' ) diff --git a/pyproject.toml b/pyproject.toml index 7d959cf..c969307 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,8 +39,8 @@ classifiers = [ ] [project.urls] -"Source Code" = "https://github.com/seldon-code/pyseldon" -Documentation = "https://seldon-code.github.io/pyseldon" +"Source Code" = "https://github.com/seldon-code/pyseldonlib" +Documentation = "https://seldon-code.github.io/pyseldonlib/" [build-system] requires = ["pybind11","meson-python","setuptools>=42", "wheel", "setuptools_scm"] diff --git a/pyseldon/ActivityDrivenModel.py b/pyseldonlib/ActivityDrivenModel.py similarity index 99% rename from pyseldon/ActivityDrivenModel.py rename to pyseldonlib/ActivityDrivenModel.py index e1bc2c1..5767961 100644 --- a/pyseldon/ActivityDrivenModel.py +++ b/pyseldonlib/ActivityDrivenModel.py @@ -9,7 +9,6 @@ Temporal Dynamics ----------------- - max_iterations: Limits the total number of simulation steps. If set to None, the model runs indefinitely, allowing for long-term analysis of opinion evolution. @@ -20,7 +19,6 @@ Agent Behavior and Interaction ------------------------------ - m: Determines how many agents an active agent interacts with during each time step. Influences the rate of opinion spreading; higher values mean more interactions and potentially faster consensus or polarization. @@ -47,14 +45,12 @@ Social Context and Controversialness ------------------------------------ - alpha: Controls the degree of controversialness of the issue being simulated. A higher alpha can lead to more polarized opinions, as agents might have stronger reactions to the issue. Bots and External Influence --------------------------- - n_bots: Specifies the number of bots in the simulation, which are fixed in their opinions. Bots influence the network without being influenced, potentially driving opinion shifts or reinforcing certain views. @@ -65,7 +61,6 @@ Reluctance and Activity Correlation ----------------------------------- - use_reluctances: Activates the feature where agents have a reluctance to change their opinions. Adds complexity by simulating resistance to change, affecting how quickly or slowly opinions evolve. @@ -80,7 +75,7 @@ Example: --------- ->>> from pyseldon import Activity_Driven_Model +>>> from pyseldonlib import Activity_Driven_Model >>> # Create the Activity Driven Model >>> model = Activity_Driven_Model(max_iterations=1000, convergence_tol=1e-6) >>> # Run the simulation diff --git a/pyseldon/DeGrootModel.py b/pyseldonlib/DeGrootModel.py similarity index 99% rename from pyseldon/DeGrootModel.py rename to pyseldonlib/DeGrootModel.py index 48dce53..3267923 100644 --- a/pyseldon/DeGrootModel.py +++ b/pyseldonlib/DeGrootModel.py @@ -7,7 +7,6 @@ Key features ------------ - Opinion Averaging: Agents update their opinions based on the average opinions of their neighbors, fostering convergence and consensus. @@ -21,7 +20,7 @@ Example: --------- ->>> from pyseldon import DeGroot_Model +>>> from pyseldonlib import DeGroot_Model >>> # Create the DeGroot Model >>> model = DeGroot_Model(max_iterations=1000, convergence_tol=1e-6) >>> # Run the simulation diff --git a/pyseldon/DeffuantModel.py b/pyseldonlib/DeffuantModel.py similarity index 99% rename from pyseldon/DeffuantModel.py rename to pyseldonlib/DeffuantModel.py index 0dab0ff..7b8fee8 100644 --- a/pyseldon/DeffuantModel.py +++ b/pyseldonlib/DeffuantModel.py @@ -3,7 +3,6 @@ Model Dynamics -------------- - Homophily Threshold: If the difference in opinions between two interacting agents is less than this threshold, they will update their opinions towards each other. This process leads to opinion convergence or clustering depending on the value of the threshold. @@ -15,7 +14,7 @@ Example: --------- ->>> from pyseldon import Deffuant_Model +>>> from pyseldonlib import Deffuant_Model >>> # Create the Deffuant Model >>> deffuant = Deffuant_Model(max_iterations=1000, homophily_threshold=0.2, mu=0.5) >>> # Run the simulation diff --git a/pyseldon/DeffuantVectorModel.py b/pyseldonlib/DeffuantVectorModel.py similarity index 98% rename from pyseldon/DeffuantVectorModel.py rename to pyseldonlib/DeffuantVectorModel.py index d1e377a..509addf 100644 --- a/pyseldon/DeffuantVectorModel.py +++ b/pyseldonlib/DeffuantVectorModel.py @@ -3,7 +3,6 @@ Model Dynamics -------------- - Binary Opinions: Each opinion is represented as a binary vector, where the values are restricted to 0 or 1. The interaction and adjustment process involves comparing these vectors and updating them based on the Homophily Threshold. @@ -14,7 +13,7 @@ Example: --------- ->>> from pyseldon import Deffuant_Vector_Model +>>> from pyseldonlib import Deffuant_Vector_Model >>> # Create the Deffuant Vector Model >>> deffuant = Deffuant_Vector_Model(max_iterations=1000, homophily_threshold=0.2, mu=0.5) >>> # Run the simulation diff --git a/pyseldon/InertialModel.py b/pyseldonlib/InertialModel.py similarity index 99% rename from pyseldon/InertialModel.py rename to pyseldonlib/InertialModel.py index 2c7ba1c..f9a45e9 100644 --- a/pyseldon/InertialModel.py +++ b/pyseldonlib/InertialModel.py @@ -9,7 +9,6 @@ Temporal Dynamics ----------------- - max_iterations: Limits the total number of simulation steps. If set to None, the model runs indefinitely, allowing for long-term analysis of opinion evolution. @@ -20,7 +19,6 @@ Agent Behavior and Interaction ------------------------------ - m: Determines how many agents an active agent interacts with during each time step. Influences the rate of opinion spreading; higher values mean more interactions and potentially faster consensus or polarization. @@ -47,14 +45,12 @@ Social Context and Controversialness ------------------------------------ - alpha: Controls the degree of controversialness of the issue being simulated. A higher alpha can lead to more polarized opinions, as agents might have stronger reactions to the issue. Bots and External Influence --------------------------- - n_bots: Specifies the number of bots in the simulation, which are fixed in their opinions. Bots influence the network without being influenced, potentially driving opinion shifts or reinforcing certain views. @@ -65,7 +61,6 @@ Reluctance and Activity Correlation ----------------------------------- - use_reluctances: Activates the feature where agents have a reluctance to change their opinions. Adds complexity by simulating resistance to change, affecting how quickly or slowly opinions evolve. @@ -84,7 +79,7 @@ Example: --------- ->>> from pyseldon import Inertial_Model +>>> from pyseldonlib import Inertial_Model >>> # Create the Inertial Model >>> model = Inertial_Model(max_iterations=1000, convergence_tol=1e-6) >>> # Run the simulation diff --git a/pyseldon/__init__.py b/pyseldonlib/__init__.py similarity index 89% rename from pyseldon/__init__.py rename to pyseldonlib/__init__.py index 1e991ab..cf22de2 100644 --- a/pyseldon/__init__.py +++ b/pyseldonlib/__init__.py @@ -1,4 +1,4 @@ -"""This module provides the main interface to the pyseldon package. +"""This module provides the main interface to the pyseldonlib package. It includes the following classes and functions: - DeGrootModel @@ -20,7 +20,8 @@ from .InertialModel import Inertial_Model from .ActivityDrivenModel import Activity_Driven_Model from ._othersettings import Other_Settings -from .network import * +from .utils import * +from .network import Network from ._run_simulation import ( run_simulation_from_config_file, run_simulation_from_options, diff --git a/pyseldon/_basemodel.py b/pyseldonlib/_basemodel.py similarity index 100% rename from pyseldon/_basemodel.py rename to pyseldonlib/_basemodel.py diff --git a/pyseldon/_othersettings.py b/pyseldonlib/_othersettings.py similarity index 100% rename from pyseldon/_othersettings.py rename to pyseldonlib/_othersettings.py diff --git a/pyseldon/_run_simulation.py b/pyseldonlib/_run_simulation.py similarity index 100% rename from pyseldon/_run_simulation.py rename to pyseldonlib/_run_simulation.py diff --git a/pyseldonlib/network.py b/pyseldonlib/network.py new file mode 100644 index 0000000..af048fe --- /dev/null +++ b/pyseldonlib/network.py @@ -0,0 +1,298 @@ +"""The network module contains the Network class""" + +from bindings import seldoncore +import logging +import bindings + +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + +class Network: + def __init__( + self, + model_string: str = None, + n_agents: int = None, + agents: int = None, + neighbour_list: list[int] = [], + weight_list: list[float] = [], + direction: str = "Incoming", + ): + """ + The Network class supports various network models: + + 1. DeGroot: The DeGroot network. (opinions only) + 2. Deffuant: The Deffuant network. (opinions only) + 3. DeffuantVector: The DeffuantVector network. (binary vector opinions) + 4. ActivityDriven: The ActivityDriven network. (opinions, activity, and reluctance) + 5. Inertial: The Inertial network. (opinions, activity, reluctance, and velocity) + 6. Float: The float network. (just nodes and edges) + + The Network class can be instantiated in different ways: + - By providing the model string (compulsory). + 1. By providing the number of agents. + 2. By providing the list of agents. + 3. By providing the list of neighbours, weights, and direction. + 4. Default constructor. + + Parameters + ---------- + model_string : str, optional + The model string. Default is None. + n_agents : int, optional + The number of agents. Default is None. + agents : list[int], optional + The list of agents. Default is None. + neighbour_list : list[int], optional + The list of neighbours. Default is an empty list. + weight_list : list[float], optional + The list of weights. Default is an empty list. + direction : str, optional + The direction of the network. Default is "Incoming". + """ + + if model_string == "DeGroot" or model_string == "Deffuant": + if n_agents: + self.network = seldoncore.SimpleAgentNetwork(n_agents) + elif agents: + self.network = seldoncore.SimpleAgentNetwork(agents) + elif neighbour_list and weight_list and direction: + if direction == "Incoming" or direction == "Outgoing": + self.network = seldoncore.SimpleAgentNetwork( + neighbour_list, weight_list, direction + ) + else: + TypeError("Direction allowed values are 'Incoming' or 'Outgoing'") + else: + self.network = seldoncore.SimpleAgentNetwork() + + elif model_string == "DeffuantVector": + if n_agents: + self.network = seldoncore.DiscreteVectorAgentNetwork(n_agents) + elif agents: + self.network = seldoncore.DiscreteVectorAgentNetwork(agents) + elif neighbour_list and weight_list and direction: + if direction == "Incoming" or direction == "Outgoing": + self.network = seldoncore.DiscreteVectorAgentNetwork( + neighbour_list, weight_list, direction + ) + else: + TypeError("Direction allowed values are 'Incoming' or 'Outgoing'") + else: + self.network = seldoncore.DiscreteVectorAgentNetwork() + + elif model_string == "ActivityDriven": + if n_agents: + self.network = seldoncore.ActivityDrivenAgentNetwork(n_agents) + elif agents: + self.network = seldoncore.ActivityDrivenAgentNetwork(agents) + elif neighbour_list and weight_list and direction: + if direction == "Incoming" or direction == "Outgoing": + self.network = seldoncore.ActivityDrivenAgentNetwork( + neighbour_list, weight_list, direction + ) + else: + TypeError("Direction allowed values are 'Incoming' or 'Outgoing'") + else: + self.network = seldoncore.ActivityDrivenAgentNetwork() + + elif model_string == "ActivityDrivenInertial" or model_string == "Inertial": + if n_agents: + self.network = seldoncore.InertialAgentNetwork(n_agents) + elif agents: + self.network = seldoncore.InertialAgentNetwork(agents) + elif neighbour_list and weight_list and direction: + if direction == "Incoming" or direction == "Outgoing": + self.network = seldoncore.InertialAgentNetwork( + neighbour_list, weight_list, direction + ) + else: + TypeError("Direction allowed values are 'Incoming' or 'Outgoing'") + else: + self.network = seldoncore.InertialAgentNetwork() + + else: + logger.warning( + "This is a float type network that can't be used for the simulation as it doesn't contain any agents and their data like opinions, etc." + ) + if n_agents: + self.network = seldoncore.Network(n_agents) + elif agents: + self.network = seldoncore.Network(agents) + elif neighbour_list and weight_list and direction: + if direction == "Incoming" or direction == "Outgoing": + self.network = seldoncore.Network( + neighbour_list, weight_list, direction + ) + else: + TypeError("Direction allowed values are 'Incoming' or 'Outgoing'") + else: + self.network = seldoncore.Network() + + @property + def n_agents(self): + """The number of nodes/agents in the network.""" + return self.network.n_agents() + + def n_edges(self, agent_idx: int): + """The number of edges going out/coming in at `agent_idx` in the network. + + Parameters + ----------- + agent_idx : int + The index of the agent. If not provided, the total number of edges in the network is returned. + + """ + return self.network.n_edges(agent_idx) + + @property + def get_direction(self): + """The direction of the network.""" + return self.network.direction() + + @property + def strongly_connected_components(self): + """The strongly connected components of the network. + + Returns + list: The strongly connected components of the network. + """ + return self.network.strongly_connected_components() + + def get_neighbours(self, index: int): + """The neighbours of the node/agent in the network. + + Parameters + ----------- + index : int + The index of the agent. + + """ + return self.network.get_neighbours(index) + + def get_weights(self, index: int): + """The weights of the agent. + + Parameters + ----------- + index : int + The index of the agent. + + """ + + return self.network.get_weights(index) + + def set_weights(self, agent_idx: int, weights: list): + """Set the weights of the agent. + + Parameters + ----------- + index : int + The index of the agent. + weights : list[float] + The weights of the agent. + + """ + + return self.network.set_weights(agent_idx, weights) + + def set_neighbours_and_weights( + self, agent_idx: int, buffer_neighbours: list[int], buffer_weights: list[float] + ): + """Sets the neighbour indices and weights at agent_idx + + Parameters + ----------- + agent_idx : int + The index of the agent. + buffer_neighbours : list[int] + The list of neighbours. + buffer_weights : list[float] + The list of weights. + + """ + return self.network.set_neighbours_and_weights( + agent_idx, buffer_neighbours, buffer_weights + ) + + def set_neighbours_and_weights( + self, agent_idx: int, buffer_neighbours: list[int], weight: float + ): + """Sets the neighbour indices and sets the weight to a constant value at agent_idx in the network. + + Parameters + ----------- + agent_idx : int + The index of the agent. + buffer_neighbours : list[int] + The list of neighbours. + weight : float + The weight of the agent. + + """ + return self.network.set_neighbours_and_weights( + agent_idx, buffer_neighbours, weight + ) + + def push_back_neighbour_and_weight( + self, agent_idx_i: int, agent_idx_j: int, weight: float + ): + """Adds an edge between agent_idx_i and agent_idx_j with weight w + + Parameters + ------------ + agent_idx_i : int + The index of the agent. + agent_idx_j : int + The index of the agent. + weight : float + The weight of the agent. + + """ + return self.network.push_back_neighbour_and_weight( + agent_idx_i, agent_idx_j, weight + ) + + @property + def transpose(self): + """Transposes the network, without switching the direction flag (expensive). + + Example: + -------- + N(inc) -> N(inc)^T + + """ + return self.network.transpose() + + @property + def toggle_incoming_outgoing(self): + """Switches the direction flag *without* transposing the network (expensive) + + Example: + -------- + N(inc) -> N(out) + + """ + + return self.network.toggle_incoming_outgoing() + + @property + def switch_direction_flag(self): + """Only switches the direction flag. This effectively transposes the network and, simultaneously, changes its representation. + + Example: + -------- + N(inc) -> N^T(out) + + """ + return self.network.switch_direction_flag() + + @property + def remove_double_counting(self): + """Sorts the neighbours by index and removes doubly counted edges by summing the weights of the corresponding edges.""" + return self.network.remove_double_counting() + + @property + def clear(self): + """Clears the network.""" + + return self.network.clear() \ No newline at end of file diff --git a/pyseldon/network.py b/pyseldonlib/utils.py similarity index 51% rename from pyseldon/network.py rename to pyseldonlib/utils.py index 3c1e7be..e554fa0 100644 --- a/pyseldon/network.py +++ b/pyseldonlib/utils.py @@ -1,4 +1,4 @@ -"""The network module contains the Network class and functions to generate networks and save them to files.""" +"""This module contains functions to generate networks and save them to files.""" from bindings import seldoncore import logging @@ -7,304 +7,6 @@ logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) -class Network: - def __init__( - self, - model_string: str = None, - n_agents: int = None, - agents: int = None, - neighbour_list: list[int] = [], - weight_list: list[float] = [], - direction: str = "Incoming", - ): - """ - Initialize the Network object. - - There are six types of networks that can be created using this class: - 1. DeGroot: The DeGroot network. (opinions only) - 2. Deffuant: The Deffuant network. (opinions only) - 3. DeffuantVector: The DeffuantVector network. (binary vector opinions) - 4. ActivityDriven: The ActivityDriven network. (opinions, activity, and reluctance) - 5. Inertial: The Inertial network. (opinions, activity, reluctance, and velocity) - 6. Float: The float network. (just nodes and edges) - - Also, it can be instantiated in different ways: - - model_string (str): Is compulsory, the model string. - 1. By providing the number of agents. - 2. By providing the list of agents. - 3. By providing the list of neighbours, weights, and direction. - 4. Default constructor. - - Parameters - ----------- - model_string : str, default=None - The model string. - - n_agents : int, default=None - The number of agents. - - agents : list[int], default=None - The list of agents. - - neighbour_list : list[int], default=[] - The list of neighbours. - - weight_list : list[float], default=[] - The list of weights. - - direction : str - The direction of the network. - - """ - - if model_string == "DeGroot" or model_string == "Deffuant": - if n_agents: - self.network = seldoncore.SimpleAgentNetwork(n_agents) - elif agents: - self.network = seldoncore.SimpleAgentNetwork(agents) - elif neighbour_list and weight_list and direction: - if direction == "Incoming" or direction == "Outgoing": - self.network = seldoncore.SimpleAgentNetwork( - neighbour_list, weight_list, direction - ) - else: - TypeError("Direction allowed values are 'Incoming' or 'Outgoing'") - else: - self.network = seldoncore.SimpleAgentNetwork() - - elif model_string == "DeffuantVector": - if n_agents: - self.network = seldoncore.DiscreteVectorAgentNetwork(n_agents) - elif agents: - self.network = seldoncore.DiscreteVectorAgentNetwork(agents) - elif neighbour_list and weight_list and direction: - if direction == "Incoming" or direction == "Outgoing": - self.network = seldoncore.DiscreteVectorAgentNetwork( - neighbour_list, weight_list, direction - ) - else: - TypeError("Direction allowed values are 'Incoming' or 'Outgoing'") - else: - self.network = seldoncore.DiscreteVectorAgentNetwork() - - elif model_string == "ActivityDriven": - if n_agents: - self.network = seldoncore.ActivityDrivenAgentNetwork(n_agents) - elif agents: - self.network = seldoncore.ActivityDrivenAgentNetwork(agents) - elif neighbour_list and weight_list and direction: - if direction == "Incoming" or direction == "Outgoing": - self.network = seldoncore.ActivityDrivenAgentNetwork( - neighbour_list, weight_list, direction - ) - else: - TypeError("Direction allowed values are 'Incoming' or 'Outgoing'") - else: - self.network = seldoncore.ActivityDrivenAgentNetwork() - - elif model_string == "ActivityDrivenInertial" or model_string == "Inertial": - if n_agents: - self.network = seldoncore.InertialAgentNetwork(n_agents) - elif agents: - self.network = seldoncore.InertialAgentNetwork(agents) - elif neighbour_list and weight_list and direction: - if direction == "Incoming" or direction == "Outgoing": - self.network = seldoncore.InertialAgentNetwork( - neighbour_list, weight_list, direction - ) - else: - TypeError("Direction allowed values are 'Incoming' or 'Outgoing'") - else: - self.network = seldoncore.InertialAgentNetwork() - - else: - logger.warning( - "This is a float type network that can't be used for the simulation as it doesn't contain any agents and their data like opinions, etc." - ) - if n_agents: - self.network = seldoncore.Network(n_agents) - elif agents: - self.network = seldoncore.Network(agents) - elif neighbour_list and weight_list and direction: - if direction == "Incoming" or direction == "Outgoing": - self.network = seldoncore.Network( - neighbour_list, weight_list, direction - ) - else: - TypeError("Direction allowed values are 'Incoming' or 'Outgoing'") - else: - self.network = seldoncore.Network() - - @property - def n_agents(self): - """The number of nodes/agents in the network.""" - return self.network.n_agents() - - def n_edges(self, agent_idx: int): - """The number of edges going out/coming in at `agent_idx` in the network. - - Parameters - ----------- - agent_idx : int - The index of the agent. If not provided, the total number of edges in the network is returned. - - """ - return self.network.n_edges(agent_idx) - - @property - def get_direction(self): - """The direction of the network.""" - return self.network.direction() - - @property - def strongly_connected_components(self): - """The strongly connected components of the network. - - Returns - list: The strongly connected components of the network. - """ - return self.network.strongly_connected_components() - - def get_neighbours(self, index: int): - """The neighbours of the node/agent in the network. - - Parameters - ----------- - index : int - The index of the agent. - - """ - return self.network.get_neighbours(index) - - def get_weights(self, index: int): - """The weights of the agent. - - Parameters - ----------- - index : int - The index of the agent. - - """ - - return self.network.get_weights(index) - - def set_weights(self, agent_idx: int, weights: list): - """Set the weights of the agent. - - Parameters - ----------- - index : int - The index of the agent. - weights : list[float] - The weights of the agent. - - """ - - return self.network.set_weights(agent_idx, weights) - - def set_neighbours_and_weights( - self, agent_idx: int, buffer_neighbours: list[int], buffer_weights: list[float] - ): - """Sets the neighbour indices and weights at agent_idx - - Parameters - ----------- - agent_idx : int - The index of the agent. - buffer_neighbours : list[int] - The list of neighbours. - buffer_weights : list[float] - The list of weights. - - """ - return self.network.set_neighbours_and_weights( - agent_idx, buffer_neighbours, buffer_weights - ) - - def set_neighbours_and_weights( - self, agent_idx: int, buffer_neighbours: list[int], weight: float - ): - """Sets the neighbour indices and sets the weight to a constant value at agent_idx in the network. - - Parameters - ----------- - agent_idx : int - The index of the agent. - buffer_neighbours : list[int] - The list of neighbours. - weight : float - The weight of the agent. - - """ - return self.network.set_neighbours_and_weights( - agent_idx, buffer_neighbours, weight - ) - - def push_back_neighbour_and_weight( - self, agent_idx_i: int, agent_idx_j: int, weight: float - ): - """Adds an edge between agent_idx_i and agent_idx_j with weight w - - Parameters - ------------ - agent_idx_i : int - The index of the agent. - agent_idx_j : int - The index of the agent. - weight : float - The weight of the agent. - - """ - return self.network.push_back_neighbour_and_weight( - agent_idx_i, agent_idx_j, weight - ) - - @property - def transpose(self): - """Transposes the network, without switching the direction flag (expensive). - - Example: - -------- - N(inc) -> N(inc)^T - - """ - return self.network.transpose() - - @property - def toggle_incoming_outgoing(self): - """Switches the direction flag *without* transposing the network (expensive) - - Example: - -------- - N(inc) -> N(out) - - """ - - return self.network.toggle_incoming_outgoing() - - @property - def switch_direction_flag(self): - """Only switches the direction flag. This effectively transposes the network and, simultaneously, changes its representation. - - Example: - -------- - N(inc) -> N^T(out) - - """ - return self.network.switch_direction_flag() - - @property - def remove_double_counting(self): - """Sorts the neighbours by index and removes doubly counted edges by summing the weights of the corresponding edges.""" - return self.network.remove_double_counting() - - @property - def clear(self): - """Clears the network.""" - - return self.network.clear() - - def generate_n_connections(model_string, n_agents:int, n_connections:int, self_interaction:bool= False, rng_seed:int=None): """ Generate n_connections Network for n_agents. diff --git a/tests/seldoncore/test.py b/tests/seldoncore/test.py index 1a72407..ce2a388 100644 --- a/tests/seldoncore/test.py +++ b/tests/seldoncore/test.py @@ -1,6 +1,6 @@ import pathlib as ptlb import pytest -import pyseldon +import pyseldonlib import shutil @@ -21,7 +21,7 @@ def test_run_simulation(capsys): # Test with output directory and config with capsys.disabled(): - pyseldon.seldoncore.run_simulation( + pyseldonlib.seldoncore.run_simulation( config_file_path=config_file, output_dir_path=output_dir1 ) assert ptlb.Path(output_dir1).exists() @@ -29,7 +29,7 @@ def test_run_simulation(capsys): # Test with network file with capsys.disabled(): - pyseldon.seldoncore.run_simulation( + pyseldonlib.seldoncore.run_simulation( config_file_path=config_file, network_file_path=network_file, output_dir_path=output_dir2, @@ -41,14 +41,14 @@ def test_run_simulation(capsys): invalid_network_file = str(ptlb.Path(base_dir, "tests/res/network/net.txt")) with pytest.raises(RuntimeError): with capsys.disabled(): - pyseldon.seldoncore.run_simulation( + pyseldonlib.seldoncore.run_simulation( config_file_path=config_file, network_file_path=invalid_network_file ) # Test with invalid config file with pytest.raises(RuntimeError): with capsys.disabled(): - pyseldon.seldoncore.run_simulation(config_file_path=invalid_config_file) + pyseldonlib.seldoncore.run_simulation(config_file_path=invalid_config_file) if ptlb.Path(output_dir).exists(): shutil.rmtree(output_dir) @@ -59,14 +59,14 @@ def test_run_simulation(capsys): def test_settings(): - degroot_settings = pyseldon.seldoncore.DeGrootSettings() - output_settings = pyseldon.seldoncore.OutputSettings() - deffuant_settings = pyseldon.seldoncore.DeffuantSettings() - activitydriven_settings = pyseldon.seldoncore.ActivityDrivenSettings() + degroot_settings = pyseldonlib.seldoncore.DeGrootSettings() + output_settings = pyseldonlib.seldoncore.OutputSettings() + deffuant_settings = pyseldonlib.seldoncore.DeffuantSettings() + activitydriven_settings = pyseldonlib.seldoncore.ActivityDrivenSettings() activitydriveninertial_settings = ( - pyseldon.seldoncore.ActivityDrivenInertialSettings() + pyseldonlib.seldoncore.ActivityDrivenInertialSettings() ) - initial_network_settings = pyseldon.seldoncore.InitialNetworkSettings() + initial_network_settings = pyseldonlib.seldoncore.InitialNetworkSettings() assert degroot_settings is not None assert output_settings is not None @@ -78,10 +78,10 @@ def test_settings(): def test_network(): - degroot_network = pyseldon.seldoncore.SimpleAgentNetwork() - deffuant_network = pyseldon.seldoncore.SimpleAgentNetwork() - activitydriven_network = pyseldon.seldoncore.ActivityAgentNetwork() - activitydriveninertial_network = pyseldon.seldoncore.InertialAgentNetwork() + degroot_network = pyseldonlib.seldoncore.SimpleAgentNetwork() + deffuant_network = pyseldonlib.seldoncore.SimpleAgentNetwork() + activitydriven_network = pyseldonlib.seldoncore.ActivityAgentNetwork() + activitydriveninertial_network = pyseldonlib.seldoncore.InertialAgentNetwork() assert degroot_network is not None assert deffuant_network is not None @@ -90,11 +90,11 @@ def test_network(): def test_simulation_with_simulationOptions(): - degroot_settings = pyseldon.seldoncore.DeGrootSettings() + degroot_settings = pyseldonlib.seldoncore.DeGrootSettings() degroot_settings.max_iterations = 100 - output_settings = pyseldon.seldoncore.OutputSettings() - initial_network_settings = pyseldon.seldoncore.InitialNetworkSettings() - simulation_options = pyseldon.seldoncore.SimulationOptions() + output_settings = pyseldonlib.seldoncore.OutputSettings() + initial_network_settings = pyseldonlib.seldoncore.InitialNetworkSettings() + simulation_options = pyseldonlib.seldoncore.SimulationOptions() simulation_options.output_settings = output_settings simulation_options.model_settings = degroot_settings simulation_options.network_settings = initial_network_settings @@ -103,7 +103,7 @@ def test_simulation_with_simulationOptions(): base_dir = ptlb.Path(__file__).parent.resolve() output_dir = str(base_dir / "outputs/output") - pyseldon.seldoncore.run_simulation( + pyseldonlib.seldoncore.run_simulation( options=simulation_options, output_dir_path=output_dir ) assert ptlb.Path(output_dir).exists() diff --git a/tests/seldoncore/test_activity_driven_settings.py b/tests/seldoncore/test_activity_driven_settings.py index e7725b9..220332d 100644 --- a/tests/seldoncore/test_activity_driven_settings.py +++ b/tests/seldoncore/test_activity_driven_settings.py @@ -1,9 +1,9 @@ -import pyseldon +import pyseldonlib import pytest def test_activity_driven_settings(): - settings = pyseldon.seldoncore.ActivityDrivenSettings() + settings = pyseldonlib.seldoncore.ActivityDrivenSettings() assert settings.max_iterations == None assert settings.dt == 0.01 assert settings.m == 10 diff --git a/tests/seldoncore/test_deffuant_settings.py b/tests/seldoncore/test_deffuant_settings.py index 51ff4ed..8202c9f 100644 --- a/tests/seldoncore/test_deffuant_settings.py +++ b/tests/seldoncore/test_deffuant_settings.py @@ -1,9 +1,9 @@ -import pyseldon +import pyseldonlib import pytest def test_deffuant_settings(): - settings = pyseldon.seldoncore.DeffuantSettings() + settings = pyseldonlib.seldoncore.DeffuantSettings() assert settings.max_iterations == None assert settings.homophily_threshold == 0.2 assert settings.mu == 0.5 diff --git a/tests/seldoncore/test_degroot_settings.py b/tests/seldoncore/test_degroot_settings.py index d8d2314..d863101 100644 --- a/tests/seldoncore/test_degroot_settings.py +++ b/tests/seldoncore/test_degroot_settings.py @@ -1,9 +1,9 @@ -import pyseldon +import pyseldonlib import pytest def test_degroot_settings(): - settings = pyseldon.seldoncore.DeGrootSettings() + settings = pyseldonlib.seldoncore.DeGrootSettings() assert settings.max_iterations == None assert settings.convergence_tol == 0.0 diff --git a/tests/seldoncore/test_initial_network_settings.py b/tests/seldoncore/test_initial_network_settings.py index 0b3279a..f9b4985 100644 --- a/tests/seldoncore/test_initial_network_settings.py +++ b/tests/seldoncore/test_initial_network_settings.py @@ -1,10 +1,10 @@ -import pyseldon +import pyseldonlib import pathlib as ptlb import pytest def test_initial_network_settings_readwrite(): - network_settings = pyseldon.seldoncore.InitialNetworkSettings() + network_settings = pyseldonlib.seldoncore.InitialNetworkSettings() # default values assert network_settings.file is None diff --git a/tests/seldoncore/test_io.py b/tests/seldoncore/test_io.py index ab0f4af..a6c53d6 100644 --- a/tests/seldoncore/test_io.py +++ b/tests/seldoncore/test_io.py @@ -1,4 +1,4 @@ -import pyseldon +import pyseldonlib import pytest import pathlib @@ -7,7 +7,7 @@ def test_io_network(): proj_root_path = pathlib.Path.cwd() network_file = str(proj_root_path / "tests" / "res" / "network.txt") - network = pyseldon.seldoncore.generate_from_file_activity_agent(network_file) + network = pyseldonlib.seldoncore.generate_from_file_activity_agent(network_file) assert network.n_agents() == 3 @@ -23,7 +23,7 @@ def test_io_agents(): proj_root_path = pathlib.Path.cwd() agent_file = str(proj_root_path / "tests" / "res" / "opinions.txt") - agents = pyseldon.seldoncore.agents_from_file_activity_agent(agent_file) + agents = pyseldonlib.seldoncore.agents_from_file_activity_agent(agent_file) opinions_expected = [2.1127107987061544, 0.8088982488089491, -0.8802809369462433] activities_expected = [ 0.044554683389757696, diff --git a/tests/seldoncore/test_network.py b/tests/seldoncore/test_network.py index 0b368c3..29f445f 100644 --- a/tests/seldoncore/test_network.py +++ b/tests/seldoncore/test_network.py @@ -1,5 +1,5 @@ import pytest -import pyseldon +import pyseldonlib def test_network_class_tests(): @@ -8,7 +8,7 @@ def test_network_class_tests(): n_connections = 10 gen_pseudorandom = 0 - network = pyseldon.seldoncore.generate_n_connections_( + network = pyseldonlib.seldoncore.generate_n_connections_( n_agents=n_agents, n_connections=n_connections, self_interaction = False, @@ -93,7 +93,7 @@ def test_network_class_tests(): neighbour_no_double_counting = [[0, 1, 2], [0, 1, 2], [0, 1, 2], [], [1, 3]] weights_no_double_counting = [[0, 3, -1], [1, 2, -2], [2, 1, 3], [], [1, 1]] - network = pyseldon.seldoncore.Network(neighbour_list, weights, "Incoming") + network = pyseldonlib.seldoncore.Network(neighbour_list, weights, "Incoming") network.remove_double_counting() for i_agent in range(network.n_agents()): @@ -116,7 +116,7 @@ def test_network_class_tests(): [8, 6, 4, 1], [7, 6, 5, 2], ] - network = pyseldon.seldoncore.generate_square_lattice_(n_edge=3) + network = pyseldonlib.seldoncore.generate_square_lattice_(n_edge=3) for i_agent in range(network.n_agents()): assert ( diff --git a/tests/seldoncore/test_network_generation.py b/tests/seldoncore/test_network_generation.py index ee74084..b0fbb95 100644 --- a/tests/seldoncore/test_network_generation.py +++ b/tests/seldoncore/test_network_generation.py @@ -1,4 +1,4 @@ -import pyseldon +import pyseldonlib import pytest @@ -12,7 +12,7 @@ def test_network_generation(): weight = 0.25 weights = [weight, weight, weight] - network = pyseldon.network.generate_fully_connected(model_string = "DeGroot", + network = pyseldonlib.network.generate_fully_connected(model_string = "DeGroot", n_agents=n_agents, weight=weight, rng_seed=None ) diff --git a/tests/seldoncore/test_output_settings.py b/tests/seldoncore/test_output_settings.py index 2fd9099..f2752a0 100644 --- a/tests/seldoncore/test_output_settings.py +++ b/tests/seldoncore/test_output_settings.py @@ -1,9 +1,9 @@ -import pyseldon +import pyseldonlib import pytest def test_output_settings(): - settings = pyseldon.seldoncore.OutputSettings() + settings = pyseldonlib.seldoncore.OutputSettings() assert settings.n_output_agents is None assert settings.n_output_network is None assert settings.print_progress is False diff --git a/tests/seldoncore/test_probability_distributions.py b/tests/seldoncore/test_probability_distributions.py index fa0ad81..5c79f48 100644 --- a/tests/seldoncore/test_probability_distributions.py +++ b/tests/seldoncore/test_probability_distributions.py @@ -1,6 +1,6 @@ import os from pathlib import Path -import pyseldon +import pyseldonlib import pytest import random @@ -11,7 +11,7 @@ def write_results_to_file(n_samples, dist, filename): print(f"file = {file_path}") file_path.parent.mkdir(parents=True, exist_ok=True) - gen = pyseldon.seldoncore.RandomGenerator(random.randint(0, 2**32 - 1)) + gen = pyseldonlib.seldoncore.RandomGenerator(random.randint(0, 2**32 - 1)) results = [dist(gen) for _ in range(n_samples)] with open(file_path, "w") as file: @@ -22,21 +22,21 @@ def write_results_to_file(n_samples, dist, filename): def test_probability_distributions(): write_results_to_file( 10000, - pyseldon.seldoncore.Truncated_Normal_Distribution(1.0, 0.5, 0.75), + pyseldonlib.seldoncore.Truncated_Normal_Distribution(1.0, 0.5, 0.75), "truncated_normal.txt", ) write_results_to_file( - 10000, pyseldon.seldoncore.Power_Law_Distribution(0.01, 2.1), "power_law.txt" + 10000, pyseldonlib.seldoncore.Power_Law_Distribution(0.01, 2.1), "power_law.txt" ) write_results_to_file( 10000, - pyseldon.seldoncore.Bivariate_Normal_Distribution(0.5), + pyseldonlib.seldoncore.Bivariate_Normal_Distribution(0.5), "bivariate_normal.txt", ) def test_bivariate_gaussian_copula(): - dist1 = pyseldon.seldoncore.Power_Law_Distribution(0.02, 2.5) - dist2 = pyseldon.seldoncore.Truncated_Normal_Distribution(1.0, 0.75, 0.2) - copula = pyseldon.seldoncore.Bivariate_Gaussian_Copula(0.5, dist1, dist2) + dist1 = pyseldonlib.seldoncore.Power_Law_Distribution(0.02, 2.5) + dist2 = pyseldonlib.seldoncore.Truncated_Normal_Distribution(1.0, 0.75, 0.2) + copula = pyseldonlib.seldoncore.Bivariate_Gaussian_Copula(0.5, dist1, dist2) write_results_to_file(10000, copula, "gaussian_copula.txt") diff --git a/tests/seldoncore/test_sampling.py b/tests/seldoncore/test_sampling.py index 376b1bc..ee20c10 100644 --- a/tests/seldoncore/test_sampling.py +++ b/tests/seldoncore/test_sampling.py @@ -1,7 +1,7 @@ import math import pytest import random -import pyseldon +import pyseldonlib def compute_p(k, n): @@ -20,9 +20,9 @@ def test_draw_unique_k_from_n(): histogram = [0] * n buffer = [] - gen = pyseldon.seldoncore.RandomGenerator(random.randint(0, 2**32 - 1)) + gen = pyseldonlib.seldoncore.RandomGenerator(random.randint(0, 2**32 - 1)) for _i in range(0, N_RUNS): - pyseldon.seldoncore.draw_unique_k_from_n( + pyseldonlib.seldoncore.draw_unique_k_from_n( ignore_idx=ignore_idx, k=k, n=n, buffer=buffer, gen=gen ) for num in buffer: diff --git a/tests/seldoncore/test_tarjan_scc.py b/tests/seldoncore/test_tarjan_scc.py index 5f97291..52265d4 100644 --- a/tests/seldoncore/test_tarjan_scc.py +++ b/tests/seldoncore/test_tarjan_scc.py @@ -1,5 +1,5 @@ import pytest -import pyseldon +import pyseldonlib # Test data similar to the C++ version neighbour_list = [[1], [2, 3], [0], [4], [5], [4], [4, 7], [5, 8], [9], [6, 7]] @@ -10,7 +10,7 @@ def test_tarjan_scc(): # Run Tarjan's algorithm - tarjan_scc = pyseldon.seldoncore.TarjanConnectivityAlgo(neighbour_list) + tarjan_scc = pyseldonlib.seldoncore.TarjanConnectivityAlgo(neighbour_list) # Convert each SCC list to a set for comparison scc_sets = [set(scc) for scc in tarjan_scc.scc_list] diff --git a/tests/seldoncore/test_util.py b/tests/seldoncore/test_util.py index d2bf43d..cf9474f 100644 --- a/tests/seldoncore/test_util.py +++ b/tests/seldoncore/test_util.py @@ -1,11 +1,11 @@ import pytest -import pyseldon +import pyseldonlib def test_hamming_distance(): v1 = [1, 1, 1, 0, 1] v2 = [0, 1, 1, 0, 0] - dist = pyseldon.seldoncore.hamming_distance(v1, v2) + dist = pyseldonlib.seldoncore.hamming_distance(v1, v2) assert dist == 2 diff --git a/tests/test_activity_driven.py b/tests/test_activity_driven.py index 3f85a96..a7141bc 100644 --- a/tests/test_activity_driven.py +++ b/tests/test_activity_driven.py @@ -1,4 +1,4 @@ -import pyseldon +import pyseldonlib import pathlib import pytest import shutil @@ -8,14 +8,14 @@ def test_activity_driven(): # using ./tests/res/activity_probabilistic_conf.toml - other_settings = pyseldon.Other_Settings( + other_settings = pyseldonlib.Other_Settings( number_of_agents=1000, connections_per_agent=10, n_output_agents=1, print_progress=False, ) - model = pyseldon.Activity_Driven_Model( + model = pyseldonlib.Activity_Driven_Model( max_iterations=20, dt=0.01, # Timestep for the integration of the coupled ODEs m=10, # Number of agents contacted, when the agent is active @@ -46,7 +46,7 @@ def test_activity_driven(): # By using a config file config_file_path = str(base_dir / "res/activity_probabilistic_conf.toml") - pyseldon.run_simulation_from_config_file( + pyseldonlib.run_simulation_from_config_file( config_file_path=config_file_path, output_dir_path=output_dir ) assert pathlib.Path(output_dir).exists() @@ -57,7 +57,7 @@ def test_activity_driven(): def test_activityProb(): proj_root = pathlib.Path.cwd() input_file = str(proj_root / "tests" / "res" / "activity_probabilistic_conf.toml") - options = pyseldon.parse_config_file(input_file) + options = pyseldonlib.parse_config_file(input_file) output_dir_path = proj_root / "tests" / "output" @@ -65,7 +65,7 @@ def test_activityProb(): shutil.rmtree(output_dir_path) output_dir_path.mkdir(parents=True, exist_ok=True) - simulation = pyseldon.seldoncore.SimulationActivityAgent(options=options) + simulation = pyseldonlib.seldoncore.SimulationActivityAgent(options=options) simulation.run(str(output_dir_path)) assert any(output_dir_path.iterdir()), "Output directory is empty after simulation." @@ -79,11 +79,11 @@ def test_activityProbTwoAgents(): output_dir_path = str(proj_root / "tests" / "output") - other_settings = pyseldon.Other_Settings( + other_settings = pyseldonlib.Other_Settings( number_of_agents=2, connections_per_agent=1, print_progress=False ) - model = pyseldon.Activity_Driven_Model( + model = pyseldonlib.Activity_Driven_Model( max_iterations=10000, dt=0.005, # Timestep for the integration of the coupled ODEs m=1, # Number of agents contacted, when the agent is active @@ -120,11 +120,11 @@ def test_activityProbTwoAgents(): def test_activity1Bot1AgentReluctance(): proj_root = pathlib.Path.cwd() - other_settings = pyseldon.Other_Settings( + other_settings = pyseldonlib.Other_Settings( number_of_agents=2, connections_per_agent=1, print_progress=False ) - model = pyseldon.Activity_Driven_Model( + model = pyseldonlib.Activity_Driven_Model( max_iterations=1000, dt=0.001, # Timestep for the integration of the coupled ODEs m=1, # Number of agents contacted, when the agent is active diff --git a/tests/test_activity_driven_inertial_settings.py b/tests/test_activity_driven_inertial_settings.py index ef319c9..ea67ae0 100644 --- a/tests/test_activity_driven_inertial_settings.py +++ b/tests/test_activity_driven_inertial_settings.py @@ -1,9 +1,9 @@ -import pyseldon +import pyseldonlib import pytest def test_activity_driven_inertial_settings(): - settings = pyseldon.seldoncore.ActivityDrivenInertialSettings() + settings = pyseldonlib.seldoncore.ActivityDrivenInertialSettings() assert settings.max_iterations == None assert settings.dt == 0.01 assert settings.m == 10 diff --git a/tests/test_activity_inertial.py b/tests/test_activity_inertial.py index 6285466..2a323a5 100644 --- a/tests/test_activity_inertial.py +++ b/tests/test_activity_inertial.py @@ -1,4 +1,4 @@ -import pyseldon +import pyseldonlib import pathlib import pytest import cmath @@ -8,10 +8,10 @@ # Test the probabilistic inertial activity driven model with one bot and one agent def test_inertial1Bot1Agent(): proj_root_path = pathlib.Path.cwd() - other_settings = pyseldon.Other_Settings( + other_settings = pyseldonlib.Other_Settings( print_progress=False, number_of_agents=2, connections_per_agent=1 ) - model = pyseldon.Inertial_Model( + model = pyseldonlib.Inertial_Model( max_iterations=1000, dt=0.001, m=1, diff --git a/tests/test_deGroot.py b/tests/test_deGroot.py index a721f8e..0ed147c 100644 --- a/tests/test_deGroot.py +++ b/tests/test_deGroot.py @@ -1,4 +1,4 @@ -import pyseldon +import pyseldonlib import math import pytest import pathlib @@ -10,13 +10,13 @@ def test_deGroot(): neighbour_list = [[1, 0], [0, 1]] weight_list = [[0.2, 0.8], [0.2, 0.8]] - network = pyseldon.seldoncore.SimpleAgentNetwork( + network = pyseldonlib.seldoncore.SimpleAgentNetwork( neighbour_list=neighbour_list, weight_list=weight_list, direction="Incoming" ) output_dir = str(pathlib.Path.cwd() / "tests/output") - model = pyseldon.DeGroot_Model(max_iterations=100, convergence_tol=1e-6) + model = pyseldonlib.DeGroot_Model(max_iterations=100, convergence_tol=1e-6) model.Network = network model.set_agent_opinion(0, 0.0) model.set_agent_opinion(1, 1.0) diff --git a/tests/test_deffuant.py b/tests/test_deffuant.py index 4a5fa03..9d80a91 100644 --- a/tests/test_deffuant.py +++ b/tests/test_deffuant.py @@ -1,4 +1,4 @@ -import pyseldon +import pyseldonlib import pytest from pathlib import Path import shutil @@ -6,10 +6,10 @@ def test_basic_deffuant_model_two_agents(): proj_root = Path.cwd() - other_settings = pyseldon.Other_Settings( + other_settings = pyseldonlib.Other_Settings( number_of_agents=2, connections_per_agent=0 ) - model = pyseldon.Deffuant_Model( + model = pyseldonlib.Deffuant_Model( max_iterations=10, homophily_threshold=0.2, mu=0.5, @@ -51,10 +51,10 @@ def test_basic_deffuant_model_two_agents(): def test_lattice_deffuant_model_16X16_agents(): proj_root = Path.cwd() - other_settings = pyseldon.Other_Settings( + other_settings = pyseldonlib.Other_Settings( number_of_agents=256, connections_per_agent=0 ) - model = pyseldon.Deffuant_Model( + model = pyseldonlib.Deffuant_Model( max_iterations=10000, homophily_threshold=1.0, mu=0.5, @@ -98,10 +98,10 @@ def test_lattice_deffuant_model_16X16_agents(): # Test the multi-dimensional Deffuant vector model, with 3-dimensional binary opinions, for two agents def test_deffuant_vector_model(): proj_root = Path.cwd() - other_settings = pyseldon.Other_Settings( + other_settings = pyseldonlib.Other_Settings( number_of_agents=2, connections_per_agent=0 ) - model = pyseldon.Deffuant_Vector_Model( + model = pyseldonlib.Deffuant_Vector_Model( max_iterations=10, homophily_threshold=2, mu=0.5, diff --git a/visualisations/check_package.py b/visualisations/check_package.py deleted file mode 100644 index 9c4281c..0000000 --- a/visualisations/check_package.py +++ /dev/null @@ -1,94 +0,0 @@ -import pyseldon -import pathlib - -# pyseldon.seldoncore.run_simulation(config_file_path='/home/parrot_user/Desktop/pyseldon/subprojects/seldon/examples/ActivityDriven/conf.toml') - -# sim_options = pyseldon.seldoncore.SimulationOptions(model_string = "Deffuant", model_settings = pyseldon.seldoncore.DeffuantSettings(max_iterations = 20), output_settings = pyseldon.seldoncore.OutputSettings(n_output_agents= 200,n_output_network = 5)) -# simulation = pyseldon.seldoncore.SimulationSimpleAgent(sim_options) -# agent = simulation.network.agent[1].data.opinion - -# print(agent) -# print(type(agent)) - -# simulation = pyseldon.seldoncore.SimulationSimpleAgent(pyseldon.seldoncore.parse_config_file("/home/parrot_user/Desktop/pyseldon/subprojects/seldon/examples/DeGroot/conf.toml")) -# agent = simulation.network.agent - -# simulation.run() -# for i in agent: -# print(i.data.opinion) -# print(dir(simulation)) - -# pyseldon.seldoncore.run_simulation(config_file_path = "/home/parrot_user/Desktop/pyseldon/subprojects/seldon/examples/ActivityDrivenBot/conf.toml") - -# agent = simulation.network.agent[5].data.opinion -# print(agent) - - -# print(type(DeGrootSettings())) -# print(type(Network())) - -# network = Network(model_string="DeGroot", n_agents=5) -# print(network.n_agents) -# op = OutputSettings(n_output_agents = 1) -# op.n_output_agents = 2 -# # print(op.print_settings) - -# deg = DeGrootSettings(max_iterations =1) -# deff = DeffuantSettings(max_iterations = 2, homophily_threshold=0.5) -# deffv = DeffuantSettings(max_iterations = 2, homophily_threshold=0.5, use_binary_vector=True, dim=2) -# # print(deg) -# # print(deg.settings.max_iterations) -# # print(deg.max_iterations) - -# sett = SimulationOptions(model_string = "DeGroot", output_settings=op, model_settings=deg) -# print(sett.model_string) -# print(sett.model) -# print(sett.output_settings) -# print(sett.options) - -# x = Simulation(options = SimulationOptions(model_string = "DeffuantVector", output_settings=op, model_settings= deffv), agent_file_path=None, network_file_path=None) -# # x.run() -# network = x.network -# print(network.n_agents()) -# print(network.n_agents) - -other_settings = pyseldon.Other_Settings(n_output_agents = 1, n_output_network= 20,number_of_agents = 300,connections_per_agent = 10) -model = pyseldon.DeGroot_Model(max_iterations=20, rng_seed=120, other_settings=other_settings) -# print(f"max_iterations_before{model.max_iterations}") -# model.max_iterations = 200 -# print(f"max_iterations_after{model.max_iterations}") -# print(f"rng_seed_before{model.rng_seed}") -# model.rng_seed = 120 -# model.run("./output1") -other_settings = pyseldon.Other_Settings(n_output_agents = 1, n_output_network= 1,number_of_agents = 500,connections_per_agent = 10) -model = pyseldon.DeGroot_Model(max_iterations="20", rng_seed=120, other_settings=other_settings) -model.run("./output") -result = model.agents_opinions() -print(result) - -#-------------------------------------------------- -# newest -# model = DeGrootModel(max_iterations=100,rng_seed=120) -# model.run("./output1") - -# network = model.get_Network() -# print(network.n_agents()) -# # opinions = model.agents_opinions() -# for x in network.get_neighbours(1): -# print(x) -# # for x in network.get_weights(1): -# # print(x) -# network.set_neighbours_and_weights(1, [16,45], 0.5) -# for x in network.get_weights(1): -# print(x) -# for x in network.get_neighbours(1): -# print(x) -# model.run() -# for x in network.get_weights(1): -# print(x) -# for x in network.get_neighbours(1): -# print(x) -# print(opinions) - -# pyseldon.run_simulation_from_config_file(config_file_path="/home/parrot_user/Desktop/pyseldon/subprojects/seldon/examples/DeGroot/conf.toml", output_dir_path= "./output") - diff --git a/visualisations/cytoscapenormalisation.py b/visualisations/cytoscapenormalisation.py index 639af5e..88a23ac 100644 --- a/visualisations/cytoscapenormalisation.py +++ b/visualisations/cytoscapenormalisation.py @@ -1,7 +1,7 @@ import csv -input_file = '/home/parrot_user/Desktop/pyseldon/examples/ouput_20_agents/network_0.txt' # Your CSV file -output_file ='/home/parrot_user/Desktop/pyseldon/examples/ouput_20_agents/network.csv' # Output file for Cytoscape +input_file = '/home/parrot_user/Desktop/pyseldonlib/examples/ouput_20_agents/network_0.txt' # Your CSV file +output_file ='/home/parrot_user/Desktop/pyseldonlib/examples/ouput_20_agents/network.csv' # Output file for Cytoscape with open(input_file, 'r') as csvfile, open(output_file, 'w', newline='') as out_csv: reader = csv.reader(csvfile) diff --git a/visualisations/degrootmodel.ipynb b/visualisations/degrootmodel.ipynb index 77c2ab9..ca24c45 100644 --- a/visualisations/degrootmodel.ipynb +++ b/visualisations/degrootmodel.ipynb @@ -13,7 +13,7 @@ "metadata": {}, "outputs": [], "source": [ - "import pyseldon" + "import pyseldonlib" ] }, { @@ -29,7 +29,7 @@ "metadata": {}, "outputs": [], "source": [ - "other_settings = pyseldon.Other_Settings(n_output_agents=10,\n", + "other_settings = pyseldonlib.Other_Settings(n_output_agents=10,\n", " n_output_network= None, \n", " print_progress= True, \n", " output_initial=True, \n", @@ -93,7 +93,7 @@ } ], "source": [ - "model = pyseldon.DeGroot_Model(max_iterations=1000,\n", + "model = pyseldonlib.DeGroot_Model(max_iterations=1000,\n", " convergence_tol=1e-6,\n", " rng_seed=120, \n", " other_settings=other_settings)\n", diff --git a/visualisations/ouput_20_agents_10_connections_each/degrootmodel.ipynb b/visualisations/ouput_20_agents_10_connections_each/degrootmodel.ipynb index 7a62cab..cc65413 100644 --- a/visualisations/ouput_20_agents_10_connections_each/degrootmodel.ipynb +++ b/visualisations/ouput_20_agents_10_connections_each/degrootmodel.ipynb @@ -13,7 +13,7 @@ "metadata": {}, "outputs": [], "source": [ - "import pyseldon" + "import pyseldonlib" ] }, { @@ -29,7 +29,7 @@ "metadata": {}, "outputs": [], "source": [ - "other_settings = pyseldon.Other_Settings(n_output_agents=10,\n", + "other_settings = pyseldonlib.Other_Settings(n_output_agents=10,\n", " n_output_network= None, \n", " print_progress= True, \n", " output_initial=True, \n", @@ -93,7 +93,7 @@ } ], "source": [ - "model = pyseldon.DeGroot_Model(max_iterations=1000,\n", + "model = pyseldonlib.DeGroot_Model(max_iterations=1000,\n", " convergence_tol=1e-6,\n", " rng_seed=120, \n", " other_settings=other_settings)\n", diff --git a/visualisations/output_20_agents_4_connections_each/degrootmodel.ipynb b/visualisations/output_20_agents_4_connections_each/degrootmodel.ipynb index 974c390..78bbcf5 100644 --- a/visualisations/output_20_agents_4_connections_each/degrootmodel.ipynb +++ b/visualisations/output_20_agents_4_connections_each/degrootmodel.ipynb @@ -13,7 +13,7 @@ "metadata": {}, "outputs": [], "source": [ - "import pyseldon" + "import pyseldonlib" ] }, { @@ -29,7 +29,7 @@ "metadata": {}, "outputs": [], "source": [ - "other_settings = pyseldon.Other_Settings(n_output_agents=1,\n", + "other_settings = pyseldonlib.Other_Settings(n_output_agents=1,\n", " n_output_network= None, \n", " print_progress= True, \n", " output_initial=True, \n", @@ -102,7 +102,7 @@ } ], "source": [ - "model = pyseldon.DeGroot_Model(max_iterations=1000,\n", + "model = pyseldonlib.DeGroot_Model(max_iterations=1000,\n", " convergence_tol=1e-6,\n", " rng_seed=120, \n", " other_settings=other_settings)\n",