-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactoring mesa.space #6
Comments
Can't wait for this feature. This is the only blocker to me implementing mesa-frames version of Sugarscape constant growback. It boils down to implementing the |
Let me ensure I understood correctly the issue. The available spaces are the neighborhood spaces which are not occupied. The problem is that in the traditional Sugarscape model, since the step is sequential for agents, there is a race condition. If parallelized, we could have two agents that select the same space at the same time. |
Yeah, that (update the position in parallel, then do tie-breaking) is the method used in the FLAME 2 implementation of Sugarscape instantaneous growback (i.e. simpler version of constant growback, where the sugar grows to max value in the next step right after being consumed; constant growback has a growing rate), in figure 6. Here is their code. |
I see, that's very interesting that it's so recent! Do you think tie-breaking should be left to the user or handled by the library? Depending on the model, it can be either very simple or very complex to handle tie-breaking, similar to the challenge of vectorizing user-defined functions. Perhaps it would be better to include a section in the documentation on how to deal with race conditions? |
I think the basic version |
@rht Do you think it would be better to convert DataFrames to GeoDataFrames with the respective geo-library if space is added to the model or simply adding a position/geometry column? |
Which one is faster to implement? I have no strong opinion on either, as long as there could be a common API -- unlikely? Because Mesa-Geo and Mesa's current space.py have different API. If designing a common API is too much at this stage, my only requirement is that it shouldn't be too much boilerplate code for user who starts learning by doing Schelling or Boltzmann wealth model. Note that in core Mesa, we are moving away from the old space.py implementation to a new cell-based implementation, https://github.com/projectmesa/mesa/tree/main/mesa/experimental/cell_space, that is conceptually simpler (see e.g. the get neighborhood method, https://github.com/projectmesa/mesa/blob/2cee49efeac07ea44342b918b2db6fb170649793/mesa/experimental/cell_space/cell.py#L132) but also sufficiently performant (the PR itself). But the structure in core Mesa that is closer to Mesa-Geo is the new experimental PropertyLayer (the PR for more context and examples). |
Thank you for the references; they are very useful. So you're moving to a cell-based space to achieve better granularity of the environment (i.e., by setting properties of each single cell with the PropertyLayer) and to create an easier abstraction for interacting with and creating different types of spaces more easily. To create a unique API that aligns with the future of mesa and works for mesa-geo objects, we can create the cell collection in a GeoPandas DataFrame (GeoPolars could also be implemented in the future). GeoPandas allows the geometry column to be a series of shapely objects, representing the geometry of the cell itself (e.g., a box for a rectangular grid, a complex polygon for continuous spaces). The coordinate reference system (CRS) can also be set, aligning it with mesa-geo. The other columns of the DataFrame would contain the properties for each cell (e.g., maximum number of agents or other custom properties in the PropertyLayer). I am unsure why there are so many classes with similar functionality but different implementations and interfaces in mesa. This complexity can make it difficult for end-users to understand and use multiple classes with custom behaviors, and it can also be challenging for developers to comprehend the layers of abstraction. I propose creating a single unique (abstract?) class that stores cells in a GeoDataFrame, with other columns representing the "properties" of the PropertyLayer. This class would combine the functionalities of PropertyLayer/_PropertyGrid, CellCollection, DiscreteSpace, SingleGrid, and MultiGrid. From this abstract class, we could create child classes for each type of space (e.g., network, rectangular grid, etc.). Additionally, I would move the move_to method of CellAgent to the AgentContainer. I think the end result would mirror the structure of AgentSet and AgentsDF with CellSet and CellsDF respectively to implement multiple type of cells and store all cells in the model with GeoDataFrames instead of DataFrames. |
Yes I agree, sorry for the mess (old space, property layer, cell space, and the implementations). Mesa was in a flux of development last year, and there is not enough explicit communication to the public on which one is recommended for the current best practice, which one should be used for integration, and so on. Docs, tutorials, and how-to's are lacking. There is also a problem that the cell_space version of Mesa-Geo doesn't exist yet.
Yes, that would make sense for mesa-frames. In Mesa, the PropertyLayer is separate from grid/space because it is implemented as a np.ndarray, and operation on it would be a vectorized operation, which regular old space/cell space doesn't support. Optional question: for the GeoDataFrame, how does it work for a sparse agents situation (e.g. 10 agents, in a grid of 100x100)? Wouldn't it be 10k rows of mostly empty agent content, but yet each must have a property? This is optional because I think we can still design a common abstract interface while postponing a more specific implementation.
SGTM. The |
I think it's normal; mesa is evolving a lot, and keeping up with documentation is hard. However, I think it should be a priority for mesa 3.0. As a user familiar with mesa, I struggle to understand which classes to use, what has been deprecated or how things work without looking at the source code. I can also help to improve docs at the end of the GSOC period if we have time.
That is a very good point. I think there's a tradeoff here. Either we have very granular cells (i.e., each cell can have its own property) with a large memory usage for sparse models, or we have less granularity (each cell in the set has the same property) with more efficient memory usage (we could store geometries at the agent level and store property attributes for cells at the cell class level). What do you think works better? Maybe we can have users using both. |
Yeah, it's a good problem to have (revamping the API). The old API is getting clunky to use.
Don't worry about this for now. Focus on making mesa-frames more awesome, as there are lots of things to do, mainly the classic models, for Sampy use case, and using GPU to scale to millions of agents and huge space. Also, I'm still reading on
From the user/API standpoint, I think we should have a sparse flag that is very simple to toggle (along the line of in NumPy where you can switch to a sparse matrix seamlessly). And from the developer standpoint, we will have to worry about the fast |
Thanks for the feedback. I agree work is needed on the examples and tutorials. I think we're doing a good job with docstring though, but if you disagrees or find areas for improvement, please point them out! I have created open issues with some resources for anyone that wants to improve the examples:
And we have projectmesa/mesa-examples#118 incoming which uses both the AgentSet and the Cell Space. If I can find the time I will also work on them somewhat myself. Unfortunately, that keeps being a big if. |
Thank you for the references! I agree that docstrings are generally sufficient for understanding what a component does, but as you mentioned, examples are lacking. I almost always have to look at the source code to understand how to actually use it in practice. It's great that there are open issues to work on examples though! If I may make a suggestion, in addition to adding examples to mesa-examples, I would recommend including short examples in the docstrings, similar to what you often see in the polars, pandas, or numpy API documentation. These are great for quickly understanding what a component does. |
Roadmap
Class Structure and Design
SpaceDF
_agents
attribute in a DataFrame/GeoDataFrame. This approach avoids many missing values in the AgentSetDF and reduces confusion when multiple spaces of the same type are present (e.g., an agent in both a grid and in a social network)pos
property for AgentContainer that performs an instant join with the space_agents
DataFrameMultiSpaceDF
DiscreteSpaceDF
set_cells
method)_agents
stores cell properties in the_cells
attribute in a DataFrame. The_cells
DataFrame explicitly stores only cells that have agents or have specific properties different from the class levelContinousSpaceDF
GridDF
GeoGridDF
The text was updated successfully, but these errors were encountered: