From cc4949d7c972d018ec215511c3ba79d004cd900f Mon Sep 17 00:00:00 2001 From: Hydrodynamical Date: Tue, 20 Oct 2026 20:02:23 -0400 Subject: [PATCH 1/2] Extract reusable graphon control core and validate numerical workflows --- .github/workflows/tests.yml | 21 + README.md | 11 +- collect_paper_figures.sh | 36 +- docs/DEVELOPMENT.md | 97 ++ docs/NUMERICS.md | 75 ++ e1_kuramoto.py | 782 +----------- e1_msweep.py | 377 +++--- e1_noise_figure.py | 159 ++- e2_bc.py | 895 +------------- graphon_control/__init__.py | 15 + graphon_control/artifacts.py | 278 +++++ graphon_control/cli.py | 54 + graphon_control/controls.py | 200 +++ graphon_control/diagnostics.py | 33 + graphon_control/dynamics.py | 125 ++ graphon_control/experiments/__init__.py | 1 + .../experiments/bounded_confidence.py | 537 ++++++++ .../experiments/bounded_confidence_plots.py | 254 ++++ graphon_control/experiments/generic.py | 256 ++++ graphon_control/experiments/kuramoto.py | 463 +++++++ graphon_control/experiments/kuramoto_plots.py | 214 ++++ graphon_control/initial_conditions.py | 72 ++ graphon_control/interactions.py | 24 + graphon_control/objectives.py | 179 +++ graphon_control/plotting.py | 508 ++++++++ graphon_control/training.py | 76 ++ graphon_control/validation.py | 83 ++ model_1.py | 1083 +---------------- model_1_viz.py | 500 +------- pyproject.toml | 31 + requirements-tested.txt | 7 + tests/conftest.py | 7 + tests/test_artifacts.py | 228 ++++ tests/test_controls.py | 194 +++ tests/test_experiments.py | 148 +++ tests/test_numerics.py | 211 ++++ tests/test_package.py | 95 ++ tests/test_plotting.py | 80 ++ tests/test_training.py | 65 + tests/test_workflows.py | 133 ++ 40 files changed, 5140 insertions(+), 3467 deletions(-) create mode 100644 .github/workflows/tests.yml create mode 100644 docs/DEVELOPMENT.md create mode 100644 docs/NUMERICS.md create mode 100644 graphon_control/__init__.py create mode 100644 graphon_control/artifacts.py create mode 100644 graphon_control/cli.py create mode 100644 graphon_control/controls.py create mode 100644 graphon_control/diagnostics.py create mode 100644 graphon_control/dynamics.py create mode 100644 graphon_control/experiments/__init__.py create mode 100644 graphon_control/experiments/bounded_confidence.py create mode 100644 graphon_control/experiments/bounded_confidence_plots.py create mode 100644 graphon_control/experiments/generic.py create mode 100644 graphon_control/experiments/kuramoto.py create mode 100644 graphon_control/experiments/kuramoto_plots.py create mode 100644 graphon_control/initial_conditions.py create mode 100644 graphon_control/interactions.py create mode 100644 graphon_control/objectives.py create mode 100644 graphon_control/plotting.py create mode 100644 graphon_control/training.py create mode 100644 graphon_control/validation.py create mode 100644 pyproject.toml create mode 100644 requirements-tested.txt create mode 100644 tests/conftest.py create mode 100644 tests/test_artifacts.py create mode 100644 tests/test_controls.py create mode 100644 tests/test_experiments.py create mode 100644 tests/test_numerics.py create mode 100644 tests/test_package.py create mode 100644 tests/test_plotting.py create mode 100644 tests/test_training.py create mode 100644 tests/test_workflows.py diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..112bcd8 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,21 @@ +name: Numerical checks +on: [push, pull_request] +jobs: + test: + runs-on: ubuntu-latest + env: + MPLBACKEND: Agg + OMP_NUM_THREADS: '1' + MKL_NUM_THREADS: '1' + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.12' + cache: pip + - run: python -m pip install --index-url https://download.pytorch.org/whl/cpu torch==2.14.1 + - run: python -m pip install -r requirements-tested.txt + - run: python -m pip install --no-deps -e . + - run: python -m pytest + - run: python e1_kuramoto.py --smoke --no-plots --no-mirror --out-root smoke-results + - run: python e2_bc.py --smoke --no-plots --no-mirror --out-root smoke-results diff --git a/README.md b/README.md index 8b1d114..9df3ad6 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ A PyTorch research implementation that learns how agents influence one another over time. It combines neural interaction kernels, differentiable simulation, and stochastic optimization. -Companion code for *Graphon Controlled Opinion Dynamics*, by **Joseph K. Miller and Brandon Su**. +Companion code for *Optimal Graphon Control of Collective Dynamics*, by **Joseph K. Miller and Brandon Su**. ## Experiments @@ -26,22 +26,23 @@ From the repository root: ```bash python3 -m venv .venv source .venv/bin/activate -python -m pip install torch numpy matplotlib tqdm pillow +python -m pip install -e . python e1_kuramoto.py --smoke --device cpu --no-mirror ``` -This runs a 20-iteration workflow check. Results appear under `out_1/`, including `untwist.gif`, `kernel_time.gif`, and `metrics.json`. +This runs a 20-iteration workflow check on a small grid and network. Results appear under `out_1/`, including `untwist.gif`, `kernel_time.gif`, and `metrics.json`. ## Code | File | Contents | | --- | --- | -| `model_1.py` | Neural controller, simulation, and training | +| `graphon_control/` | Reusable controller, dynamics, objectives, and training | +| `model_1.py` | General experiment entry point | | `e1_kuramoto.py` | Oscillator experiment | | `e2_bc.py` | Opinion dynamics experiment | | `model_1_viz.py` | Visualization utilities | -Use `python