Trissa Shamp
Trissa Shamp

Reputation: 19

Lorenz Attractor

enter image description here

I have a question related to numpy's empty() function. I am trying to plot a chaos graph, in the meanwhile, I have been using np.empty() function to create empty arrays consisting of 20,000 elements. The code works perfectly fine when I use the empty() func, but when I decide to try another approach and use np.zeros(), the plot turns out to be a straight line rather than the chaos graph.

I have looked up for the difference between .empty() and .zeros(), but I am having trouble finding out the reason. When I create dydt with .zeros(), the plot becomes a line but it still works fine if dxdt and dzdt are created with .zeros() rather than .empty(). What might be the reason for that?

import numpy as np
import matplotlib.pyplot as plt

#chaotic solution
σ = 10
ρ = 28
β = 8/3

dt = 0.01 #is the sample rate in seconds.
x = 20000
    
dxdt = np.empty(x + 1)
dydt = np.empty(x + 1)
dzdt = np.empty(x + 1)

for i in range (0,x):
     dxdt[i+1] = dxdt[i] + σ*(dydt[i] - dxdt[i])*dt
     dydt[i+1] = dydt[i] + (dxdt[i] * (ρ - dzdt[i]) - dydt[i])*dt
     dzdt[i+1] = dzdt[i] + (dxdt[i] * dydt[i] - β * dzdt[i\])*dt

# Initial values
dxdt[0], dydt[0], dzdt[0] = (0., 1., 1.05)

# Plot

fig = plt.figure(figsize=(16, 16),dpi=400)
ax = fig.gca(projection='3d')
ax.plot(dxdt, dydt, dzdt, lw=0.5)
ax.set_xlabel("X Axis")
ax.set_ylabel("Y Axis")
ax.set_zlabel("Z Axis")
ax.set_title("Lorenz Attractor")
plt.show()]

Upvotes: 0

Views: 319

Answers (1)

Josh Friedlander
Josh Friedlander

Reputation: 11657

I think possibly you want to set the initial values before you begin the loop? Here is the change, plus some minor formatting (as it is now my interpreter wouldn't run it):

# chaotic solution
σ = 10
ρ = 28
β = 8 / 3

dt = 0.01  # is the sample rate in seconds.
x = 20000

dxdt = np.empty(x + 1)
dydt = np.empty(x + 1)
dzdt = np.empty(x + 1)

# Initial values
dxdt[0], dydt[0], dzdt[0] = (0.0, 1.0, 1.05)

for i in range(x):
    dxdt[i + 1] = dxdt[i] + σ * (dydt[i] - dxdt[i]) * dt
    dydt[i + 1] = dydt[i] + (dxdt[i] * (ρ - dzdt[i]) - dydt[i]) * dt
    dzdt[i + 1] = dzdt[i] + (dxdt[i] * dydt[i] - β * dzdt[i]) * dt

fig = plt.figure(figsize=(16, 16),dpi=400)
ax = fig.add_subplot(projection='3d')
ax.plot(dxdt, dydt, dzdt, lw=0.5)
ax.set_xlabel("X Axis")
ax.set_ylabel("Y Axis")
ax.set_zlabel("Z Axis")
ax.set_title("Lorenz Attractor")
plt.show()

enter image description here

Note that empty and zeros are slightly different but shouldn't matter for your context, it is more about optimising memory allocation based on how many zeroes you expect to end up with. Replacing the one with the other makes no difference in my solution. I also replaced setting the projection with gca(), which has been deprecated.

Upvotes: 1

Related Questions