Skip to content
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

updated boid_flockers to include direction #2696

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

sanika-n
Copy link
Contributor

I updated boid_flockers so that the direction of movement of agents is shown in the simulation.
I did this by changing the marker to caret-down (a triangle with a larger base so that the direction of motion is not ambiguous) and then rotating the marker according to the direction of motion of the agent. Here are some images of boid_flockers after this update:
image

image

Copy link

Performance benchmarks:

Model Size Init time [95% CI] Run time [95% CI]
BoltzmannWealth small 🔵 +2.8% [+1.6%, +4.0%] 🔵 -0.7% [-0.9%, -0.6%]
BoltzmannWealth large 🔵 +0.1% [-0.4%, +0.5%] 🔵 -0.3% [-1.3%, +0.6%]
Schelling small 🔵 +0.2% [+0.0%, +0.4%] 🟢 -4.0% [-4.1%, -3.9%]
Schelling large 🔵 +0.3% [-0.2%, +0.8%] 🔵 -2.7% [-3.4%, -2.0%]
WolfSheep small 🔵 +0.2% [-0.1%, +0.5%] 🔵 -0.0% [-0.2%, +0.2%]
WolfSheep large 🔵 -0.5% [-1.3%, +0.1%] 🔵 +0.3% [-0.6%, +1.4%]
BoidFlockers small 🔵 +0.8% [+0.3%, +1.3%] 🔵 +0.4% [+0.3%, +0.6%]
BoidFlockers large 🔵 +0.7% [+0.3%, +1.0%] 🔵 +0.7% [+0.4%, +1.0%]

Copy link
Member

@EwoutH EwoutH left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, this is really useful. Code itself looks good!

Why don't the non-blocking boids have an direction?

Have you any idea on the performance impact?

@EwoutH EwoutH requested a review from Sahil-Chhoker February 22, 2025 09:46
@EwoutH EwoutH added enhancement Release notes label visualisation labels Feb 22, 2025
@Sahil-Chhoker
Copy link
Collaborator

Really sorry @EwoutH @sanika-n, as much as I would love to review this PR, my exams got me all tied up for about next 10 days.

@EwoutH
Copy link
Member

EwoutH commented Feb 22, 2025

No worries, it’s all voluntarily. Thanks for communicating your availability clearly, I can pick this one up.

@EwoutH
Copy link
Member

EwoutH commented Feb 23, 2025

@sanika-n a simple initial test is running the old model for 1000 steps and (manually) timing how long it takes, and then doing the same for the updated model. Make sure to use the same seed in both cases.

@sanika-n
Copy link
Contributor Author

Awesome, this is really useful. Code itself looks good!

Why don't the non-blocking boids have an direction?

Have you any idea on the performance impact?

Just added the direction element to all the boids, and these are the timings that I got after updating the non-flocking boids

Random seed 42

Altered version
1000 steps: 11min 44sec
50 steps: 15.84s
25 steps: 8.18s

Original version
1000 steps: 5min 22s
50 steps: 10.33s
25 steps: 5.42s

@EwoutH
Copy link
Member

EwoutH commented Feb 27, 2025

@sanika-n thanks for the benchmarks. A 2x slowdown is more that I would like. It would be interesting to see where the performance degradation is coming from:

  1. The angle calculation np.degrees(np.arctan2(...))
  2. Marker transformation & drawing

If it's the former, we could try to vectorize it. If it's the latter, we could add a marker cache. Something like:

import numpy as np
from matplotlib.markers import MarkerStyle

# Pre-compute markers for different angles (e.g., every 10 degrees)
MARKER_CACHE = {}
for angle in range(0, 360, 10):
    marker = MarkerStyle(10)
    marker._transform = marker.get_transform().rotate_deg(angle)
    MARKER_CACHE[angle] = marker

def boid_draw(agent):
    neighbors = len(agent.neighbors)
    
    # Calculate the angle
    deg = np.degrees(np.arctan2(agent.direction[0], agent.direction[1]))
    # Round to nearest 10 degrees
    rounded_deg = round(deg / 10) * 10 % 360
    
    if neighbors <= 1:
        return {"color": "red", "size": 20, "marker": MARKER_CACHE[rounded_deg]}
    elif neighbors >= 2:
        return {"color": "green", "size": 20, "marker": MARKER_CACHE[rounded_deg]}

@sanika-n
Copy link
Contributor Author

sanika-n commented Feb 27, 2025

Thank you so much! It's much faster now (5 min 43 seconds for 1000 steps)
I also tried to implement vectorization, hope it is in line with what you meant...

@EwoutH EwoutH requested a review from quaquel February 27, 2025 19:27
@EwoutH
Copy link
Member

EwoutH commented Feb 27, 2025

Glad to hear it helped, that’s a serious speed-up!

It might be good to add a few comments what we’re doing and why.

Conceptually and functionally we’re good. @quaquel, could you do a code/implementation review?

@quaquel
Copy link
Member

quaquel commented Mar 1, 2025

@sanika-n can you update this to be in line with the base branch?

My agenda is a bit of a mess, but will try to find a few hours soon to go through various open PRs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Release notes label visualisation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants