1.. _tut_nonauto:
2
3Non-autonomous systems
4======================
5
6.. versionadded:: 0.3.0
7
8All the ODE systems we have used in the examples thus far belong to the class of autonomous systems.
9That is, the time variable :math:`t` never appears explicitly in the expressions of the ODEs. In this
10section, we will see how non-autonomous systems can be defined and integrated in heyoka.
11
12The dynamical system we will be focusing on is, again, a pendulum, but this time we will
13spice things up a little by introducing a velocity-dependent damping effect and a time-dependent
14external forcing. These additional effects create a rich and complex dynamical picture
15which is highly sensitive to the initial conditions. See :cite:`hubbard1999forced`
16for a detailed analysis of this dynamical system.
17
18The ODE system of the forced damped pendulum reads:
19
20.. math::
21
22   \begin{cases}
23   x^\prime = v \\
24   v^\prime = \cos t - 0.1v - \sin(x)
25   \end{cases}.
26
27The :math:`\cos t` term represents a periodic time-dependent forcing, while :math:`-0.1v`
28is a linear drag representing the effect of air on the pendulum's bob. Following :cite:`hubbard1999forced`,
29we take as initial conditions
30
31.. math::
32
33   \begin{cases}
34   x\left( 0 \right) = 0 \\
35   v\left( 0 \right) = 1.85
36   \end{cases}.
37
38That is, the pendulum is initially in the vertical position with a positive velocity.
39
40The time variable is represented in heyoka's expression system by a special placeholder
41called, in a dizzying display of inventiveness, ``time``. Because the name ``time`` is fairly
42common (e.g., ``time()`` is a function in the POSIX API), it is generally a good idea
43to prepend the namespace ``heyoka`` (or its abbreviation, ``hy``) when using
44the ``time`` expression, in order to avoid ambiguities that could confuse the compiler.
45With that in mind, let's look at how the forced damped pendulum is defined in heyoka:
46
47.. literalinclude:: ../tutorial/forced_damped_pendulum.cpp
48   :language: c++
49   :lines: 18-33
50
51Note that, for the sake of completeness, we passed an explicit initial value for the time
52variable via the keyword argument ``kw::time``. In this specific case, this is superfluous,
53as the default initial value for the time variable is already zero.
54
55We can now integrate the system for a few time units, checking how the value of :math:`x`
56varies in time:
57
58.. literalinclude:: ../tutorial/forced_damped_pendulum.cpp
59   :language: c++
60   :lines: 35-40
61
62.. code-block:: console
63
64   x = 3.49038
65   x = 5.93825
66   x = 7.30491
67   x = 8.12543
68   x = 5.12362
69   x = 0.979573
70   x = -0.90328
71   x = -0.127736
72   x = -0.773195
73   x = 1.8008
74   x = 2.71244
75   x = -1.00752
76   x = -1.55152
77   x = 1.60996
78   x = -0.880721
79   x = -0.970923
80   x = 2.35702
81   x = 0.0993313
82   x = -1.95449
83   x = 1.46416
84   x = 0.243313
85   x = -1.949
86   x = 1.55939
87   x = 1.21015
88   x = -2.06244
89
90After an initial excursion to higher values for :math:`x`, the system seems to settle into a stable motion. Note that, because
91this system can exhibit chaotic behaviour, changing
92the initial conditions might lead to a qualitatively-different long-term behaviour.
93
94Full code listing
95-----------------
96
97.. literalinclude:: ../tutorial/forced_damped_pendulum.cpp
98   :language: c++
99   :lines: 9-
100