# The simulation model¶

To construct a Lorenz-63 simulation model for pypfilt, we need to create a Model subclass that defines the state vector structure and the state update rule. Because this model is a system of ordinary differential equations, we can derive from the OdeModel class, which provides a convenient wrapper around scipy.integrate.solve_ivp().

Here, we define the state vector to contain six floating-point values:

$x_t = [\sigma, \rho, \beta, x, y, z]^T$
• The state vector structure is defined by the field_types() method, which returns a list of (name, type) pairs.

• The right-hand side is defined by the d_dt() method, which keeps the parameters $$\sigma$$, $$\rho$$, and $$\beta$$ fixed, and calculates the rate of change for $$x(t)$$, $$y(t)$$, and $$z(t)$$.

class Lorenz63(OdeModel):
def field_types(self, ctx):
r"""
Define the state vector :math:[\sigma, \rho, \beta, x, y, z]^T.
"""
return [
('sigma', float),
('rho', float),
('beta', float),
('x', float),
('y', float),
('z', float),
]

def d_dt(self, time, xt, ctx, is_forecast):
"""
The right-hand side of the ODE system.

:param time: The current time.
:param xt: The particle state vectors.
:param ctx: The simulation context.
:param is_forecast: True if this is a forecasting simulation.
"""
rates = np.zeros(xt.shape, xt.dtype)
rates['x'] = xt['sigma'] * (xt['y'] - xt['x'])
rates['y'] = xt['x'] * (xt['rho'] - xt['z']) - xt['y']
rates['z'] = xt['x'] * xt['y'] - xt['beta'] * xt['z']
return rates