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

.. only:: html

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

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

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

.. _sphx_glr_examples_example_sympy.py:


Building a lmfit model with SymPy
=================================

SymPy is a Python library for symbolic mathematics. It can be very useful to
build a model with SymPy and then apply that model to the data with lmfit.
This example shows how to do that. Please note that this example requires
both the sympy and matplotlib packages.

.. GENERATED FROM PYTHON SOURCE LINES 11-18

.. code-block:: Python

    import matplotlib.pyplot as plt
    import numpy as np
    import sympy
    from sympy.parsing import sympy_parser

    import lmfit








.. GENERATED FROM PYTHON SOURCE LINES 19-21

Instead of creating the SymPy symbols explicitly and building an expression
with them, we will use the SymPy parser.

.. GENERATED FROM PYTHON SOURCE LINES 21-29

.. code-block:: Python


    gauss_peak1 = sympy_parser.parse_expr('A1*exp(-(x-xc1)**2/(2*sigma1**2))')
    gauss_peak2 = sympy_parser.parse_expr('A2*exp(-(x-xc2)**2/(2*sigma2**2))')
    exp_back = sympy_parser.parse_expr('B*exp(-x/xw)')

    model_list = sympy.Array((gauss_peak1, gauss_peak2, exp_back))
    model = sum(model_list)








.. GENERATED FROM PYTHON SOURCE LINES 30-32

We are using SymPy's lambdify function to make a function from the model
expressions. We then use these functions to generate some fake data.

.. GENERATED FROM PYTHON SOURCE LINES 32-36

.. code-block:: Python


    model_list_func = sympy.lambdify(list(model_list.free_symbols), model_list)
    model_func = sympy.lambdify(list(model.free_symbols), model)








.. GENERATED FROM PYTHON SOURCE LINES 37-38

Generate synthetic data with noise and plot the data.

.. GENERATED FROM PYTHON SOURCE LINES 38-50

.. code-block:: Python

    np.random.seed(1)
    x = np.linspace(0, 10, 40)
    param_values = dict(x=x, A1=2, sigma1=1, sigma2=1, A2=3, xc1=2, xc2=5, xw=4, B=5)
    y = model_func(**param_values)
    yi = model_list_func(**param_values)
    yn = y + np.random.randn(y.size)*0.4

    plt.plot(x, yn, 'o')
    plt.plot(x, y)
    for c in yi:
        plt.plot(x, c, color='0.7')




.. image-sg:: /examples/images/sphx_glr_example_sympy_001.png
   :alt: example sympy
   :srcset: /examples/images/sphx_glr_example_sympy_001.png, /examples/images/sphx_glr_example_sympy_001_3_00x.png 3.00x
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 51-52

Next, we will just create a lmfit model from the function and fit the data.

.. GENERATED FROM PYTHON SOURCE LINES 52-55

.. code-block:: Python

    lm_mod = lmfit.Model(model_func, independent_vars=('x',))
    res = lm_mod.fit(data=yn, **param_values)








.. GENERATED FROM PYTHON SOURCE LINES 56-60

.. code-block:: Python

    res.plot_fit()
    plt.plot(x, y, label='true')
    plt.legend()




.. image-sg:: /examples/images/sphx_glr_example_sympy_002.png
   :alt: Model(_lambdifygenerated)
   :srcset: /examples/images/sphx_glr_example_sympy_002.png, /examples/images/sphx_glr_example_sympy_002_3_00x.png 3.00x
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 61-65

The nice thing of using SymPy is that we can easily modify our fit function.
Let's assume we know that the width of both Gaussians are identical. Similarly,
we assume that the ratio between both Gaussians is fixed to 3:2 for some
reason. Both can be expressed by just substituting the variables.

.. GENERATED FROM PYTHON SOURCE LINES 65-74

.. code-block:: Python

    model2 = model.subs('sigma2', 'sigma1').subs('A2', '3/2*A1')
    model2_func = sympy.lambdify(list(model2.free_symbols), model2)
    lm_mod = lmfit.Model(model2_func, independent_vars=('x',))
    param2_values = dict(x=x, A1=2, sigma1=1, xc1=2, xc2=5, xw=4, B=5)
    res2 = lm_mod.fit(data=yn, **param2_values)
    res2.plot_fit()
    plt.plot(x, y, label='true')
    plt.legend()
    plt.show()



.. image-sg:: /examples/images/sphx_glr_example_sympy_003.png
   :alt: Model(_lambdifygenerated)
   :srcset: /examples/images/sphx_glr_example_sympy_003.png, /examples/images/sphx_glr_example_sympy_003_3_00x.png 3.00x
   :class: sphx-glr-single-img






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

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


.. _sphx_glr_download_examples_example_sympy.py:

.. only:: html

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

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

      :download:`Download Jupyter notebook: example_sympy.ipynb <example_sympy.ipynb>`

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

      :download:`Download Python source code: example_sympy.py <example_sympy.py>`

    .. container:: sphx-glr-download sphx-glr-download-zip

      :download:`Download zipped: example_sympy.zip <example_sympy.zip>`


.. only:: html

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

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