Mesa 3.1.2__tar.gz → 3.1.3__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.

Potentially problematic release.


This version of Mesa might be problematic. Click here for more details.

Files changed (189) hide show
  1. {mesa-3.1.2 → mesa-3.1.3}/.pre-commit-config.yaml +2 -2
  2. {mesa-3.1.2 → mesa-3.1.3}/CONTRIBUTING.md +2 -0
  3. {mesa-3.1.2 → mesa-3.1.3}/HISTORY.md +54 -0
  4. {mesa-3.1.2 → mesa-3.1.3}/PKG-INFO +2 -1
  5. {mesa-3.1.2 → mesa-3.1.3}/benchmarks/configurations.py +7 -2
  6. {mesa-3.1.2 → mesa-3.1.3}/docs/apis/experimental.md +12 -0
  7. {mesa-3.1.2 → mesa-3.1.3}/mesa/__init__.py +1 -1
  8. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/boid_flockers/agents.py +26 -38
  9. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/boid_flockers/app.py +6 -1
  10. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/boid_flockers/model.py +30 -37
  11. {mesa-3.1.2 → mesa-3.1.3}/mesa/experimental/__init__.py +2 -2
  12. {mesa-3.1.2 → mesa-3.1.3}/mesa/experimental/cell_space/voronoi.py +1 -4
  13. mesa-3.1.3/mesa/experimental/continuous_space/__init__.py +8 -0
  14. mesa-3.1.3/mesa/experimental/continuous_space/continuous_space.py +273 -0
  15. mesa-3.1.3/mesa/experimental/continuous_space/continuous_space_agents.py +101 -0
  16. {mesa-3.1.2 → mesa-3.1.3}/mesa/model.py +1 -1
  17. {mesa-3.1.2 → mesa-3.1.3}/mesa/space.py +7 -0
  18. {mesa-3.1.2 → mesa-3.1.3}/mesa/visualization/mpl_space_drawing.py +22 -12
  19. {mesa-3.1.2 → mesa-3.1.3}/mesa/visualization/solara_viz.py +30 -7
  20. {mesa-3.1.2 → mesa-3.1.3}/pyproject.toml +1 -0
  21. mesa-3.1.3/tests/test_continuous_space.py +432 -0
  22. {mesa-3.1.2 → mesa-3.1.3}/tests/test_model.py +12 -0
  23. {mesa-3.1.2 → mesa-3.1.3}/.codespellignore +0 -0
  24. {mesa-3.1.2 → mesa-3.1.3}/.coveragerc +0 -0
  25. {mesa-3.1.2 → mesa-3.1.3}/.github/ISSUE_TEMPLATE/bug-report.md +0 -0
  26. {mesa-3.1.2 → mesa-3.1.3}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  27. {mesa-3.1.2 → mesa-3.1.3}/.github/ISSUE_TEMPLATE/feature-request.md +0 -0
  28. {mesa-3.1.2 → mesa-3.1.3}/.github/PULL_REQUEST_TEMPLATE/bug.md +0 -0
  29. {mesa-3.1.2 → mesa-3.1.3}/.github/PULL_REQUEST_TEMPLATE/feature.md +0 -0
  30. {mesa-3.1.2 → mesa-3.1.3}/.github/dependabot.yml +0 -0
  31. {mesa-3.1.2 → mesa-3.1.3}/.github/pull_request_template.md +0 -0
  32. {mesa-3.1.2 → mesa-3.1.3}/.github/release.yml +0 -0
  33. {mesa-3.1.2 → mesa-3.1.3}/.github/workflows/benchmarks.yml +0 -0
  34. {mesa-3.1.2 → mesa-3.1.3}/.github/workflows/build_lint.yml +0 -0
  35. {mesa-3.1.2 → mesa-3.1.3}/.github/workflows/release.yml +0 -0
  36. {mesa-3.1.2 → mesa-3.1.3}/.gitignore +0 -0
  37. {mesa-3.1.2 → mesa-3.1.3}/.readthedocs.yml +0 -0
  38. {mesa-3.1.2 → mesa-3.1.3}/CITATION.bib +0 -0
  39. {mesa-3.1.2 → mesa-3.1.3}/CODE_OF_CONDUCT.md +0 -0
  40. {mesa-3.1.2 → mesa-3.1.3}/Dockerfile +0 -0
  41. {mesa-3.1.2 → mesa-3.1.3}/LICENSE +0 -0
  42. {mesa-3.1.2 → mesa-3.1.3}/NOTICE +0 -0
  43. {mesa-3.1.2 → mesa-3.1.3}/README.md +0 -0
  44. {mesa-3.1.2 → mesa-3.1.3}/benchmarks/compare_timings.py +0 -0
  45. {mesa-3.1.2 → mesa-3.1.3}/benchmarks/global_benchmark.py +0 -0
  46. {mesa-3.1.2 → mesa-3.1.3}/binder/environment.yml +0 -0
  47. {mesa-3.1.2 → mesa-3.1.3}/codecov.yaml +0 -0
  48. {mesa-3.1.2 → mesa-3.1.3}/docker-compose.yml +0 -0
  49. {mesa-3.1.2 → mesa-3.1.3}/docs/Makefile +0 -0
  50. {mesa-3.1.2 → mesa-3.1.3}/docs/README.md +0 -0
  51. {mesa-3.1.2 → mesa-3.1.3}/docs/_static/switcher.json +0 -0
  52. {mesa-3.1.2 → mesa-3.1.3}/docs/apis/agent.md +0 -0
  53. {mesa-3.1.2 → mesa-3.1.3}/docs/apis/api_main.md +0 -0
  54. {mesa-3.1.2 → mesa-3.1.3}/docs/apis/batchrunner.md +0 -0
  55. {mesa-3.1.2 → mesa-3.1.3}/docs/apis/datacollection.md +0 -0
  56. {mesa-3.1.2 → mesa-3.1.3}/docs/apis/mesa_logging.md +0 -0
  57. {mesa-3.1.2 → mesa-3.1.3}/docs/apis/model.md +0 -0
  58. {mesa-3.1.2 → mesa-3.1.3}/docs/apis/space.md +0 -0
  59. {mesa-3.1.2 → mesa-3.1.3}/docs/apis/visualization.md +0 -0
  60. {mesa-3.1.2 → mesa-3.1.3}/docs/best-practices.md +0 -0
  61. {mesa-3.1.2 → mesa-3.1.3}/docs/conf.py +0 -0
  62. {mesa-3.1.2 → mesa-3.1.3}/docs/example_template.txt +0 -0
  63. {mesa-3.1.2 → mesa-3.1.3}/docs/examples_overview_template.txt +0 -0
  64. {mesa-3.1.2 → mesa-3.1.3}/docs/getting_started.md +0 -0
  65. {mesa-3.1.2 → mesa-3.1.3}/docs/images/mesa_logo.ico +0 -0
  66. {mesa-3.1.2 → mesa-3.1.3}/docs/images/mesa_logo.png +0 -0
  67. {mesa-3.1.2 → mesa-3.1.3}/docs/images/tutorial/br_ginis.png +0 -0
  68. {mesa-3.1.2 → mesa-3.1.3}/docs/images/tutorial/dc_endwealth.png +0 -0
  69. {mesa-3.1.2 → mesa-3.1.3}/docs/images/tutorial/dc_gini.png +0 -0
  70. {mesa-3.1.2 → mesa-3.1.3}/docs/images/tutorial/dc_oneagent.png +0 -0
  71. {mesa-3.1.2 → mesa-3.1.3}/docs/images/tutorial/first_hist.png +0 -0
  72. {mesa-3.1.2 → mesa-3.1.3}/docs/images/tutorial/multirun_hist.png +0 -0
  73. {mesa-3.1.2 → mesa-3.1.3}/docs/images/tutorial/numpy_grid.png +0 -0
  74. {mesa-3.1.2 → mesa-3.1.3}/docs/images/tutorial/viz_chart.png +0 -0
  75. {mesa-3.1.2 → mesa-3.1.3}/docs/images/tutorial/viz_empty.png +0 -0
  76. {mesa-3.1.2 → mesa-3.1.3}/docs/images/tutorial/viz_greycircles.png +0 -0
  77. {mesa-3.1.2 → mesa-3.1.3}/docs/images/tutorial/viz_histogram.png +0 -0
  78. {mesa-3.1.2 → mesa-3.1.3}/docs/images/tutorial/viz_redcircles.png +0 -0
  79. {mesa-3.1.2 → mesa-3.1.3}/docs/images/wolf_sheep.png +0 -0
  80. {mesa-3.1.2 → mesa-3.1.3}/docs/index.md +0 -0
  81. {mesa-3.1.2 → mesa-3.1.3}/docs/make.bat +0 -0
  82. {mesa-3.1.2 → mesa-3.1.3}/docs/mesa.md +0 -0
  83. {mesa-3.1.2 → mesa-3.1.3}/docs/migration_guide.md +0 -0
  84. {mesa-3.1.2 → mesa-3.1.3}/docs/tutorials/MoneyModel.py +0 -0
  85. {mesa-3.1.2 → mesa-3.1.3}/docs/tutorials/files/viz_chart.png +0 -0
  86. {mesa-3.1.2 → mesa-3.1.3}/docs/tutorials/files/viz_empty.png +0 -0
  87. {mesa-3.1.2 → mesa-3.1.3}/docs/tutorials/files/viz_greycircles.png +0 -0
  88. {mesa-3.1.2 → mesa-3.1.3}/docs/tutorials/files/viz_histogram.png +0 -0
  89. {mesa-3.1.2 → mesa-3.1.3}/docs/tutorials/files/viz_redcircles.png +0 -0
  90. {mesa-3.1.2 → mesa-3.1.3}/docs/tutorials/files/viz_slider.png +0 -0
  91. {mesa-3.1.2 → mesa-3.1.3}/docs/tutorials/intro_tutorial.ipynb +0 -0
  92. {mesa-3.1.2 → mesa-3.1.3}/docs/tutorials/visualization_tutorial.ipynb +0 -0
  93. {mesa-3.1.2 → mesa-3.1.3}/maintenance/fetch_unlabeled_prs.py +0 -0
  94. {mesa-3.1.2 → mesa-3.1.3}/mesa/agent.py +0 -0
  95. {mesa-3.1.2 → mesa-3.1.3}/mesa/batchrunner.py +0 -0
  96. {mesa-3.1.2 → mesa-3.1.3}/mesa/datacollection.py +0 -0
  97. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/README.md +0 -0
  98. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/__init__.py +0 -0
  99. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/__init__.py +0 -0
  100. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/epstein_civil_violence/Epstein Civil Violence.ipynb +0 -0
  101. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/epstein_civil_violence/Readme.md +0 -0
  102. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/epstein_civil_violence/__init__.py +0 -0
  103. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/epstein_civil_violence/agents.py +0 -0
  104. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/epstein_civil_violence/app.py +0 -0
  105. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/epstein_civil_violence/model.py +0 -0
  106. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/pd_grid/Readme.md +0 -0
  107. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/pd_grid/__init__.py +0 -0
  108. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/pd_grid/agents.py +0 -0
  109. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/pd_grid/analysis.ipynb +0 -0
  110. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/pd_grid/app.py +0 -0
  111. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/pd_grid/model.py +0 -0
  112. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/sugarscape_g1mt/Readme.md +0 -0
  113. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/sugarscape_g1mt/__init__.py +0 -0
  114. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/sugarscape_g1mt/agents.py +0 -0
  115. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/sugarscape_g1mt/app.py +0 -0
  116. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/sugarscape_g1mt/model.py +0 -0
  117. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/sugarscape_g1mt/sugar-map.txt +0 -0
  118. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/sugarscape_g1mt/tests.py +0 -0
  119. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/wolf_sheep/Readme.md +0 -0
  120. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/wolf_sheep/__init__.py +0 -0
  121. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/wolf_sheep/agents.py +0 -0
  122. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/wolf_sheep/app.py +0 -0
  123. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/wolf_sheep/model.py +0 -0
  124. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/__init__.py +0 -0
  125. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/boid_flockers/Readme.md +0 -0
  126. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/boid_flockers/__init__.py +0 -0
  127. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/boltzmann_wealth_model/Readme.md +0 -0
  128. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/boltzmann_wealth_model/__init__.py +0 -0
  129. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/boltzmann_wealth_model/agents.py +0 -0
  130. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/boltzmann_wealth_model/app.py +0 -0
  131. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/boltzmann_wealth_model/model.py +0 -0
  132. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/boltzmann_wealth_model/st_app.py +0 -0
  133. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/conways_game_of_life/Readme.md +0 -0
  134. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/conways_game_of_life/__init__.py +0 -0
  135. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/conways_game_of_life/agents.py +0 -0
  136. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/conways_game_of_life/app.py +0 -0
  137. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/conways_game_of_life/model.py +0 -0
  138. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/conways_game_of_life/st_app.py +0 -0
  139. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/schelling/Readme.md +0 -0
  140. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/schelling/__init__.py +0 -0
  141. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/schelling/agents.py +0 -0
  142. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/schelling/analysis.ipynb +0 -0
  143. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/schelling/app.py +0 -0
  144. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/schelling/model.py +0 -0
  145. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/virus_on_network/Readme.md +0 -0
  146. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/virus_on_network/__init__.py +0 -0
  147. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/virus_on_network/agents.py +0 -0
  148. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/virus_on_network/app.py +0 -0
  149. {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/virus_on_network/model.py +0 -0
  150. {mesa-3.1.2 → mesa-3.1.3}/mesa/experimental/cell_space/__init__.py +0 -0
  151. {mesa-3.1.2 → mesa-3.1.3}/mesa/experimental/cell_space/cell.py +0 -0
  152. {mesa-3.1.2 → mesa-3.1.3}/mesa/experimental/cell_space/cell_agent.py +0 -0
  153. {mesa-3.1.2 → mesa-3.1.3}/mesa/experimental/cell_space/cell_collection.py +0 -0
  154. {mesa-3.1.2 → mesa-3.1.3}/mesa/experimental/cell_space/discrete_space.py +0 -0
  155. {mesa-3.1.2 → mesa-3.1.3}/mesa/experimental/cell_space/grid.py +0 -0
  156. {mesa-3.1.2 → mesa-3.1.3}/mesa/experimental/cell_space/network.py +0 -0
  157. {mesa-3.1.2 → mesa-3.1.3}/mesa/experimental/cell_space/property_layer.py +0 -0
  158. {mesa-3.1.2 → mesa-3.1.3}/mesa/experimental/devs/__init__.py +0 -0
  159. {mesa-3.1.2 → mesa-3.1.3}/mesa/experimental/devs/eventlist.py +0 -0
  160. {mesa-3.1.2 → mesa-3.1.3}/mesa/experimental/devs/simulator.py +0 -0
  161. {mesa-3.1.2 → mesa-3.1.3}/mesa/experimental/mesa_signals/__init__.py +0 -0
  162. {mesa-3.1.2 → mesa-3.1.3}/mesa/experimental/mesa_signals/mesa_signal.py +0 -0
  163. {mesa-3.1.2 → mesa-3.1.3}/mesa/experimental/mesa_signals/observable_collections.py +0 -0
  164. {mesa-3.1.2 → mesa-3.1.3}/mesa/experimental/mesa_signals/signals_util.py +0 -0
  165. {mesa-3.1.2 → mesa-3.1.3}/mesa/mesa_logging.py +0 -0
  166. {mesa-3.1.2 → mesa-3.1.3}/mesa/visualization/__init__.py +0 -0
  167. {mesa-3.1.2 → mesa-3.1.3}/mesa/visualization/components/__init__.py +0 -0
  168. {mesa-3.1.2 → mesa-3.1.3}/mesa/visualization/components/altair_components.py +0 -0
  169. {mesa-3.1.2 → mesa-3.1.3}/mesa/visualization/components/matplotlib_components.py +0 -0
  170. {mesa-3.1.2 → mesa-3.1.3}/mesa/visualization/user_param.py +0 -0
  171. {mesa-3.1.2 → mesa-3.1.3}/mesa/visualization/utils.py +0 -0
  172. {mesa-3.1.2 → mesa-3.1.3}/mypy.ini +0 -0
  173. {mesa-3.1.2 → mesa-3.1.3}/tests/__init__.py +0 -0
  174. {mesa-3.1.2 → mesa-3.1.3}/tests/read_requirements.py +0 -0
  175. {mesa-3.1.2 → mesa-3.1.3}/tests/test_agent.py +0 -0
  176. {mesa-3.1.2 → mesa-3.1.3}/tests/test_batch_run.py +0 -0
  177. {mesa-3.1.2 → mesa-3.1.3}/tests/test_cell_space.py +0 -0
  178. {mesa-3.1.2 → mesa-3.1.3}/tests/test_components_matplotlib.py +0 -0
  179. {mesa-3.1.2 → mesa-3.1.3}/tests/test_datacollector.py +0 -0
  180. {mesa-3.1.2 → mesa-3.1.3}/tests/test_devs.py +0 -0
  181. {mesa-3.1.2 → mesa-3.1.3}/tests/test_end_to_end_viz.sh +0 -0
  182. {mesa-3.1.2 → mesa-3.1.3}/tests/test_examples.py +0 -0
  183. {mesa-3.1.2 → mesa-3.1.3}/tests/test_grid.py +0 -0
  184. {mesa-3.1.2 → mesa-3.1.3}/tests/test_import_namespace.py +0 -0
  185. {mesa-3.1.2 → mesa-3.1.3}/tests/test_lifespan.py +0 -0
  186. {mesa-3.1.2 → mesa-3.1.3}/tests/test_mesa_logging.py +0 -0
  187. {mesa-3.1.2 → mesa-3.1.3}/tests/test_mesa_signals.py +0 -0
  188. {mesa-3.1.2 → mesa-3.1.3}/tests/test_solara_viz.py +0 -0
  189. {mesa-3.1.2 → mesa-3.1.3}/tests/test_space.py +0 -0
@@ -4,7 +4,7 @@ ci:
4
4
  repos:
5
5
  - repo: https://github.com/astral-sh/ruff-pre-commit
6
6
  # Ruff version.
7
- rev: v0.8.1
7
+ rev: v0.8.6
8
8
  hooks:
9
9
  # Run the linter.
10
10
  - id: ruff
@@ -14,7 +14,7 @@ repos:
14
14
  - id: ruff-format
15
15
  types_or: [ python, pyi, jupyter ]
16
16
  - repo: https://github.com/asottile/pyupgrade
17
- rev: v3.19.0
17
+ rev: v3.19.1
18
18
  hooks:
19
19
  - id: pyupgrade
20
20
  args: [--py311-plus]
@@ -137,6 +137,8 @@ To create a new release, follow these steps:
137
137
  9. The [`release.yml`](https://github.com/projectmesa/mesa/blob/main/.github/workflows/release.yml) CI workflow should automatically create and upload the package to PyPI. Verify this on [PyPI.org](https://pypi.org/project/mesa/).
138
138
  10. Finally, after release, open a new PR to update the version number in [`mesa/__init__.py`](https://github.com/projectmesa/mesa/blob/main/mesa/__init__.py) for the next release (e.g., `"3.1.0.dev"`).
139
139
 
140
+ A recorded video of this process is [available here](https://youtu.be/JE44jkegmns).
141
+
140
142
  ## Special Thanks
141
143
 
142
144
  A special thanks to the following projects who offered inspiration for this contributing file.
@@ -1,6 +1,60 @@
1
1
  ---
2
2
  title: Release History
3
3
  ---
4
+ # 3.1.3 (2025-01-11)
5
+ ## Highlights
6
+ Mesa 3.1.3 introduces a major experimental reimplementation of Mesa's continuous space, providing an intuitive agent-centric API and significant performance improvements. The new implementation supports n-dimensional spaces and offers streamlined methods for agent movement and neighbor calculations.
7
+
8
+ ### New Continuous Space Features
9
+ - Agent-centric movement API similar to cell spaces
10
+ - Efficient neighbor calculations and position updates
11
+ - Support for n-dimensional spaces
12
+ - Improved memory management with dynamic array resizing
13
+
14
+ Here's a quick look at the new API:
15
+
16
+ ```python
17
+ # Create a 2D continuous space
18
+ space = ContinuousSpace(
19
+ dimensions=[[0, 1], [0, 1]],
20
+ torus=True,
21
+ random=model.random
22
+ )
23
+
24
+ # Create and position an agent
25
+ agent = ContinuousSpaceAgent(space, model)
26
+ agent.position = [0.5, 0.5]
27
+
28
+ # Move agent using vector arithmetic
29
+ agent.position += [0.1, 0.1]
30
+
31
+ # Get neighbors within radius
32
+ neighbors, distances = agent.get_neighbors_in_radius(radius=0.2)
33
+
34
+ # Find k nearest neighbors
35
+ nearest, distances = agent.get_nearest_neighbors(k=5)
36
+ ```
37
+
38
+ The new implementation particularly benefits models requiring frequent position updates and neighbor queries, such as flocking simulations or particle systems. See [#2584](https://github.com/projectmesa/mesa/pull/2584) for more details. We would love to get feedback on the new Continuous Space in [#2611](https://github.com/projectmesa/mesa/discussions/2611).
39
+
40
+ Other improvements in this release include consistent visualization behavior across space types with the reimplementation of `draw_voronoi` [#2608](https://github.com/projectmesa/mesa/pull/2608), and a new render interval slider for controlling visualization update frequency in SolaraViz, which helps improve performance when working with complex visualizations [#2596](https://github.com/projectmesa/mesa/pull/2596). We've also fixed a bug affecting random number generation determinism when using `Model(seed=something)`, ensuring both `model.random` and `model.rng` now behave consistently when seeded with the same initial value [#2598](https://github.com/projectmesa/mesa/pull/2598).
41
+
42
+ ## What's Changed
43
+ ### 🧪 Experimental features
44
+ * Reimplementation of Continuous Space by @quaquel in https://github.com/projectmesa/mesa/pull/2584
45
+ ### 🛠 Enhancements made
46
+ * reimplementation of draw_voroinoi by @quaquel in https://github.com/projectmesa/mesa/pull/2608
47
+ * Add render interval slider to control visualization update frequency by @HMNS19 in https://github.com/projectmesa/mesa/pull/2596
48
+ ### 🐛 Bugs fixed
49
+ * Bugfix for non deterministic rng behavior by @quaquel in https://github.com/projectmesa/mesa/pull/2598
50
+ ### 🔍 Examples updated
51
+ * Clarify ContinuousSpace.get_neighbors behavior with multiple agents at same position by @quaquel in https://github.com/projectmesa/mesa/pull/2599
52
+
53
+ ## New Contributors
54
+ * @HMNS19 made their first contribution in https://github.com/projectmesa/mesa/pull/2596
55
+
56
+ **Full Changelog**: https://github.com/projectmesa/mesa/compare/v3.1.2...v3.1.3
57
+
4
58
  # 3.1.2 (2025-01-04)
5
59
  ## Highlights
6
60
  Mesa v3.1.2 is a patch release containing updates to our wolf-sheep, shelling and prisoner's dilemma example models and improving documentation in the tutorials and visualisation docstring. No functional changes to the core library were made.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Mesa
3
- Version: 3.1.2
3
+ Version: 3.1.3
4
4
  Summary: Agent-based modeling (ABM) in Python
5
5
  Project-URL: homepage, https://github.com/projectmesa/mesa
6
6
  Project-URL: repository, https://github.com/projectmesa/mesa
@@ -24,6 +24,7 @@ Classifier: Topic :: Scientific/Engineering :: Artificial Life
24
24
  Requires-Python: >=3.11
25
25
  Requires-Dist: numpy
26
26
  Requires-Dist: pandas
27
+ Requires-Dist: scipy
27
28
  Requires-Dist: tqdm
28
29
  Provides-Extra: all
29
30
  Requires-Dist: ipython; extra == 'all'
@@ -90,14 +90,19 @@ configurations = {
90
90
  "seeds": 25,
91
91
  "replications": 3,
92
92
  "steps": 20,
93
- "parameters": {"population": 200, "width": 100, "height": 100, "vision": 5},
93
+ "parameters": {
94
+ "population_size": 200,
95
+ "width": 100,
96
+ "height": 100,
97
+ "vision": 5,
98
+ },
94
99
  },
95
100
  "large": {
96
101
  "seeds": 10,
97
102
  "replications": 3,
98
103
  "steps": 10,
99
104
  "parameters": {
100
- "population": 400,
105
+ "population_size": 400,
101
106
  "width": 150,
102
107
  "height": 150,
103
108
  "vision": 15,
@@ -54,3 +54,15 @@ This namespace contains experimental features. These are under development, and
54
54
  .. automodule:: experimental.devs.simulator
55
55
  :members:
56
56
  ```
57
+
58
+ ## Continuous Space
59
+
60
+ ```{eval-rst}
61
+ .. automodule:: experimental.continuous_space.continuous_space
62
+ :members:
63
+ ```
64
+
65
+ ```{eval-rst}
66
+ .. automodule:: experimental.continuous_space.continuous_space_agents
67
+ :members:
68
+ ```
@@ -22,7 +22,7 @@ __all__ = [
22
22
  ]
23
23
 
24
24
  __title__ = "mesa"
25
- __version__ = "3.1.2"
25
+ __version__ = "3.1.3"
26
26
  __license__ = "Apache 2.0"
27
27
  _this_year = datetime.datetime.now(tz=datetime.UTC).date().year
28
28
  __copyright__ = f"Copyright {_this_year} Project Mesa Team"
@@ -6,10 +6,10 @@ of flocking behavior.
6
6
 
7
7
  import numpy as np
8
8
 
9
- from mesa import Agent
9
+ from mesa.experimental.continuous_space import ContinuousSpaceAgent
10
10
 
11
11
 
12
- class Boid(Agent):
12
+ class Boid(ContinuousSpaceAgent):
13
13
  """A Boid-style flocker agent.
14
14
 
15
15
  The agent follows three behaviors to flock:
@@ -26,10 +26,12 @@ class Boid(Agent):
26
26
  def __init__(
27
27
  self,
28
28
  model,
29
- speed,
30
- direction,
31
- vision,
32
- separation,
29
+ space,
30
+ position=(0, 0),
31
+ speed=1,
32
+ direction=(1, 1),
33
+ vision=1,
34
+ separation=1,
33
35
  cohere=0.03,
34
36
  separate=0.015,
35
37
  match=0.05,
@@ -46,7 +48,8 @@ class Boid(Agent):
46
48
  separate: Relative importance of avoiding close neighbors (default: 0.015)
47
49
  match: Relative importance of matching neighbors' directions (default: 0.05)
48
50
  """
49
- super().__init__(model)
51
+ super().__init__(space, model)
52
+ self.position = position
50
53
  self.speed = speed
51
54
  self.direction = direction
52
55
  self.vision = vision
@@ -58,46 +61,31 @@ class Boid(Agent):
58
61
 
59
62
  def step(self):
60
63
  """Get the Boid's neighbors, compute the new vector, and move accordingly."""
61
- self.neighbors = self.model.space.get_neighbors(self.pos, self.vision, False)
64
+ neighbors, distances = self.get_neighbors_in_radius(radius=self.vision)
65
+ self.neighbors = [n for n in neighbors if n is not self]
62
66
 
63
67
  # If no neighbors, maintain current direction
64
- if not self.neighbors:
65
- new_pos = self.pos + self.direction * self.speed
66
- self.model.space.move_agent(self, new_pos)
68
+ if not neighbors:
69
+ self.position += self.direction * self.speed
67
70
  return
68
71
 
69
- # Initialize vectors for the three flocking behaviors
70
- cohere = np.zeros(2) # Cohesion vector
71
- match_vector = np.zeros(2) # Alignment vector
72
- separation_vector = np.zeros(2) # Separation vector
72
+ delta = self.space.calculate_difference_vector(self.position, agents=neighbors)
73
73
 
74
- # Calculate the contribution of each neighbor to the three behaviors
75
- for neighbor in self.neighbors:
76
- heading = self.model.space.get_heading(self.pos, neighbor.pos)
77
- distance = self.model.space.get_distance(self.pos, neighbor.pos)
78
-
79
- # Cohesion - steer towards the average position of neighbors
80
- cohere += heading
81
-
82
- # Separation - avoid getting too close
83
- if distance < self.separation:
84
- separation_vector -= heading
85
-
86
- # Alignment - match neighbors' flying direction
87
- match_vector += neighbor.direction
88
-
89
- # Weight each behavior by its factor and normalize by number of neighbors
90
- n = len(self.neighbors)
91
- cohere = cohere * self.cohere_factor
92
- separation_vector = separation_vector * self.separate_factor
93
- match_vector = match_vector * self.match_factor
74
+ cohere_vector = delta.sum(axis=0) * self.cohere_factor
75
+ separation_vector = (
76
+ -1 * delta[distances < self.separation].sum(axis=0) * self.separate_factor
77
+ )
78
+ match_vector = (
79
+ np.asarray([n.direction for n in neighbors]).sum(axis=0) * self.match_factor
80
+ )
94
81
 
95
82
  # Update direction based on the three behaviors
96
- self.direction += (cohere + separation_vector + match_vector) / n
83
+ self.direction += (cohere_vector + separation_vector + match_vector) / len(
84
+ neighbors
85
+ )
97
86
 
98
87
  # Normalize direction vector
99
88
  self.direction /= np.linalg.norm(self.direction)
100
89
 
101
90
  # Move boid
102
- new_pos = self.pos + self.direction * self.speed
103
- self.model.space.move_agent(self, new_pos)
91
+ self.position += self.direction * self.speed
@@ -1,3 +1,8 @@
1
+ import os
2
+ import sys
3
+
4
+ sys.path.insert(0, os.path.abspath("../../../.."))
5
+
1
6
  from mesa.examples.basic.boid_flockers.model import BoidFlockers
2
7
  from mesa.visualization import Slider, SolaraViz, make_space_component
3
8
 
@@ -17,7 +22,7 @@ model_params = {
17
22
  "value": 42,
18
23
  "label": "Random Seed",
19
24
  },
20
- "population": Slider(
25
+ "population_size": Slider(
21
26
  label="Number of boids",
22
27
  value=100,
23
28
  min=10,
@@ -5,11 +5,17 @@ A Mesa implementation of Craig Reynolds's Boids flocker model.
5
5
  Uses numpy arrays to represent vectors.
6
6
  """
7
7
 
8
+ import os
9
+ import sys
10
+
11
+ sys.path.insert(0, os.path.abspath("../../../.."))
12
+
13
+
8
14
  import numpy as np
9
15
 
10
16
  from mesa import Model
11
17
  from mesa.examples.basic.boid_flockers.agents import Boid
12
- from mesa.space import ContinuousSpace
18
+ from mesa.experimental.continuous_space import ContinuousSpace
13
19
 
14
20
 
15
21
  class BoidFlockers(Model):
@@ -17,7 +23,7 @@ class BoidFlockers(Model):
17
23
 
18
24
  def __init__(
19
25
  self,
20
- population=100,
26
+ population_size=100,
21
27
  width=100,
22
28
  height=100,
23
29
  speed=1,
@@ -31,7 +37,7 @@ class BoidFlockers(Model):
31
37
  """Create a new Boids Flocking model.
32
38
 
33
39
  Args:
34
- population: Number of Boids in the simulation (default: 100)
40
+ population_size: Number of Boids in the simulation (default: 100)
35
41
  width: Width of the space (default: 100)
36
42
  height: Height of the space (default: 100)
37
43
  speed: How fast the Boids move (default: 1)
@@ -44,48 +50,35 @@ class BoidFlockers(Model):
44
50
  """
45
51
  super().__init__(seed=seed)
46
52
 
47
- # Model Parameters
48
- self.population = population
49
- self.vision = vision
50
- self.speed = speed
51
- self.separation = separation
52
-
53
53
  # Set up the space
54
- self.space = ContinuousSpace(width, height, torus=True)
55
-
56
- # Store flocking weights
57
- self.factors = {"cohere": cohere, "separate": separate, "match": match}
54
+ self.space = ContinuousSpace(
55
+ [[0, width], [0, height]],
56
+ torus=True,
57
+ random=self.random,
58
+ n_agents=population_size,
59
+ )
58
60
 
59
61
  # Create and place the Boid agents
60
- self.make_agents()
62
+ positions = self.rng.random(size=(population_size, 2)) * self.space.size
63
+ directions = self.rng.uniform(-1, 1, size=(population_size, 2))
64
+ Boid.create_agents(
65
+ self,
66
+ population_size,
67
+ self.space,
68
+ position=positions,
69
+ direction=directions,
70
+ cohere=cohere,
71
+ separate=separate,
72
+ match=match,
73
+ speed=speed,
74
+ vision=vision,
75
+ separation=separation,
76
+ )
61
77
 
62
78
  # For tracking statistics
63
79
  self.average_heading = None
64
80
  self.update_average_heading()
65
81
 
66
- def make_agents(self):
67
- """Create and place all Boid agents randomly in the space."""
68
- for _ in range(self.population):
69
- # Random position
70
- x = self.random.random() * self.space.x_max
71
- y = self.random.random() * self.space.y_max
72
- pos = np.array((x, y))
73
-
74
- # Random initial direction
75
- direction = np.random.random(2) * 2 - 1 # Random vector between -1 and 1
76
- direction /= np.linalg.norm(direction) # Normalize
77
-
78
- # Create and place the Boid
79
- boid = Boid(
80
- model=self,
81
- speed=self.speed,
82
- direction=direction,
83
- vision=self.vision,
84
- separation=self.separation,
85
- **self.factors,
86
- )
87
- self.space.place_agent(boid, pos)
88
-
89
82
  def update_average_heading(self):
90
83
  """Calculate the average heading (direction) of all Boids."""
91
84
  if not self.agents:
@@ -15,6 +15,6 @@ Notes:
15
15
  - Features graduate from experimental status once their APIs are stabilized
16
16
  """
17
17
 
18
- from mesa.experimental import cell_space, devs, mesa_signals
18
+ from mesa.experimental import cell_space, continuous_space, devs, mesa_signals
19
19
 
20
- __all__ = ["cell_space", "devs", "mesa_signals"]
20
+ __all__ = ["cell_space", "continuous_space", "devs", "mesa_signals"]
@@ -186,7 +186,6 @@ class VoronoiGrid(DiscreteSpace):
186
186
  random: Random | None = None,
187
187
  cell_klass: type[Cell] = Cell,
188
188
  capacity_function: callable = round_float,
189
- cell_coloring_property: str | None = None,
190
189
  ) -> None:
191
190
  """A Voronoi Tessellation Grid.
192
191
 
@@ -200,7 +199,7 @@ class VoronoiGrid(DiscreteSpace):
200
199
  random (Random): random number generator
201
200
  cell_klass (type[Cell]): type of cell class
202
201
  capacity_function (Callable): function to compute (int) capacity according to (float) area
203
- cell_coloring_property (str): voronoi visualization polygon fill property
202
+
204
203
  """
205
204
  super().__init__(capacity=capacity, random=random, cell_klass=cell_klass)
206
205
  self.centroids_coordinates = centroids_coordinates
@@ -215,7 +214,6 @@ class VoronoiGrid(DiscreteSpace):
215
214
  self.triangulation = None
216
215
  self.voronoi_coordinates = None
217
216
  self.capacity_function = capacity_function
218
- self.cell_coloring_property = cell_coloring_property
219
217
 
220
218
  self._connect_cells()
221
219
  self._build_cell_polygons()
@@ -266,4 +264,3 @@ class VoronoiGrid(DiscreteSpace):
266
264
  polygon_area = self._compute_polygon_area(polygon)
267
265
  self._cells[region].properties["area"] = polygon_area
268
266
  self._cells[region].capacity = self.capacity_function(polygon_area)
269
- self._cells[region].properties[self.cell_coloring_property] = 0
@@ -0,0 +1,8 @@
1
+ """Continuous space support."""
2
+
3
+ from mesa.experimental.continuous_space.continuous_space import ContinuousSpace
4
+ from mesa.experimental.continuous_space.continuous_space_agents import (
5
+ ContinuousSpaceAgent,
6
+ )
7
+
8
+ __all__ = ["ContinuousSpace", "ContinuousSpaceAgent"]