Hello, I’m trying to simulate the Belousov-Zhabotinsky (BZ) reaction as implemented here.
I have written the following implementation for that purpose:
using Images, ImageView, ProgressMeter
function react(petridish::Matrix{<:RGB}, α, β, γ, kernel)
# Count the average amount of each species in the 8 cells around each cell
# through a convolution with a 3x3 mask
s = imfilter(petridish, kernel)
# Apply the reaction equations
react!(s, α, β, γ)
return s
end
function react!(
s,
α::Number,
β::Number,
γ::Number
)
@inbounds for ii in eachindex(s)
# Get components
ss = s[ii]
r = red(ss)
g = green(ss)
b = blue(ss)
# Compute new components
new_r = clamp(r * (1 + α*g - γ*b), 0, 1)
new_g = clamp(g * (1 + β*b - α*r), 0, 1)
new_b = clamp(b * (1 + γ*r - β*g), 0, 1)
# Update s
s[ii] = RGB(new_r, new_g, new_b)
end
end
function simulate(petridish, nx, ny, max_iter, α, β, γ, kernel)
animation = zeros(RGB{N0f8}, (nx, ny, max_iter));
@showprogress for ii in 1:max_iter
petridish = react(petridish, α, β, γ, kernel)
animation[:, :, ii] = petridish
end
return animation
end
nx, ny = 1000, 1000
α, β, γ = 1, 1, 1.2
max_iter = 500
kernel = centered(ones(3, 3) / 9)
init_petridish = rand(RGB{N0f8}, (nx, ny));
petridish = simulate(init_petridish, nx, ny, max_iter, α, β, γ, kernel)
imshow(petridish)
My problem is that when trying to run this code by either running an include
or directly pasting into a REPL, the code is very slow, in the hours. So I decided to figure out if I could find the bottleneck with Juno’s @profiler
function but it turns out this script runs a lot faster (~seconds) just by doing this.
Is the problem with my code or with some package I’m using?
TLDR: The speedup occurs when running Juno.@profiler include("bzreaction.jl")
in the Atom IDE with Juno installed