Creating Van der Pol oscillator class with data frames
I'm trying to recreate this graph:
... and this table:
... using this set of equations:
It has to include these methods:
Instructions: Create a class that can be used to simulate Van der Pol oscillators. That class should contain at least the following methods:
add_oscillator(self, mu, x0=1, y0=0)
: Add a new oscillator with parametersmu
initial valuesx(0)=x0
(default:1
) andy(0)=y0
(default:0
).delete_oscillator(self, i)
: Delete thei-th
开发者_开发技巧oscillator from the list of available oscillators.getsim_data(self, duration=30.0, dt=0.01)
: Simulate theN
oscillators previously added to the object (usingadd_oscilator
) for the specifiedduration
(default:30s
) and with a sampling stepdt
(default:0.01s
) and return the simulated data as a pandasDataFrame
of shape(duration/dt, N)
. "Simulating" these oscillators mean obtainingx(t)
by solving the ODE above. This can be done manually using the Euler integration scheme (as seen in previous labs) or using an ODE solver (e.g.,scipy.solve_ivp()
function).plot(fself, tmin=0.0, tmax=30.0)
: Plot the time course of the different oscillators fromtmin
totmax
.Here is an example of use:
vdp = VanDerPol()
vdp.add_oscillator(1.0) # oscilator 0
vdp.add_oscillator(3.0) # oscilator 1
vdp.add_oscillator(2.0) # oscilator 2
vdp.delete_oscilator(1)
print(vdp.get_sim_data(dt=0.01))
vdp.plot(tmin=10)
I am trying to create a Python class to simulate a Van der Pol oscillator using numpy
, scipy
, DataFrame
, and matplotlib
.
This is my first exposure to coding, so I'm aware my code might be very junky.
I started off by completing the add_oscillator
and delete_oscillator
functions. Both seem to work, though I'm unsure if the new_oscillator
class is the best way to achieve what I did.
I began running into problems in get_sim_data
. I used information from this link to get a function working, and then adding the data to a DataFrame
. The resulting data seems to be wrong, and I'm not sure where the mistake is.
The graphed plot also doesn't look like what I need it to look alike, and the x-axis
numbers are 0-3000
, instead of 10-30
.
Any help is appreciated. Thanks.
from scipy.integrate import solve_ivp
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
class VanDerPol:
def __init__(self):
self.oscillators = []
self.df = pd.DataFrame()
def add_oscillator(self, mu, x0=1, y0=0):
class new_oscillator:
def __init__(self, mu, x0, y0):
self.mu = mu
self.x0 = x0
self.y0 = y0
def __str__(self):
return f"mu={self.mu}, x0={self.x0}, y0={self.y0}"
self.oscillators.append(new_oscillator(mu, x0, y0))
def delete_oscillator(self, i):
self.oscillators.pop(i)
def get_sim_data(self, duration=30.0, dt=0.01):
# durations = np.arange(0, duration, dt, dtype=float)
durations = np.linspace(0, duration, int(duration / dt))
# df = pd.DataFrame(durations)
for o in self.oscillators:
def vdp(t, z):
x, y = z
return [y, o.mu * (1 - x**2) * y - x]
data = solve_ivp(vdp, [0, duration], [o.x0, o.y0], t_eval=durations)
# df = pd.DataFrame(data.y[0])
# df = pd.DataFrame()
df = pd.DataFrame(data.y[0])
# df[o] = pd.Series(data.y[0])
# print(data.y[0])
self.df[o] = df
# print(self.df)
print(self.df)
def plot(self, tmin=0.0, tmax=30.0):
plt.plot(self.df)
vdp = VanDerPol()
vdp.add_oscillator(1.0) # oscillator 0
vdp.add_oscillator(3.0) # oscillator 1
vdp.add_oscillator(2.0) # oscillator 2
vdp.delete_oscillator(1)
print(vdp.get_sim_data(dt=0.01))
vdp.plot(tmin=10)
精彩评论