-
Notifications
You must be signed in to change notification settings - Fork 134
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
Mesa implementation of Ising Model #138
base: main
Are you sure you want to change the base?
Conversation
agents_list = list(self.agents) | ||
self._steps += 1000 | ||
for i in range(1000): | ||
random_spin = self.random.choice(agents_list) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having to create a new list of agents from scratch and selecting one is not ideal. I know this is a limitation of AgentSet
. @EwoutH any idea to do this in a performant way via AgentSet
? It seems to be a tower of abstractions, that it has slowed down the benchmark for mesa-frames as well: see https://github.com/adamamer20/mesa-frames/issues/25.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for the comment. it does not feel right at all haha.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently I don’t think there is. @vitorfrois could you open a new issue on the main Mesa repo describing this lack of functionality and linking to this PR as example?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was going to suggest you can just do:
self.agents.select(n=1000)
But looking at our current implementation (here) that isn’t actually random.
What you can do though is:
self.agents.shuffle().select(n=1000)
|
||
What happens when the temperature slider is set very low? (This is called the "ferromagnetic" state.) Again, try this with different **Spin Up Probability** values. | ||
|
||
Between these two very different behaviors is a transition point. On an infinite grid, the transition point can be proved to be $2 / ln (1 + sqrt 2)$, which is about 2.27. On a large enough finite toroidal grid, the transition point is near this number. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't have means of aggregating various param sweep into a single plot of magnetization vs temperature. This is a homework for us developers to allow visualizing batch_run result easily.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This model is very helpful in demonstrating phase transition. We have Epstein civil violence, but the Ising model is the bread and butter toy model for phase transition in statistical physics. We should aim towards being able to specify this model in code concisely. |
Other than the 2 comments, this PR LGTM. Once you fix them, I will merge. |
@rht comments fixed! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like a really clean and neat implementation! I already like it a lot, especially that it demonstrates some more recent Mesa functionality and comes with visualization.
I left some comments, but already like it a lot!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For consistency is prefer this named app.py
.
It might not be the best name, but it’s what we use now.
import solara | ||
from ising.model import IsingModel | ||
from ising.portrayal import portray_spin | ||
from mesa.visualization import JupyterViz |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can now import SolaraViz
from mesa.visualization import JupyterViz | |
from mesa.visualization import SolaraViz |
|
||
@solara.component | ||
def Page(): | ||
JupyterViz( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
JupyterViz( | |
SolaraViz( |
self.state = init_state | ||
|
||
def neighbors(self): | ||
return self.model.grid.iter_neighbors((self.x, self.y), True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make explicit for readability:
return self.model.grid.iter_neighbors((self.x, self.y), True) | |
return self.model.grid.iter_neighbors((self.x, self.y), moore=True) |
""" | ||
Create a cell, in the given state, at the given x, y position. | ||
""" | ||
super().__init__(pos, model) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn’t this map to unique_id, model
?
If intended, please add a comment, if not, update
for i in range(1000): | ||
random_spin = self.random.choice(agents_list) | ||
dE = self.get_energy_change(random_spin) | ||
if dE < 0: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe you can do here
if dE < 0: | |
if dE < 0 or self.random.random() < self.boltzmann_factor(dE): |
If I understand Python correctly, the later part won’t be evaluated if the former is False
already, making it just as fast, and more readable.
|
||
def step(self): | ||
agents_list = list(self.agents) | ||
self._steps += 1000 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understand this correctly, you are using _step to count the number of agent activations (you use 1000, as in the for loop). Why use _step
for this?
Co-authored-by: Ewout ter Hoeven <E.M.terHoeven@student.tudelft.nl>
Ising Model (https://ccl.northwestern.edu/netlogo/models/Ising, https://en.wikipedia.org/wiki/Ising_model) implementation using new Visualization of Ising Model as issued at #136.