Skip to main content
Mathematics LibreTexts

6.4: Simulating Continuous-Time Models

  • Page ID
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)

    \( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)

    ( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)

    \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

    \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)

    \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)

    \( \newcommand{\Span}{\mathrm{span}}\)

    \( \newcommand{\id}{\mathrm{id}}\)

    \( \newcommand{\Span}{\mathrm{span}}\)

    \( \newcommand{\kernel}{\mathrm{null}\,}\)

    \( \newcommand{\range}{\mathrm{range}\,}\)

    \( \newcommand{\RealPart}{\mathrm{Re}}\)

    \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

    \( \newcommand{\Argument}{\mathrm{Arg}}\)

    \( \newcommand{\norm}[1]{\| #1 \|}\)

    \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)

    \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    \( \newcommand{\vectorA}[1]{\vec{#1}}      % arrow\)

    \( \newcommand{\vectorAt}[1]{\vec{\text{#1}}}      % arrow\)

    \( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vectorC}[1]{\textbf{#1}} \)

    \( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)

    \( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)

    \( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)

    \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)

    \(\newcommand{\avec}{\mathbf a}\) \(\newcommand{\bvec}{\mathbf b}\) \(\newcommand{\cvec}{\mathbf c}\) \(\newcommand{\dvec}{\mathbf d}\) \(\newcommand{\dtil}{\widetilde{\mathbf d}}\) \(\newcommand{\evec}{\mathbf e}\) \(\newcommand{\fvec}{\mathbf f}\) \(\newcommand{\nvec}{\mathbf n}\) \(\newcommand{\pvec}{\mathbf p}\) \(\newcommand{\qvec}{\mathbf q}\) \(\newcommand{\svec}{\mathbf s}\) \(\newcommand{\tvec}{\mathbf t}\) \(\newcommand{\uvec}{\mathbf u}\) \(\newcommand{\vvec}{\mathbf v}\) \(\newcommand{\wvec}{\mathbf w}\) \(\newcommand{\xvec}{\mathbf x}\) \(\newcommand{\yvec}{\mathbf y}\) \(\newcommand{\zvec}{\mathbf z}\) \(\newcommand{\rvec}{\mathbf r}\) \(\newcommand{\mvec}{\mathbf m}\) \(\newcommand{\zerovec}{\mathbf 0}\) \(\newcommand{\onevec}{\mathbf 1}\) \(\newcommand{\real}{\mathbb R}\) \(\newcommand{\twovec}[2]{\left[\begin{array}{r}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\ctwovec}[2]{\left[\begin{array}{c}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\threevec}[3]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\cthreevec}[3]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\fourvec}[4]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\cfourvec}[4]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\fivevec}[5]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\cfivevec}[5]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\mattwo}[4]{\left[\begin{array}{rr}#1 \amp #2 \\ #3 \amp #4 \\ \end{array}\right]}\) \(\newcommand{\laspan}[1]{\text{Span}\{#1\}}\) \(\newcommand{\bcal}{\cal B}\) \(\newcommand{\ccal}{\cal C}\) \(\newcommand{\scal}{\cal S}\) \(\newcommand{\wcal}{\cal W}\) \(\newcommand{\ecal}{\cal E}\) \(\newcommand{\coords}[2]{\left\{#1\right\}_{#2}}\) \(\newcommand{\gray}[1]{\color{gray}{#1}}\) \(\newcommand{\lgray}[1]{\color{lightgray}{#1}}\) \(\newcommand{\rank}{\operatorname{rank}}\) \(\newcommand{\row}{\text{Row}}\) \(\newcommand{\col}{\text{Col}}\) \(\renewcommand{\row}{\text{Row}}\) \(\newcommand{\nul}{\text{Nul}}\) \(\newcommand{\var}{\text{Var}}\) \(\newcommand{\corr}{\text{corr}}\) \(\newcommand{\len}[1]{\left|#1\right|}\) \(\newcommand{\bbar}{\overline{\bvec}}\) \(\newcommand{\bhat}{\widehat{\bvec}}\) \(\newcommand{\bperp}{\bvec^\perp}\) \(\newcommand{\xhat}{\widehat{\xvec}}\) \(\newcommand{\vhat}{\widehat{\vvec}}\) \(\newcommand{\uhat}{\widehat{\uvec}}\) \(\newcommand{\what}{\widehat{\wvec}}\) \(\newcommand{\Sighat}{\widehat{\Sigma}}\) \(\newcommand{\lt}{<}\) \(\newcommand{\gt}{>}\) \(\newcommand{\amp}{&}\) \(\definecolor{fillinmathshade}{gray}{0.9}\)

    Simulation of a continuous-time model is equivalent to the numerical integration of differential equations, which, by itself, is a major research area in applied mathematics and computational science with more than a century of history. There are a large number of methodologies developed for how to accomplish accurate, fast, efficient numerical integrations. It would easily take a few books and semesters to cover them, and this textbook is not intended to do that. Instead, here we focus on the simplest possible method for simulating a continuous time model, by using the following formula as an approximation of a differential equation

    \[\begin{align} \dfrac{dx}{dt} &=G(x); \\[4pt] x(t+\Delta{t}) &= x(t) +G(x(t))\Delta{t} \label{6.26} \end{align} \]

    This method is called the Euler forward method. Its basic idea is very straightforward; you just keep accumulating small increases/decreases of \(x\) that is expected from the local derivatives specified in the original differential equation. The sequence produced by this discretized formula will approach the true solution of the original differential equation at the \(\displaystyle \lim_{∆t → 0}\), although in practice, this method is less accurate for finite-sized \(∆t\) than other more sophisticated methods (see Exercise 6.6.3). Having said that, its intuitiveness and easiness of implementation have a merit, especially for those who are new to computer simulation. So let’s stick to this method for now.

    In nearly all aspects, simulation of continuous-time models using the Euler forward method is identical to the simulation of discrete-time models we discussed in Chapter 4. Probably the only technical difference is that we have \(∆t\) as a step size for time, which may not be 1, so we also need to keep track of the progress of time in addition to the progress of the state variables. Let’s work on the following example to see how to implement the Euler forward method.

    Here we consider simulating the following continuous-time logistic growth model for \(0 ≤ t < 50\) in Python, with \(x(0) = 0.1\), \(r = 0.2\), \(K = 1\) and \(∆t = 0.01\):

    \[\frac{dx}{dt} =rx(1-\frac{x}{K}) \label{6.27} \]

    The first (and only) thing we need to do is to discretize time in the model above. Using Equation \ref{6.26}, the equation becomes

    \[x(t+\Delta{t}) =x(t) +rx(t)(1 -\frac{x(t)}{K}) \Delta{t}, \label{6.28} \]

    which is nothing more than a typical difference equation. So, we can easily revise Code 4.10 to create a simulator of Equation \ref{6.27}:

    Code 6.1.png

    Code 6.1 pt 2.png
    Figure 6.4.1. If you choose even smaller values for \(∆t\), the curve will get closer to the true solution of Equation \ref{6.27}.
    Figure \(\PageIndex{1}\): Visual output of Code 6.1.
    Exercise \(\PageIndex{1}\)

    Vary \(∆t\) to have larger values in the previous example and see how the simulation result is affected by such changes.

    As the exercise above illustrates, numerical integration of differential equations involves some technical issues, such as the stability and convergence of solutions and the possibility of “artifacts” arising from discretization of time. You should always be attentive to these issues and be careful when implementing simulation codes for continuous-time models. I hope the following exercises will help you further investigate those subtleties of the numerical integration of differential equations.

    Exercise \(\PageIndex{2}\): Lotka-Volterra (predator prey) model

    Simulate the following continuous-time Lotka-Volterra (predator prey) model for \(0 ≤ t < 50\) in Python, with \(x(0) = y(0) = 0.1\), \(a = b = c = d = 1\) and \(∆t = 0.01\). Visualize the simulation results over time and also in a phase space.

    \[\frac{dx}{dt} =ax-bxy \label{6.29} \]

    Exercise \(\PageIndex{3}\): Other integration methods

    There are many other more sophisticated methods for the numerical integration of differential equations, such as the backward Euler method, Heun’s method, the Runge-Kutta methods,etc. Investigate some of those methods to see how they work and why their results are better than that of the Euler forward method.

    This page titled 6.4: Simulating Continuous-Time Models is shared under a CC BY-NC-SA 3.0 license and was authored, remixed, and/or curated by Hiroki Sayama (OpenSUNY) via source content that was edited to the style and standards of the LibreTexts platform.