
.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
.. "auto_examples/07_mann_linear_regression.py"
.. LINE NUMBERS ARE GIVEN BELOW.

.. only:: html

    .. note::
        :class: sphx-glr-download-link-note

        :ref:`Go to the end <sphx_glr_download_auto_examples_07_mann_linear_regression.py>`
        to download the full example code

.. rst-class:: sphx-glr-example-title

.. _sphx_glr_auto_examples_07_mann_linear_regression.py:


===============================================
Example 7: Mann Eddy Lifetime Linear Regression
===============================================

This example demonstrates the a simple configuration of ``DRDMannTurb`` to spectra fitting
while using a linear approximation to the Mann eddy lifetime function (in log-log space)
under the Kaimal one-point spectra.

For reference, the full Mann eddy lifetime function is given by

.. math::

    \tau^{\mathrm{IEC}}(k)=\frac{(k L)^{-\frac{2}{3}}}{\sqrt{{ }_2 F_1\left(1 / 3,17 / 6 ; 4 / 3 ;-(k L)^{-2}\right)}}

where the hypergeometric function can only be evaluated on the CPU. The purpose of this example is
to show how a GPU kernel of a linear approximation (in log-log space) of the Mann eddy lifetime can
be generated automatically to speed up tasks that require the GPU. As before, the Kaimal spectra is
used for the one-point-spectra model.

The external API works the same as with other models, but the following may speed up some tasks
that rely exclusively on the Mann eddy lifetime function.

.. GENERATED FROM PYTHON SOURCE LINES 26-30

Import packages
---------------

First, we import the packages we need for this example.

.. GENERATED FROM PYTHON SOURCE LINES 30-49

.. code-block:: Python


    import torch
    import torch.nn as nn

    from drdmannturb import EddyLifetimeType
    from drdmannturb.parameters import (
        LossParameters,
        NNParameters,
        PhysicalParameters,
        ProblemParameters,
    )
    from drdmannturb.spectra_fitting import CalibrationProblem, OnePointSpectraDataGenerator

    device = "cuda" if torch.cuda.is_available() else "cpu"

    if torch.cuda.is_available():
        torch.set_default_tensor_type("torch.cuda.FloatTensor")









.. GENERATED FROM PYTHON SOURCE LINES 50-53

Set up physical parameters and domain associated with the Kaimal spectrum.
We perform the spectra fitting over the :math:`k_1` space :math:`[10^{{-1}}, 10^2]`
with 20 points.

.. GENERATED FROM PYTHON SOURCE LINES 53-63

.. code-block:: Python


    # Scales associated with Kaimal spectrum
    L = 0.59  # length scale
    Gamma = 3.9  # time scale
    sigma = 3.2  # magnitude (σ = αϵ^{2/3})

    zref = 1  # reference height

    domain = torch.logspace(-1, 2, 20)








.. GENERATED FROM PYTHON SOURCE LINES 64-78

``CalibrationProblem`` Construction
-----------------------------------
The following cell defines the ``CalibrationProblem`` using default values
for the ``NNParameters`` and ``LossParameters`` dataclasses. Importantly,
these data classes are not necessary, see their respective documentations for the default values.
The current set-up involves using the Mann model for the eddy lifetime function, meaning no
neural network is used in learning the :math:`\tau` function. Additionally, the physical parameters
are taken from the reference values for the Kaimal spectra. Finally, in this scenario the regression
occurs as an MSE fit to the spectra, which are generated from Mann turbulence (i.e. a synthetic data fit).
The ``EddyLifetimeType.MANN_APPROX`` argument determines the type of eddy lifetime function to use.
Here, we will employ a linear regression to determine a surrogate eddy lifetime function. Using one
evaluation of the Mann function on the provided spectra (here we are just taking it as if it's from a Mann model)
which can be done from either synthetic or real-world data. In normal space, this is a function of the form :math:`` \exp(\alpha \boldsymbol{k} + \beta)`
where the :math:`\alpha, \beta` are coefficients determined by the linear regression in log-log space.

.. GENERATED FROM PYTHON SOURCE LINES 78-91

.. code-block:: Python

    pb = CalibrationProblem(
        nn_params=NNParameters(
            nlayers=2,
            hidden_layer_sizes=[10, 10],
            activations=[nn.ReLU(), nn.ReLU()],
        ),
        prob_params=ProblemParameters(
            nepochs=10, eddy_lifetime=EddyLifetimeType.MANN_APPROX
        ),
        loss_params=LossParameters(),
        phys_params=PhysicalParameters(L=L, Gamma=Gamma, sigma=sigma, domain=domain),
        device=device,
    )







.. GENERATED FROM PYTHON SOURCE LINES 92-98

Data Generation
---------------
In the following cell, we construct our :math:`k_1` data points grid and
generate the values. ``Data`` will be a tuple ``(<data points>, <data values>)``.
It is worth noting that the second element of each tuple in ``DataPoints`` is the corresponding
reference height, which we have chosen to be uniformly `zref`.

.. GENERATED FROM PYTHON SOURCE LINES 98-100

.. code-block:: Python

    Data = OnePointSpectraDataGenerator(zref=zref, data_points=domain).Data








.. GENERATED FROM PYTHON SOURCE LINES 101-105

Calibration
-----------
Now, we fit our model. ``CalibrationProblem.calibrate`` takes the tuple ``Data``
which we just constructed and performs a typical training loop.

.. GENERATED FROM PYTHON SOURCE LINES 105-110

.. code-block:: Python

    optimal_parameters = pb.calibrate(data=Data)

    pb.print_calibrated_params()






.. rst-class:: sphx-glr-script-out

 .. code-block:: none

    ========================================
    Mann Linear Approximation R2 Score in log-log space: 0.9920140661948813
    ========================================
    ========================================
    Initial loss: 1.6704806837355108
    ========================================

      0%|          | 0/10 [00:00<?, ?it/s]
     10%|█         | 1/10 [00:02<00:25,  2.86s/it]
     20%|██        | 2/10 [00:03<00:10,  1.33s/it]
     60%|██████    | 6/10 [00:03<00:01,  3.07it/s]
    100%|██████████| 10/10 [00:03<00:00,  5.93it/s]
    100%|██████████| 10/10 [00:03<00:00,  3.00it/s]
    ========================================
    Spectra fitting concluded with final loss: 0.043833329137891446
    ========================================
    Optimal calibrated L        :   0.5803 
    Optimal calibrated Γ        :   0.4354 
    Optimal calibrated αϵ^{2/3} :   3.2239 
    ========================================




.. GENERATED FROM PYTHON SOURCE LINES 111-114

The following plot shows the best fit to the synthetic Mann data. Notice that
the eddy lifetime function is linear in log-log space and is a close approximation
to the Mann eddy lifetime function.

.. GENERATED FROM PYTHON SOURCE LINES 114-115

.. code-block:: Python

    pb.plot()



.. image-sg:: /auto_examples/images/sphx_glr_07_mann_linear_regression_001.png
   :alt: One-point spectra, Eddy lifetime
   :srcset: /auto_examples/images/sphx_glr_07_mann_linear_regression_001.png
   :class: sphx-glr-single-img






.. rst-class:: sphx-glr-timing

   **Total running time of the script:** (0 minutes 7.929 seconds)


.. _sphx_glr_download_auto_examples_07_mann_linear_regression.py:

.. only:: html

  .. container:: sphx-glr-footer sphx-glr-footer-example

    .. container:: sphx-glr-download sphx-glr-download-jupyter

      :download:`Download Jupyter notebook: 07_mann_linear_regression.ipynb <07_mann_linear_regression.ipynb>`

    .. container:: sphx-glr-download sphx-glr-download-python

      :download:`Download Python source code: 07_mann_linear_regression.py <07_mann_linear_regression.py>`


.. only:: html

 .. rst-class:: sphx-glr-signature

    `Gallery generated by Sphinx-Gallery <https://sphinx-gallery.github.io>`_
