The entire code lorenz.jl:
using CUDA
using StaticArrays
using Plots
using DifferentialEquations
@kwdef struct AttractorParams
σ::Float64 = 10.0
ρ::Float64 = 28.0
β::Float64 = (8.0 / 3.0)
end
function lorenz!(du, u, params, _)
x, y, z = u
du[1] = params.σ * (y - x)
du[2] = x * (params.ρ - z) - y
du[3] = (x * y) - (params.β * z)
return nothing
end
function simulate(initial_condition, tspan, params)
prob = ODEProblem(lorenz!, initial_condition, tspan, params)
return solve(prob, Tsit5(), reltol=1e-6, abstol=1e-6)
end
function plot_xz(sol)
x_coords = [point[1] for point in sol.u]
z_coords = [point[3] for point in sol.u]
p = plot(x_coords, z_coords, seriestype=:path, xlabel="X", ylabel="Z", lw=0.25, alpha=07, size=(1200, 1200))
return p
end
function plot_xy(sol)
x_coords = [point[1] for point in sol.u]
y_coords = [point[2] for point in sol.u]
p = plot(x_coords, y_coords, seriestype=:path, xlabel="X", ylabel="Y", lw=0.5, alpha=0.7, size=(1200, 1200),
background_color=:black, legend=false, linecolor=cgrad(:viridis))
return p
end
function run_sim()
u0 = [1.0, 0.0, 0.0]
tspan = (0.0, 1000.0)
sim_results = simulate(u0, tspan, AttractorParams())
viz = plot_xy(sim_results)
display(viz)
end
A visualization of the XY projection of the classic Lorenz System.
So it turns out that in Julia if you want to render a the Lorenz system efficiently, you don't have to manually integrate it via iteration, there's this library with ODE system support that automatically uses CUDA if you load it. The code for this was fast. (h/t @ponder.ooo )
#julia #mathviz