stochastic-flock 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,69 @@
1
+ name: Build and Upload to PyPI
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ push:
6
+ branches: [ main ]
7
+ release:
8
+ types: [published, created, released] # Added more types for safety
9
+
10
+ jobs:
11
+ build_wheels:
12
+ name: Build wheels on ${{ matrix.os }}
13
+ runs-on: ${{ matrix.os }}
14
+ strategy:
15
+ fail-fast: false
16
+ matrix:
17
+
18
+ os: [ubuntu-latest, windows-latest, macos-14]
19
+
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+ with:
23
+ submodules: recursive
24
+
25
+ - name: Build wheels
26
+ uses: pypa/cibuildwheel@v2.21.3
27
+ env:
28
+ # Only CPython 3.10+, No PyPy (fixes your previous error)
29
+ CIBW_SKIP: pp* cp36-* cp37-* cp38-* cp39-* *-win32 *-manylinux_i686
30
+ # manylinux_2_28 provides GCC 11/12 for C++20 support
31
+ CIBW_MANYLINUX_X86_64_IMAGE: manylinux_2_28
32
+ CIBW_BUILD_VERBOSITY: 1
33
+
34
+ - uses: actions/upload-artifact@v4
35
+ with:
36
+ name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
37
+ path: ./wheelhouse/*.whl
38
+
39
+ build_sdist:
40
+ name: Build source distribution
41
+ runs-on: ubuntu-latest
42
+ steps:
43
+ - uses: actions/checkout@v4
44
+ with:
45
+ submodules: recursive
46
+ - name: Build sdist
47
+ run: pipx run build --sdist
48
+ - uses: actions/upload-artifact@v4
49
+ with:
50
+ name: cibw-sdist
51
+ path: dist/*.tar.gz
52
+
53
+ upload_pypi:
54
+ needs: [build_wheels, build_sdist]
55
+ runs-on: ubuntu-latest
56
+ # This job only runs when you actually publish a "Release" on GitHub
57
+ if: github.event_name == 'release' || github.event_name == 'workflow_dispatch'
58
+ permissions:
59
+ id-token: write # Mandatory for Trusted Publishing
60
+ contents: read
61
+ steps:
62
+ - uses: actions/download-artifact@v4
63
+ with:
64
+ pattern: cibw-*
65
+ path: dist
66
+ merge-multiple: true
67
+
68
+ - name: Publish to PyPI
69
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,34 @@
1
+ # 1. Ignore everything by default
2
+ *
3
+
4
+ # 2. Allow all directories so Git can search them
5
+ !*/
6
+
7
+ # 3. Un-ignore C++ and Project Metadata files (anywhere)
8
+ !*.cpp
9
+ !*.hpp
10
+ !*.h
11
+ !*.gitignore
12
+ !*.txt
13
+ !*.toml
14
+ !*.md
15
+ !Makefile
16
+ !.github/
17
+ !.github/workflows/*.yml
18
+
19
+ # 4. Handle Python files:
20
+ # We DON'T un-ignore *.py globally (this keeps root .py files ignored).
21
+ # Instead, we only un-ignore the specific folder you want:
22
+ !src/stochastic_flock/
23
+ !src/stochastic_flock/*.py
24
+
25
+ # 5. Standard cleanup (Re-ignore build artifacts)
26
+ build/
27
+ build_pgo/
28
+ build_native/
29
+ dist/
30
+ __pycache__/
31
+ *.egg-info/
32
+ *.so
33
+ .venv/
34
+ src/stochastic_flock/__init__.py
@@ -0,0 +1,92 @@
1
+ cmake_minimum_required(VERSION 3.18)
2
+ project(stochastic_flock LANGUAGES CXX)
3
+
4
+ set(CMAKE_CXX_STANDARD 20)
5
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
6
+
7
+ # 1. Dependencies (Eigen)
8
+ include(FetchContent)
9
+ set(EIGEN_BUILD_PKGCONFIG OFF CACHE BOOL "" FORCE)
10
+ set(EIGEN_BUILD_DOC OFF CACHE BOOL "" FORCE)
11
+ set(BUILD_TESTING OFF CACHE BOOL "" FORCE)
12
+ set(EIGEN_LEAVE_TEST_IN_ALL_TARGET OFF CACHE BOOL "" FORCE)
13
+ set(EIGEN_BUILD_TESTING OFF CACHE BOOL "" FORCE)
14
+
15
+ FetchContent_Declare(
16
+ eigen
17
+ GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git
18
+ GIT_TAG 3.4.0
19
+ )
20
+
21
+ # Use the "manual" population instead of MakeAvailable
22
+ # so we can use EXCLUDE_FROM_ALL
23
+ FetchContent_GetProperties(eigen)
24
+ if(NOT eigen_POPULATED)
25
+ FetchContent_Populate(eigen)
26
+ # The EXCLUDE_FROM_ALL flag here is the magic bit.
27
+ # It tells CMake: "Build this, but don't install its files."
28
+ add_subdirectory(${eigen_SOURCE_DIR} ${eigen_BINARY_DIR} EXCLUDE_FROM_ALL)
29
+ endif()
30
+
31
+ find_package(Python3 COMPONENTS Interpreter Development.Module REQUIRED) #added .Module
32
+
33
+ # if(NOT pybind11_FOUND)
34
+ # execute_process(
35
+ # COMMAND "${Python3_EXECUTABLE}" -m pybind11 --cmakedir
36
+ # OUTPUT_VARIABLE pybind11_DIR
37
+ # OUTPUT_STRIP_TRAILING_WHITESPACE
38
+ # ERROR_QUIET
39
+ # )
40
+ # endif()
41
+
42
+ # # Now find it (using the path discovered above if necessary)
43
+ # find_package(pybind11 REQUIRED)
44
+
45
+ find_package(pybind11 QUIET)
46
+
47
+ # If not found, fall back to your manual search (works for your local build)
48
+ if(NOT pybind11_FOUND)
49
+ execute_process(
50
+ COMMAND "${Python3_EXECUTABLE}" -m pybind11 --cmakedir
51
+ OUTPUT_VARIABLE pybind11_DIR
52
+ OUTPUT_STRIP_TRAILING_WHITESPACE
53
+ ERROR_QUIET
54
+ )
55
+ find_package(pybind11 REQUIRED PATHS ${pybind11_DIR} NO_DEFAULT_PATH)
56
+ endif()
57
+
58
+ # 3. Define Optimization Settings (Interface Library)
59
+ # This replaces your 'foreach' loop logic
60
+ add_library(sim_opts INTERFACE)
61
+ target_compile_definitions(sim_opts INTERFACE EIGEN_RUNTIME_NO_MALLOC)
62
+
63
+ if(NOT MSVC)
64
+ target_compile_options(sim_opts INTERFACE -O3 -ffast-math -Wall)
65
+ if(NATIVE_OPTIM)
66
+ target_compile_options(sim_opts INTERFACE -march=native)
67
+ include(CheckIPOSupported)
68
+ check_ipo_supported(RESULT lto_supported)
69
+ if(lto_supported)
70
+ set_property(TARGET sim_opts PROPERTY INTERFACE_INTERPROCEDURAL_OPTIMIZATION TRUE)
71
+ endif()
72
+ endif()
73
+ endif()
74
+
75
+ pybind11_add_module(stochastic_flock src/python_bindings.cpp)
76
+ target_include_directories(stochastic_flock PRIVATE src)
77
+ target_link_libraries(stochastic_flock PRIVATE Eigen3::Eigen sim_opts)
78
+
79
+ install(TARGETS stochastic_flock DESTINATION stochastic_flock)
80
+
81
+ #TODO : ^^^ doesnt install to stochastic_flock folder. perhaps completely remove coupled makefile with bird_solver and python?
82
+
83
+
84
+ # 5. Target: Optional SFML (Skipped during Python build)
85
+ if(NOT SKBUILD)
86
+ find_package(SFML 2.5 COMPONENTS graphics window system QUIET)
87
+ if(SFML_FOUND)
88
+ add_executable(bird_solver src/bird_solver.cpp)
89
+ target_include_directories(bird_solver PRIVATE src)
90
+ target_link_libraries(bird_solver PRIVATE Eigen3::Eigen sfml-graphics sfml-window sfml-system sim_opts)
91
+ endif()
92
+ endif()
@@ -0,0 +1,41 @@
1
+ # 1. Path to your virtual environment's python
2
+ # This ensures we use your .venv even if it isn't "activated" in the terminal
3
+ PYTHON = $(shell pwd)/.venv/bin/python3
4
+ THREADS = $(shell nproc)
5
+
6
+ init:
7
+ $(PYTHON) -m pip install -e .
8
+ all:
9
+ # Only configure if the build directory doesn't exist
10
+ @if [ ! -d "build" ]; then \
11
+ cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DPython3_EXECUTABLE=$(PYTHON); \
12
+ fi
13
+ # Use -j to use all CPU cores
14
+ cmake --build build -j $(THREADS)
15
+ cp build/stochastic_flock*.so src/stochastic_flock
16
+
17
+ native:
18
+ cmake -B build_native -S . -DCMAKE_BUILD_TYPE=Release -DNATIVE_OPTIM=ON -DPython3_EXECUTABLE=$(PYTHON)
19
+ cmake --build build_native -j $(THREADS)
20
+
21
+ pgo: #only does bird_solver PGO
22
+
23
+ cmake -B build_pgo -S . -DCMAKE_BUILD_TYPE=Release -DNATIVE_OPTIM=ON -DCMAKE_CXX_FLAGS="-fprofile-generate" -DPython3_EXECUTABLE=$(PYTHON)
24
+ cmake --build build_pgo --target bird_solver -j $(THREADS)
25
+
26
+ ./build_pgo/bird_solver
27
+
28
+ cmake -B build_pgo -S . -DCMAKE_BUILD_TYPE=Release -DNATIVE_OPTIM=ON -DCMAKE_CXX_FLAGS="-fprofile-use" -DPython3_EXECUTABLE=$(PYTHON)
29
+ cmake --build build_pgo --target bird_solver -j $(THREADS)
30
+
31
+ debug:
32
+ cmake -B build_debug -S . -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="-fsanitize=address,undefined" -DPython3_EXECUTABLE=$(PYTHON)
33
+ cmake --build build_debug -j $(THREADS)
34
+
35
+ clean:
36
+ rm -rf build build_native build_debug build_pgo *.so *.gcda dist
37
+
38
+ help:
39
+ @echo "all: Standard build"
40
+ @echo "native: Fast build with native hardware optimizations"
41
+ @echo "pgo: Profile guided optimization + native build, max performance"
@@ -0,0 +1,88 @@
1
+ Metadata-Version: 2.2
2
+ Name: stochastic_flock
3
+ Version: 0.1.0
4
+ Summary: Unified Bird Flocking Simulation (1D & 2D)
5
+ Author-Email: Michael Stavreff <Mstavreff@outlook.com>
6
+ Requires-Python: >=3.8
7
+ Requires-Dist: numpy
8
+ Description-Content-Type: text/markdown
9
+
10
+
11
+
12
+ # High Performance C++ Flocking Simulation for Stochastic Modelling
13
+ > *Michael Stavreff,*
14
+ > *December 17, 2025*
15
+ ## Development & Compilation
16
+
17
+ This project uses **CMake** and a **Makefile** to manage the C++ build process, dependencies (Eigen, pybind11), and performance optimizations.
18
+
19
+ ### Prerequisites
20
+
21
+ To build the project from source, you will need:
22
+ * **C++20 Compiler** (GCC 10+ or Clang 11+)
23
+ * **CMake** (3.18+)
24
+ * **Python 3.8+** (with `python3-venv` and `python3-dev`)
25
+ * **SFML 2.5** (Optional: only required for the visual standalone solver)
26
+ ```bash
27
+ sudo apt install libsfml-dev
28
+ ```
29
+
30
+ ### Developer Setup
31
+ 1. Clone and create a virtual environment:
32
+
33
+ ```Bash
34
+ git clone https://github.com/Mstavreff/stochastic_flock.git
35
+ cd stochastic_flock
36
+ python3 -m venv .venv
37
+ source .venv/bin/activate
38
+ ```
39
+ 2. Install build dependencies:
40
+ ```Bash
41
+ pip install -r requirements.txt
42
+ ```
43
+
44
+ ### Building the Project
45
+ The provided Makefile contains shortcuts for common build scenarios.
46
+ 1. Standard Build (Python + C++ Solver)
47
+ Compiles the Python module into the root directory and the standalone solver into build/.
48
+
49
+ ```Bash
50
+ make
51
+ ```
52
+ 2. Native Hardware Optimization
53
+ Compiles using -march=native and -ffast-math. This produces the fastest possible binary for your specific CPU but is not portable to other hardware.
54
+
55
+ ```Bash
56
+ make native
57
+ ```
58
+ 3. Profile-Guided Optimization (PGO) + Native
59
+ For maximum performance, use PGO to optimize code paths based on simulation data. Uses ```tuning.py``` to instrument and recompiles using native flags.
60
+ ```Bash
61
+ make pgo
62
+ ```
63
+ 4. Debug Mode
64
+ Compiles with debug symbols (-g) and Undefined Behavior Sanitizers for use with GDB/LLDB.
65
+
66
+ ```Bash
67
+ make debug
68
+ ```
69
+ ### Python Usage
70
+
71
+ If you simply wish to use the simulation in a Python environment without modifying the C++ source:
72
+
73
+ ```Bash
74
+ pip install stochastic_flock
75
+ ```
76
+ For local development, after running make, you can import the module directly in the root directory:
77
+
78
+ ```Python
79
+ >>> import stochastic_flock
80
+ >>> sim = stochastic_flock.Simulation2d(params, seed)
81
+ ```
82
+ ## Introduction
83
+ Financial markets have famously exhibited flocking or herding behavior, most famously during crises and impending crashes. Such movements typically are completely unpredictable; the aim of this paper is to explore whether these movements are compltely unable to be modelled or are instead the product of some highly non-linear behavior requiring a novel approach. Naturally, birds in large flocks are an interesting candidate to model such emergent behavior in financial markets. Large flocks exhibit features which must be re-interpreted to a financial context, particularly in attraction, repulsion, turning behavior, and in the context of the particular paper, leader/follower dynamics:
84
+
85
+ ### Reference Paper Overview
86
+ *The original paper is given here: https://arxiv.org/abs/2010.01990.* While the paper is short and concise and absolutely worth a read, some important details will be repeated.
87
+
88
+ Cristiani et al.'s paper puts forward a second-order, delayed, stochastic differential equation to describe accelerations of bird agents. The stochastic element stems from birds having an exponential process (geometric in approximation) describing a follower -> leader transition where any attractive forces are dropped in their acceleration calculation and causing only repulsive-force trajectories. Additionally, birds react to the positions of others in a rank-ordered system of the nearest M birds, irregardless of distance; they also react to the delayed positions rather than the most instant information, something which creates more heavy movements and drifting of flocks in practice. These behaviors underline various interpretations worth discussing in the paper, mostly regarding trader behaviors or modelling portfolios of correlated equities in a sector which may be driven by such "social" forces and similarly experience shocks or new information in the form of a leader bird.
@@ -0,0 +1,79 @@
1
+
2
+
3
+ # High Performance C++ Flocking Simulation for Stochastic Modelling
4
+ > *Michael Stavreff,*
5
+ > *December 17, 2025*
6
+ ## Development & Compilation
7
+
8
+ This project uses **CMake** and a **Makefile** to manage the C++ build process, dependencies (Eigen, pybind11), and performance optimizations.
9
+
10
+ ### Prerequisites
11
+
12
+ To build the project from source, you will need:
13
+ * **C++20 Compiler** (GCC 10+ or Clang 11+)
14
+ * **CMake** (3.18+)
15
+ * **Python 3.8+** (with `python3-venv` and `python3-dev`)
16
+ * **SFML 2.5** (Optional: only required for the visual standalone solver)
17
+ ```bash
18
+ sudo apt install libsfml-dev
19
+ ```
20
+
21
+ ### Developer Setup
22
+ 1. Clone and create a virtual environment:
23
+
24
+ ```Bash
25
+ git clone https://github.com/Mstavreff/stochastic_flock.git
26
+ cd stochastic_flock
27
+ python3 -m venv .venv
28
+ source .venv/bin/activate
29
+ ```
30
+ 2. Install build dependencies:
31
+ ```Bash
32
+ pip install -r requirements.txt
33
+ ```
34
+
35
+ ### Building the Project
36
+ The provided Makefile contains shortcuts for common build scenarios.
37
+ 1. Standard Build (Python + C++ Solver)
38
+ Compiles the Python module into the root directory and the standalone solver into build/.
39
+
40
+ ```Bash
41
+ make
42
+ ```
43
+ 2. Native Hardware Optimization
44
+ Compiles using -march=native and -ffast-math. This produces the fastest possible binary for your specific CPU but is not portable to other hardware.
45
+
46
+ ```Bash
47
+ make native
48
+ ```
49
+ 3. Profile-Guided Optimization (PGO) + Native
50
+ For maximum performance, use PGO to optimize code paths based on simulation data. Uses ```tuning.py``` to instrument and recompiles using native flags.
51
+ ```Bash
52
+ make pgo
53
+ ```
54
+ 4. Debug Mode
55
+ Compiles with debug symbols (-g) and Undefined Behavior Sanitizers for use with GDB/LLDB.
56
+
57
+ ```Bash
58
+ make debug
59
+ ```
60
+ ### Python Usage
61
+
62
+ If you simply wish to use the simulation in a Python environment without modifying the C++ source:
63
+
64
+ ```Bash
65
+ pip install stochastic_flock
66
+ ```
67
+ For local development, after running make, you can import the module directly in the root directory:
68
+
69
+ ```Python
70
+ >>> import stochastic_flock
71
+ >>> sim = stochastic_flock.Simulation2d(params, seed)
72
+ ```
73
+ ## Introduction
74
+ Financial markets have famously exhibited flocking or herding behavior, most famously during crises and impending crashes. Such movements typically are completely unpredictable; the aim of this paper is to explore whether these movements are compltely unable to be modelled or are instead the product of some highly non-linear behavior requiring a novel approach. Naturally, birds in large flocks are an interesting candidate to model such emergent behavior in financial markets. Large flocks exhibit features which must be re-interpreted to a financial context, particularly in attraction, repulsion, turning behavior, and in the context of the particular paper, leader/follower dynamics:
75
+
76
+ ### Reference Paper Overview
77
+ *The original paper is given here: https://arxiv.org/abs/2010.01990.* While the paper is short and concise and absolutely worth a read, some important details will be repeated.
78
+
79
+ Cristiani et al.'s paper puts forward a second-order, delayed, stochastic differential equation to describe accelerations of bird agents. The stochastic element stems from birds having an exponential process (geometric in approximation) describing a follower -> leader transition where any attractive forces are dropped in their acceleration calculation and causing only repulsive-force trajectories. Additionally, birds react to the positions of others in a rank-ordered system of the nearest M birds, irregardless of distance; they also react to the delayed positions rather than the most instant information, something which creates more heavy movements and drifting of flocks in practice. These behaviors underline various interpretations worth discussing in the paper, mostly regarding trader behaviors or modelling portfolios of correlated equities in a sector which may be driven by such "social" forces and similarly experience shocks or new information in the form of a leader bird.
@@ -0,0 +1,23 @@
1
+ [build-system]
2
+ requires = ["scikit-build-core>=0.8", "pybind11"]
3
+ build-backend = "scikit_build_core.build"
4
+
5
+
6
+ [project]
7
+ name = "stochastic_flock"
8
+ version = "0.1.0"
9
+ description = "Unified Bird Flocking Simulation (1D & 2D)"
10
+ readme = "README.md"
11
+ requires-python = ">=3.8"
12
+ authors = [
13
+ {name = "Michael Stavreff", email = "Mstavreff@outlook.com"},
14
+ ]
15
+ dependencies = [
16
+ "numpy",
17
+ ]
18
+
19
+ [tool.scikit-build]
20
+ wheel.packages = ["src/stochastic_flock"]
21
+ editable.mode = "redirect"
22
+ cmake.args = ["-DSKBUILD=ON"]
23
+ build-dir = "build/{wheel_tag}"
@@ -0,0 +1,11 @@
1
+ # Tools to bridge C++ and Python
2
+ pybind11
3
+ scikit-build-core
4
+ ninja # Recommended for faster builds
5
+
6
+ numpy
7
+ eigen
8
+
9
+ # Tools for PyPi development
10
+ build
11
+ twine
@@ -0,0 +1,47 @@
1
+ #include "constants.hpp"
2
+ #include "simulation.hpp"
3
+ #include "visual.hpp"
4
+
5
+ #include <Eigen/Dense>
6
+ #include <SFML/Graphics.hpp>
7
+ #include <format>
8
+ #include <random>
9
+ #include <stdexcept>
10
+ #include <string>
11
+ #include <vector>
12
+
13
+ int main()
14
+ {
15
+
16
+ Parameters p;
17
+ int n_birds = 500;
18
+ double att = 0.03;
19
+ double rep = 2.5;
20
+ std::cout << "birds: ";
21
+ std::cin >> n_birds;
22
+ std::cout << "\n";
23
+ std::cout << "attraction: ";
24
+ std::cin >> att;
25
+ std::cout << "\n";
26
+ std::cout << "repulsion: ";
27
+ std::cin >> rep;
28
+ std::cout << "\n";
29
+
30
+ p.kWIDTH_2D = 2100;
31
+ p.kHEIGHT_2D = 1300;
32
+ p.kREP = rep;
33
+ p.kATT = att;
34
+ p.kFRAMERATE = 1000;
35
+ p.kN_BIRDS = n_birds;
36
+ p.kROUNDS = 1000000;
37
+ std::mt19937 mt;
38
+ mt.seed(std::random_device{}());
39
+ // mt.seed(50);
40
+
41
+ Eigen::Matrix<double, Eigen::Dynamic, 4> positions;
42
+ positions.resize(p.kN_BIRDS, 4);
43
+ positions = positions.setRandom() * 100;
44
+
45
+ Simulation2d<> Sim(p, mt, positions);
46
+ init_simulation(Sim);
47
+ }
@@ -0,0 +1,9 @@
1
+ #pragma once
2
+
3
+ inline constexpr int kFRAMERATE{60};
4
+ inline constexpr int kROUNDS{10000};
5
+ // Higher dimensional parameters
6
+ inline constexpr int kTREE_MEDIAN_SAMPLE{30}; // could profile
7
+ inline constexpr int kLEAF_SIZE{16}; // double once using floats to fit SIMD registers better, could profile
8
+ inline constexpr double kPRUNE_EPS{0.01}; // for approximate KD tree pruning
9
+ inline constexpr double kAPPROX_PRUNE_FACTOR{1.0 / ((1.0 + kPRUNE_EPS) * (1.0 + kPRUNE_EPS))};
@@ -0,0 +1,74 @@
1
+ #include "simulation.hpp"
2
+ // #include "visual.hpp"
3
+ #include <pybind11/eigen.h>
4
+ #include <pybind11/pybind11.h>
5
+ #include <pybind11/stl.h>
6
+
7
+ namespace py = pybind11;
8
+ using Sim1d = Simulation1d<Eigen::Dynamic>;
9
+ using Sim2d = Simulation2d<Eigen::Dynamic>;
10
+ void init_simulation(Sim2d &sim);
11
+
12
+ void bind_parameters(py::module &m)
13
+ {
14
+ py::class_<Parameters>(m, "Parameters")
15
+ .def(py::init<>())
16
+ .def_readwrite("kN_BIRDS", &Parameters::kN_BIRDS)
17
+ .def_readwrite("kM", &Parameters::kM)
18
+ .def_readwrite("kDELAY", &Parameters::kDELAY)
19
+ .def_readwrite("kPT", &Parameters::kPT)
20
+ .def_readwrite("kPD", &Parameters::kPD)
21
+ .def_readwrite("kRT", &Parameters::kRT)
22
+ .def_readwrite("kREP", &Parameters::kREP)
23
+ .def_readwrite("kALI", &Parameters::kALI)
24
+ .def_readwrite("kATT", &Parameters::kATT)
25
+ .def_readwrite("kTIMESTEP", &Parameters::kTIMESTEP)
26
+ .def_readwrite("kROUNDS", &Parameters::kROUNDS)
27
+ .def_readwrite("kPROBABILITY", &Parameters::kPROBABILITY)
28
+ .def_readwrite("kBOX_SIZE", &Parameters::kBOX_SIZE)
29
+ .def_readwrite("kEPSILON", &Parameters::kEPSILON)
30
+ .def_readwrite("kBUFFER_CYCLES", &Parameters::kBUFFER_CYCLES); // must be calculated manually in python
31
+ }
32
+
33
+ PYBIND11_MODULE(stochastic_flock, m)
34
+ {
35
+ m.doc() = "Agent-Based Bird Flocking Simulation";
36
+
37
+ bind_parameters(m);
38
+
39
+ py::class_<std::mt19937>(m, "MT19937").def(py::init<uint32_t>());
40
+
41
+ // py::class_<Sim1d>(m, "Simulation1d")
42
+ // .def(py::init<Parameters &, std::mt19937 &>())
43
+ // .def("update",
44
+ // [](Sim1d &self) {
45
+ // self.update_state();
46
+ // self.shift_back();
47
+ // })
48
+ // .def_property_readonly("states", [](Sim1d &self) { return self.states; })
49
+ // .def_property_readonly("positions", [](Sim1d &self) { return self.states.col(0); })
50
+ // .def_property_readonly("velocities", [](Sim1d &self) { return self.states.col(1); })
51
+ // .def_property_readonly("status", [](Sim1d &self) { return self.states.col(2); })
52
+ // .def_property_readonly("timers", [](Sim1d &self) { return self.timer_states; });
53
+
54
+ py::class_<Sim2d>(m, "Simulation2d")
55
+ .def(py::init<Parameters &, std::mt19937 &, const std::optional<Eigen::Matrix<double, Eigen::Dynamic, 4>> &>(),
56
+ py::arg("params"), py::arg("seed"), py::arg("start_conditions") = std::nullopt)
57
+ .def("update",
58
+ [](Sim2d &self) {
59
+ self.update_state();
60
+ self.shift_back();
61
+ })
62
+ .def("debug_tree", &Sim2d::debug_print_tree, py::arg("i") = 0, py::arg("indent") = 0)
63
+ // .def("show",
64
+ // [](Sim2d &self) {
65
+ // py::gil_scoped_release release; // Allows other Python threads to run while window is open
66
+ // init_simulation_fontless(self);
67
+ // })
68
+
69
+ .def_property_readonly("states", [](Sim2d &self) { return self.states; })
70
+ .def_property_readonly("positions", [](Sim2d &self) { return self.states.leftCols(2); })
71
+ .def_property_readonly("velocities", [](Sim2d &self) { return self.states.middleCols(2, 2); })
72
+ .def_property_readonly("status", [](Sim2d &self) { return self.states.col(4); })
73
+ .def_property_readonly("timers", [](Sim2d &self) { return self.timer_states; });
74
+ }