Skip to content

Commit

Permalink
Merge pull request #2 from User-DK/main
Browse files Browse the repository at this point in the history
ENH: Final PR for Python bindings for Seldon (GSOC'24)
  • Loading branch information
HaoZeke authored Aug 25, 2024
2 parents fcefc15 + f9d2f44 commit 11cbb82
Show file tree
Hide file tree
Showing 125 changed files with 7,215 additions and 3 deletions.
36 changes: 36 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
#from https://github.com/pybind/pybind11/blob/master/.clang-format
# See all possible options and defaults with:
# clang-format --style=llvm --dump-config
AccessModifierOffset: -4
AllowShortLambdasOnASingleLine: true
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: false
BinPackParameters: false
BreakBeforeBinaryOperators: All
ColumnLimit: 150
CommentPragmas: 'NOLINT:.*|^ IWYU pragma:'
IncludeBlocks: Regroup
IndentCaseLabels: true
IndentPPDirectives: AfterHash
IndentWidth: 4
Language: Cpp
SpaceAfterCStyleCast: true
Standard: Cpp11
StatementMacros: ['PyObject_HEAD']
TabWidth: 2
IncludeCategories:
- Regex: '<pybind11/.*'
Priority: -1
- Regex: 'pybind11.h"$'
Priority: 1
- Regex: '^".*/?detail/'
Priority: 1
SortPriority: 2
- Regex: '^"'
Priority: 1
SortPriority: 3
- Regex: '<[[:alnum:]._]+>'
Priority: 4
- Regex: '.*'
Priority: 5
81 changes: 81 additions & 0 deletions .github/workflows/build_wheels.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Build on every branch push, tag push, and pull request change:
# From: https://github.com/pypa/cibuildwheel/blob/main/examples/github-deploy.yml
# Also:
# https://github.com/airspeed-velocity/asv/blob/main/.github/workflows/build_wheels.yml
# include [wheel build] in the commit to trigger wheel builds
name: Build wheels
on: [push, pull_request, workflow_dispatch]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read # to fetch code (actions/checkout)

jobs:
get_commit_message:
name: Get commit message
runs-on: ubuntu-latest
outputs:
message: ${{ steps.commit_message.outputs.message }}
steps:
- name: Checkout pyseldonlib
uses: actions/checkout@v4
# Gets the correct commit message for pull request
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Get commit message
id: commit_message
run: |
set -xe
COMMIT_MSG=$(git log --no-merges -1 --oneline)
echo "message=$COMMIT_MSG" >> $GITHUB_OUTPUT
echo github.ref ${{ github.ref }}
build_wheels:
name: Build wheels
needs: get_commit_message
if: >-
contains(needs.get_commit_message.outputs.message, '[wheel build]') ||
github.event_name == 'schedule' ||
github.event_name == 'workflow_dispatch' ||
(github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') && ( ! endsWith(github.ref, 'dev0')))
runs-on: ${{ matrix.os }}
env: # Needed for C++20 support on MacOS
MACOSX_DEPLOYMENT_TARGET: '12.6'
strategy:
# Ensure that a wheel builder finishes even if another fails
fail-fast: false
matrix:
# macos-13 is an intel runner, macos-14 is apple silicon
os: [ubuntu-24.04, windows-2022, macos-13, macos-14]

steps:
- uses: actions/checkout@v4
- name: Echo build platform
run: echo Building wheels for ${{ matrix.os }}
- name: Build wheels
uses: pypa/[email protected]
- uses: actions/upload-artifact@v3
with:
path: ./wheelhouse/*.whl

build_sdist:
name: Build source distribution
needs: get_commit_message
if: >-
contains(needs.get_commit_message.outputs.message, '[wheel build]') ||
github.event_name == 'schedule' ||
github.event_name == 'workflow_dispatch' ||
(github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') && ( ! endsWith(github.ref, 'dev0')))
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Build sdist
shell: bash -l {0}
run: pipx run build --sdist

- uses: actions/upload-artifact@v3
with:
path: dist/*.tar.gz
54 changes: 54 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: Test and Documentation workflow

on:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
build:
runs-on: ubuntu-latest
defaults:
run:
shell: micromamba-shell {0}

steps:
- name: Checkout repository
uses: actions/checkout@v4 # Updated to latest stable version

- name: micromamba setup
uses: mamba-org/setup-micromamba@v1
with:
environment-file: environment.yml
generate-run-shell: true
cache-environment: true
init-shell: bash

- name: Install project dependencies
run: |
meson setup build
pip install .
- name: Run tests
run: |
pytest tests/
- name: Install documentation dependencies
run: |
python -m pip install --upgrade pip
pip install -r docs/requirements.txt
- name: Build the documentation
run: |
cd docs
sphinx-build -b html . source/_build/html
- name: Deploy the documentation
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: docs/source/_build/html
keep_files: true
35 changes: 35 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,33 @@
#subprojects
/subprojects/seldon/
# If we need something, we'll add it with -f
/subprojects/*
/wheelhouse/

#vscode
.vscode/

# docs
*_build/
doc/apidocs/

#pycache
*__pycache__/
*_cache/

#probability_distribution
output_probability_distributions/

#mesonpython
.mesonpy*
notes.txt
TODO.txt
tests/__pycache__/
tests/outputs/
.pytest*
output/
build/

# Prerequisites
*.d

Expand Down Expand Up @@ -30,3 +60,8 @@
*.exe
*.out
*.app

# dist folder
dist/

token
12 changes: 12 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
repos:
- repo: https://github.com/pre-commit/mirrors-clang-format
rev: v12.0.0
hooks:
- id: clang-format
files: python_bindings/bindings.cpp

- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: v0.0.241
hooks:
- id: ruff
files: ^tests/|^pyseldonlib/
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -671,4 +671,4 @@ into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.
<https://www.gnu.org/licenses/why-not-lgpl.html>.
58 changes: 58 additions & 0 deletions Project.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# 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.
- A clean and robust interface for conducting the simulations.

## Opinion Dynamics

Opinion dynamics is a field of study within the realm of complex systems and sociophysics that explores how opinions, beliefs, and attitudes evolve and spread within social networks. It combines elements of physics, social science, and mathematics to understand the mechanisms driving opinion formation and change under various influences, such as personal convictions, peer pressure, media impact, and societal norms.

Our work contributes to this interdisciplinary field by providing robust tools for simulation and analysis, aiding in the understanding of complex opinion dynamics phenomena [`Seldon-Code`](https://github.com/seldon-code).

## DeGroot Model Example

The DeGroot model is a model of social influence. It describes how agents in a network can reach a consensus by updating their opinions based on the opinions of their neighbors. The DeGroot model is a simple model of social influence that has been studied extensively in the literature. It is used to model a wide range of social phenomena, such as the spread of information, the formation of opinions, and the emergence of social norms.

Below is an example of reaching consensus in a network using the DeGroot model. We will create a network of 20 agents with random opinions and random connections between them. We will then conduct the simulation.

### Initial Opinions

Initial opinions of the agents in the network in the range of [0,1] are shown below:

![Initial Opinions](https://github.com/User-DK/pyseldon/raw/main/visualisations/ouput_20_agents_10_connections_each/initial.png)

### Final Opinions

Final opinions of the agents in the network after the simulation are shown below:

![Final Opinions](https://github.com/User-DK/pyseldon/raw/main/visualisations/ouput_20_agents_10_connections_each/final.png)

We can conclude that the agents have reached a consensus after the simulation.

### Reference
- DeGroot, M. H. (1974). Reaching a Consensus. Journal of the American Statistical Association, 69(345), 118–121. https://doi.org/10.2307/2285509


### Usage

```python
import pyseldonlib

pyseldonlib.run_simulation_from_config_file(config_file_path = '/path/to/config/file')
```

```python
import pyseldonlib

model = pyseldonlib.DeGroot_Model(max_iterations=1000,
convergence_tol=1e-6,
rng_seed=120,
other_settings=other_settings)

output_dir_path = str("./output")

model.run(output_dir_path)
```
62 changes: 60 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,60 @@
# pyseldon
Python bindings for the Seldon framework
# pyseldonlib
![](https://raw.githubusercontent.com/User-DK/pyseldon/main/res/logotext.png)

## Python bindings for the Seldon framework

This work is a part of Google Summer of Code 2024 under the Python Software Organisation. The aim of this project is to create Python bindings for the Seldon framework. The Seldon framework is a C++ Engine for Opinion Dynamics. The bindings and the complete project as a python package will allow users to use the Seldon framework in Python and carry out Simulations.

### DeGroot Model Example
The DeGroot model is a model of social influence. It describes how agents in a network can reach a consensus by updating their opinions based on the opinions of their neighbors. The DeGroot model is a simple model of social influence that has been studied extensively in the literature. It is used to model a wide range of social phenomena, such as the spread of information, the formation of opinions, and the emergence of social norms.

And here is the example of reaching consensus in a network using the DeGroot model.
We will create a network of 20 agents with random opinions and random connections between them. We will then conduct the simulation. as can be seen in the notebook file [here](./examples/ouput_20_agents_10_connections_each/degrootmodel.ipynb).

Initial opinions of the agents in the network in the range of [0,1] are shown below:
![initial opinions](https://github.com/User-DK/pyseldon/raw/main/visualisations/ouput_20_agents_10_connections_each/initial.png)

Final opinions of the agents in the network after the simulation are shown below:
![final opinions](https://github.com/User-DK/pyseldon/raw/main/visualisations/ouput_20_agents_10_connections_each/final.png)

And we can conclude that the agents have reached a consensus after the simulation.

### Reference
- DeGroot, M. H. (1974). Reaching a Consensus. Journal of the American Statistical Association, 69(345), 118–121. https://doi.org/10.2307/2285509

visualisations generated with the help of `cytoscape` some of the visualisations normalisation code can be found [here](./visualisations/)

### Steps to Install and Compile the code

### Installation
Create a new `micromamba` environment and activate it:
```bash
micromamba create -f environment.yml
micromamba activate pyseldonenv
```
If you get problem with micromamba can look at the installation documentation [here](https://mamba.readthedocs.io/en/latest/installation/micromamba-installation.html)

### Build
Set up the build directory with `meson`:
```bash
meson setup build
```

### Install Python package
Use `pip` to install the package:
```bash
pip install .
```

### Run the tests
Use `pytest` to run the tests:
```bash
pytest tests/
```
or

```bash
pytest -s tests/
```
to see the output of the tests without capturing the std output

1 change: 1 addition & 0 deletions bindings_package/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from pyseldonlib import seldoncore
Loading

0 comments on commit 11cbb82

Please sign in to comment.