.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/plot_pairwise_alignment.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code or to run this example in your browser via Binder .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_plot_pairwise_alignment.py: Pairwise alignment ================== Shows the usage of the elastic registration to perform a pairwise alignment. .. GENERATED FROM PYTHON SOURCE LINES 7-25 .. code-block:: Python # Author: Pablo Marcos Manchón # License: MIT # sphinx_gallery_thumbnail_number = 5 import matplotlib.colors as clr import matplotlib.pyplot as plt import numpy as np import skfda from skfda.datasets import make_multimodal_samples from skfda.preprocessing.registration import ( FisherRaoElasticRegistration, invert_warping, ) .. GENERATED FROM PYTHON SOURCE LINES 26-47 Given any two functions :math:`f` and :math:`g`, we define their pairwise alignment or registration to be the problem of finding a warping function :math:`\gamma^*` such that a certain energy term :math:`E[f, g \circ \gamma]` is minimized :footcite:p:`marron++_2015_functional`. .. math:: \gamma^*= \arg \min_{\gamma \in \Gamma} E[f \circ \gamma, g] In the case of elastic registration it is taken as energy function the Fisher-Rao distance with a penalisation term, due to the property of invariance to reparameterizations of warpings functions :footcite:p:`srivastava+klassen_2016_functionala`. .. math:: E[f \circ \gamma, g] = d_{FR} (f \circ \gamma, g) Firstly, we will create two unimodal samples, :math:`f` and :math:`g`, defined in [0, 1] wich will be used to show the elastic registration. Due to the similarity of these curves can be aligned almost perfectly between them. .. GENERATED FROM PYTHON SOURCE LINES 47-61 .. code-block:: Python # Samples with modes in 1/3 and 2/3 fd = make_multimodal_samples( n_samples=2, modes_location=[1 / 3, 2 / 3], random_state=1, start=0, mode_std=0.01, ) fig = fd.plot() fig.axes[0].legend(['$f$', '$g$']) plt.show() .. image-sg:: /auto_examples/images/sphx_glr_plot_pairwise_alignment_001.png :alt: plot pairwise alignment :srcset: /auto_examples/images/sphx_glr_plot_pairwise_alignment_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 62-66 In this example :math:`g` will be used as template and :math:`f` will be aligned to it. In the following figure it is shown the result of the registration process, wich can be computed using :class:`~skfda.preprocessing.registration.FisherRaoElasticRegistration`. .. GENERATED FROM PYTHON SOURCE LINES 66-83 .. code-block:: Python f, g = fd[0], fd[1] elastic_registration = FisherRaoElasticRegistration(template=g) # Aligns f to g f_align = elastic_registration.fit_transform(f) fig = fd.plot() f_align.plot(fig=fig, color='C0', linestyle='--') # Legend fig.axes[0].legend(['$f$', '$g$', r'$f \circ \gamma $']) plt.show() .. image-sg:: /auto_examples/images/sphx_glr_plot_pairwise_alignment_002.png :alt: plot pairwise alignment :srcset: /auto_examples/images/sphx_glr_plot_pairwise_alignment_002.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 84-86 The non-linear transformation :math:`\gamma` applied to :math:`f` in the alignment is stored in the attribute `warping_`. .. GENERATED FROM PYTHON SOURCE LINES 86-99 .. code-block:: Python # Warping used in the last transformation warping = elastic_registration.warping_ fig = warping.plot() # Plot identity t = np.linspace(0, 1) fig.axes[0].plot(t, t, linestyle='--') # Legend fig.axes[0].legend([r'$\gamma$', r'$\gamma_{id}$']) plt.show() .. image-sg:: /auto_examples/images/sphx_glr_plot_pairwise_alignment_003.png :alt: plot pairwise alignment :srcset: /auto_examples/images/sphx_glr_plot_pairwise_alignment_003.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 100-104 The transformation necessary to align :math:`g` to :math:`f` will be the inverse of the original warping function, :math:`\gamma^{-1}`. This fact is a consequence of the use of the Fisher-Rao metric as energy function. .. GENERATED FROM PYTHON SOURCE LINES 104-115 .. code-block:: Python warping_inverse = invert_warping(warping) fig = fd.plot(label='$f$') g.compose(warping_inverse).plot(fig=fig, color='C1', linestyle='--') # Legend fig.axes[0].legend(['$f$', '$g$', r'$g \circ \gamma^{-1} $']) plt.show() .. image-sg:: /auto_examples/images/sphx_glr_plot_pairwise_alignment_004.png :alt: plot pairwise alignment :srcset: /auto_examples/images/sphx_glr_plot_pairwise_alignment_004.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 116-123 The amount of deformation used in the registration can be controlled by using a variation of the metric with a penalty term :math:`\lambda \mathcal{R}(\gamma)` wich will reduce the elasticity of the metric. The following figure shows the original curves and the result to the alignment varying :math:`\lambda` from 0 to 0.2. .. GENERATED FROM PYTHON SOURCE LINES 123-148 .. code-block:: Python # Values of lambda penalties = np.linspace(0, 0.2, 20) # Creation of a color gradient cmap = clr.LinearSegmentedColormap.from_list('custom cmap', ['C1', 'C0']) color = cmap(0.2 + 3 * penalties) fig = plt.figure() ax = fig.add_subplot(1, 1, 1) for penalty, c in zip(penalties, color): elastic_registration.set_params(penalty=penalty) elastic_registration.transform(f).plot(fig, color=c) f.plot(fig=fig, color='C0', linewidth=2, label='$f$') g.plot(fig=fig, color='C1', linewidth=2, label='$g$') # Legend fig.axes[0].legend() plt.show() .. image-sg:: /auto_examples/images/sphx_glr_plot_pairwise_alignment_005.png :alt: plot pairwise alignment :srcset: /auto_examples/images/sphx_glr_plot_pairwise_alignment_005.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 149-152 This phenomenon of loss of elasticity is clearly observed in the warpings used, since as the term of penalty increases, the functions are closer to :math:`\gamma_{id}`. .. GENERATED FROM PYTHON SOURCE LINES 152-165 .. code-block:: Python fig = plt.figure() ax = fig.add_subplot(1, 1, 1) for penalty, c in zip(penalties, color): elastic_registration.set_params(penalty=penalty) elastic_registration.transform(f) elastic_registration.warping_.plot(fig, color=c) # Plots identity fig.axes[0].plot(t, t, color='C0', linestyle="--") plt.show() .. image-sg:: /auto_examples/images/sphx_glr_plot_pairwise_alignment_006.png :alt: plot pairwise alignment :srcset: /auto_examples/images/sphx_glr_plot_pairwise_alignment_006.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 166-175 We can perform the pairwise of multiple curves at once. We can use a single curve as template to align a set of samples to it or a set of templates to make the alignemnt the two sets. In the elastic registration example it is shown the alignment of multiple curves to the same template. We will build two sets with 3 curves each, :math:`\{f_i\}` and :math:`\{g_i\}`. .. GENERATED FROM PYTHON SOURCE LINES 175-206 .. code-block:: Python # Creation of the 2 sets of functions state = np.random.RandomState(0) location1 = state.normal(loc=-0.3, scale=0.1, size=3) fd = skfda.datasets.make_multimodal_samples( n_samples=3, modes_location=location1, noise=0.001, random_state=1, ) location2 = state.normal( loc=0.3, scale=0.1, size=3, ) g = skfda.datasets.make_multimodal_samples( n_samples=3, modes_location=location2, random_state=2, ) # Plot of the sets fig = fd.plot(color="C0", label="$f_i$") g.plot(fig=fig, color="C1", label="$g_i$") labels = fig.axes[0].get_lines() fig.axes[0].legend(handles=[labels[0], labels[-1]]) plt.show() .. image-sg:: /auto_examples/images/sphx_glr_plot_pairwise_alignment_007.png :alt: plot pairwise alignment :srcset: /auto_examples/images/sphx_glr_plot_pairwise_alignment_007.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 207-209 The following figure shows the result of the pairwise alignment of :math:`\{f_i\}` to :math:`\{g_i\}`. .. GENERATED FROM PYTHON SOURCE LINES 209-231 .. code-block:: Python # Registration of the sets elastic_registration = FisherRaoElasticRegistration(template=g) fd_registered = elastic_registration.fit_transform(fd) # Plot of the curves fig = fd.plot(color="C0", label="$f_i$") l1 = fig.axes[0].get_lines()[-1] g.plot(fig=fig, color="C1", label="$g_i$") l2 = fig.axes[0].get_lines()[-1] fd_registered.plot( fig=fig, color="C0", linestyle="--", label=r"$f_i \circ \gamma_i$", ) l3 = fig.axes[0].get_lines()[-1] fig.axes[0].legend(handles=[l1, l2, l3]) plt.show() .. image-sg:: /auto_examples/images/sphx_glr_plot_pairwise_alignment_008.png :alt: plot pairwise alignment :srcset: /auto_examples/images/sphx_glr_plot_pairwise_alignment_008.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 232-233 .. footbibliography:: .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 2.244 seconds) .. _sphx_glr_download_auto_examples_plot_pairwise_alignment.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: binder-badge .. image:: images/binder_badge_logo.svg :target: https://mybinder.org/v2/gh/GAA-UAM/scikit-fda/develop?filepath=examples/plot_pairwise_alignment.py :alt: Launch binder :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_pairwise_alignment.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_pairwise_alignment.py ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_