|
| 1 | +.. _sec-extensions-capd-capd: |
| 2 | + |
| 3 | +CAPD (rigorous numerics in dynamical systems) |
| 4 | +============================================= |
| 5 | + |
| 6 | + Main author: `Maël Godard <https://godardma.github.io>`_ |
| 7 | + |
| 8 | +This page describes how to use the CAPD library with Codac. CAPD is a C++ library for rigorous numerics in dynamical systems. |
| 9 | + |
| 10 | +To use CAPD with Codac, you first need to install the CAPD library. You can find the installation instructions on the `CAPD website <http://capd.ii.uj.edu.pl/html/capd_compilation.html>`_. |
| 11 | + |
| 12 | +Note that as CAPD is a C++ only library, the content present in this page is **only available in C++**. |
| 13 | + |
| 14 | + |
| 15 | +.. _subsec-extensions-capd-capd-install: |
| 16 | +Installing the ``codac-capd`` extension |
| 17 | +--------------------------------------- |
| 18 | + |
| 19 | +To install the ``codac-capd`` extension, you need to install the Codac library from its sources. This can be done :ref:`by using CMake <sec-install-cpp>` with the option ``WITH_CAPD=ON``. For example: |
| 20 | + |
| 21 | +.. code-block:: bash |
| 22 | +
|
| 23 | + cmake -DCMAKE_INSTALL_PREFIX=$HOME/ibex-lib/build_install -DCMAKE_BUILD_TYPE=Release -DWITH_CAPD=ON .. |
| 24 | +
|
| 25 | +We highly recommend to test the installation of the library with the provided tests. To do so, you can use the following command: |
| 26 | + |
| 27 | +.. code-block:: bash |
| 28 | +
|
| 29 | + make test |
| 30 | +
|
| 31 | +
|
| 32 | +Content |
| 33 | +------- |
| 34 | + |
| 35 | +The ``codac-capd`` extension provides functions to convert CAPD objects to Codac objects and vice versa. |
| 36 | + |
| 37 | +The functions are ``to_capd`` and ``to_codac``. They can be used to convert the following objects: |
| 38 | + |
| 39 | +- ``capd::Interval`` :math:`\leftrightarrow` ``codac2::Interval`` |
| 40 | +- ``capd::IVector`` :math:`\leftrightarrow` ``codac2::IntervalVector`` |
| 41 | +- ``capd::IMatrix`` :math:`\leftrightarrow` ``codac2::IntervalMatrix`` |
| 42 | +- ``capd::ITimeMap::SolutionCurve`` :math:`\rightarrow` ``codac2::SlicedTube<codac2::IntervalVector>`` |
| 43 | + |
| 44 | + |
| 45 | +How to use |
| 46 | +---------- |
| 47 | + |
| 48 | +The header of the ``codac-capd`` extension is not included by default. You need to include it manually in your code, together with the CAPD library: |
| 49 | + |
| 50 | +.. code-block:: c++ |
| 51 | + |
| 52 | + #include <codac-capd.h> |
| 53 | + #include <capd/capdlib.h> |
| 54 | + |
| 55 | +You can use the functions ``to_capd`` and ``to_codac`` to convert between CAPD and Codac objects as follows: |
| 56 | + |
| 57 | +.. tabs:: |
| 58 | + |
| 59 | + .. code-tab:: c++ |
| 60 | + |
| 61 | + codac2::Interval codac_interval(0,2); // Codac interval [0, 2] |
| 62 | + capd::Interval capd_interval = to_capd(codac_interval); // convert to CAPD interval |
| 63 | + codac2::Interval codac_interval2 = to_codac(capd_interval); // convert back to Codac interval |
| 64 | + |
| 65 | + |
| 66 | +Example |
| 67 | +------- |
| 68 | + |
| 69 | +.. image:: img/pendulum.png |
| 70 | + :alt: State variables of the pendulum |
| 71 | + :align: right |
| 72 | + :width: 130px |
| 73 | + |
| 74 | +For this example we will consider the pendulum with friction. |
| 75 | + |
| 76 | +The state variables of the pendulum are its angle :math:`\theta` and its angular velocity :math:`\omega`. The pendulum follows the following dynamic: |
| 77 | + |
| 78 | +.. math:: |
| 79 | + |
| 80 | + \left(\begin{array}{c} |
| 81 | + \dot{\theta}\\ |
| 82 | + \dot{\omega} |
| 83 | + \end{array}\right)=\left(\begin{array}{c} |
| 84 | + \omega\\ |
| 85 | + -\sin(\theta)\cdot\frac{g}{l}-0.5\omega |
| 86 | + \end{array}\right), |
| 87 | + |
| 88 | +
|
| 89 | +where :math:`g` is the gravity constant and :math:`l` is the length of the pendulum. |
| 90 | + |
| 91 | +This equation can be passed to the CAPD library as follows: |
| 92 | + |
| 93 | +.. tabs:: |
| 94 | + |
| 95 | + .. group-tab:: C++ |
| 96 | + |
| 97 | + .. literalinclude:: src.cpp |
| 98 | + :language: c++ |
| 99 | + :start-after: [codac-capd-2-beg] |
| 100 | + :end-before: [codac-capd-2-end] |
| 101 | + :dedent: 2 |
| 102 | + |
| 103 | +To solve this ODE, an ``IOdeSolver`` object is necessary. |
| 104 | + |
| 105 | +.. tabs:: |
| 106 | + |
| 107 | + .. group-tab:: C++ |
| 108 | + |
| 109 | + .. literalinclude:: src.cpp |
| 110 | + :language: c++ |
| 111 | + :start-after: [codac-capd-3-beg] |
| 112 | + :end-before: [codac-capd-3-end] |
| 113 | + :dedent: 2 |
| 114 | + |
| 115 | +CAPD then uses an ``ITimeMap`` to make the link between a time step and the solution of the ODE at this time. The ``I`` here stands for ``Interval`` as the solution is an interval guaranteed to enclose the solution. Here we will integrate the ODE between :math:`t_0=0s` and :math:`t_f=20s`. |
| 116 | + |
| 117 | +.. tabs:: |
| 118 | + |
| 119 | + .. group-tab:: C++ |
| 120 | + |
| 121 | + .. literalinclude:: src.cpp |
| 122 | + :language: c++ |
| 123 | + :start-after: [codac-capd-4-beg] |
| 124 | + :end-before: [codac-capd-4-end] |
| 125 | + :dedent: 2 |
| 126 | + |
| 127 | +To completly define the ODE, we need to define the initial conditions. Here we will set the initial angle to :math:`\theta_0=-\frac{\pi}{2}` and the |
| 128 | +initial angular velocity to :math:`\omega_0=0`. For the purpose of this example, we will add a small uncertainty to the initial conditions. The initial conditions are then defined as follows: |
| 129 | + |
| 130 | +.. tabs:: |
| 131 | + |
| 132 | + .. group-tab:: C++ |
| 133 | + |
| 134 | + .. literalinclude:: src.cpp |
| 135 | + :language: c++ |
| 136 | + :start-after: [codac-capd-5-beg] |
| 137 | + :end-before: [codac-capd-5-end] |
| 138 | + :dedent: 2 |
| 139 | + |
| 140 | +There are then two ways to get the result of the integration depending on the use case. |
| 141 | + |
| 142 | +If the desired result is the solution of the ODE at a given time (here say :math:`T=1s`), we can do as follows: |
| 143 | + |
| 144 | +.. tabs:: |
| 145 | + |
| 146 | + .. group-tab:: C++ |
| 147 | + |
| 148 | + .. literalinclude:: src.cpp |
| 149 | + :language: c++ |
| 150 | + :start-after: [codac-capd-6-beg] |
| 151 | + :end-before: [codac-capd-6-end] |
| 152 | + :dedent: 2 |
| 153 | + |
| 154 | +**Be careful, this method modifies the initial set** ``s`` **in place**. |
| 155 | + |
| 156 | +If the desired result is the solution curve (or tube) of the ODE on the time domain :math:`[t_0,t_f]`, we can do as follows: |
| 157 | + |
| 158 | +.. tabs:: |
| 159 | + |
| 160 | + .. group-tab:: C++ |
| 161 | + |
| 162 | + .. literalinclude:: src.cpp |
| 163 | + :language: c++ |
| 164 | + :start-after: [codac-capd-7-beg] |
| 165 | + :end-before: [codac-capd-7-end] |
| 166 | + :dedent: 2 |
| 167 | + |
| 168 | +The variable ``solution`` is the desired solution curve (or tube). The operator ``solution(t)`` gives the solution at time :math:`t`. |
| 169 | +It can be converted into a Codac ``SlicedTube<IntervalVector>`` with the function ``to_codac``. This functions takes two arguments: |
| 170 | + |
| 171 | +- the ``capd::ITimeMap::SolutionCurve`` to convert. |
| 172 | +- a ``codac2::TDomain`` object defining the temporal domain of the tube. |
| 173 | + |
| 174 | +The resulting ``SlicedTube`` will have the same time domain as the one given in argument, completed with the CAPD gates. An example of conversion is : |
| 175 | + |
| 176 | +.. tabs:: |
| 177 | + |
| 178 | + .. group-tab:: C++ |
| 179 | + |
| 180 | + .. literalinclude:: src.cpp |
| 181 | + :language: c++ |
| 182 | + :start-after: [codac-capd-8-beg] |
| 183 | + :end-before: [codac-capd-8-end] |
| 184 | + :dedent: 2 |
| 185 | + |
| 186 | +A full display can be done with the following code: |
| 187 | + |
| 188 | +.. tabs:: |
| 189 | + |
| 190 | + .. group-tab:: C++ |
| 191 | + |
| 192 | + .. literalinclude:: src.cpp |
| 193 | + :language: c++ |
| 194 | + :start-after: [codac-capd-9-beg] |
| 195 | + :end-before: [codac-capd-9-end] |
| 196 | + :dedent: 4 |
| 197 | + |
| 198 | +The result is the following figure, with in green the initial set (:math:`t=0s`) and in red the final set (:math:`t=20s`). The ``SlicedTube`` is displayed in blue with a black edge for better visibility. The orange rectangles correspond to the gates (degenerate slices). |
| 199 | + |
| 200 | +.. figure:: img/pendulum_result.png |
| 201 | + :width: 500px |
| 202 | + |
| 203 | + Result of the CAPD integration of the pendulum, enclosed in a Codac tube. |
0 commit comments