
.. 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

        Click :ref:`here <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 use that apply that model to the data with
lmfit. This example shows how to do that. Notice, that this example requires
both sympy and matplotlib.

.. GENERATED FROM PYTHON SOURCE LINES 10-20

.. code-block:: default


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

    import lmfit

    np.random.seed(1)








.. GENERATED FROM PYTHON SOURCE LINES 21-23

Instead of creating the sympy-sybols explicitly and building an expression
with  them, we will use the sympy parser.

.. GENERATED FROM PYTHON SOURCE LINES 23-32

.. code-block:: default


    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)
    model





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

 Out:

 .. code-block:: none


    A1*exp(-(x - xc1)**2/(2*sigma1**2)) + A2*exp(-(x - xc2)**2/(2*sigma2**2)) + B*exp(-x/xw)



.. GENERATED FROM PYTHON SOURCE LINES 33-35

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

.. GENERATED FROM PYTHON SOURCE LINES 35-52

.. code-block:: default


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

    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', zorder=1.9, ms=3)
    plt.plot(x, y, lw=3)
    for c in yi:
        plt.plot(x, c, lw=1, c='0.7')





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





.. GENERATED FROM PYTHON SOURCE LINES 53-54

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

.. GENERATED FROM PYTHON SOURCE LINES 54-62

.. code-block:: default


    lm_mod = lmfit.Model(model_func, independent_vars=('x'))
    res = lm_mod.fit(data=yn, **param_values)
    res.plot_fit()
    plt.plot(x, y, label='true')
    plt.legend()

    res



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



.. raw:: html

    <div class="output_subarea output_html rendered_html output_result">
    <h2> Model</h2> Model(_lambdifygenerated) <h2>Fit Statistics</h2><table><tr><td>fitting method</td><td>leastsq</td><td></td></tr><tr><td># function evals</td><td>64</td><td></td></tr><tr><td># data points</td><td>40</td><td></td></tr><tr><td># variables</td><td>8</td><td></td></tr><tr><td>chi-square</td><td> 5.39675674</td><td></td></tr><tr><td>reduced chi-square</td><td> 0.16864865</td><td></td></tr><tr><td>Akaike info crit.</td><td>-64.1232514</td><td></td></tr><tr><td>Bayesian info crit.</td><td>-50.6122157</td><td></td></tr></table><h2>Variables</h2><table><tr><th> name </th><th> value </th><th> standard error </th><th> relative error </th><th> initial value </th><th> min </th><th> max </th><th> vary </th></tr><tr><td> A1 </td><td>  2.03953400 </td><td>  0.30458039 </td><td> (14.93%) </td><td> 2 </td><td>        -inf </td><td>         inf </td><td> True </td></tr><tr><td> A2 </td><td>  3.24628549 </td><td>  0.27392227 </td><td> (8.44%) </td><td> 3 </td><td>        -inf </td><td>         inf </td><td> True </td></tr><tr><td> xc1 </td><td>  2.11179622 </td><td>  0.14262608 </td><td> (6.75%) </td><td> 2 </td><td>        -inf </td><td>         inf </td><td> True </td></tr><tr><td> B </td><td>  5.42073333 </td><td>  0.38660956 </td><td> (7.13%) </td><td> 5 </td><td>        -inf </td><td>         inf </td><td> True </td></tr><tr><td> xc2 </td><td>  5.05045727 </td><td>  0.09355979 </td><td> (1.85%) </td><td> 5 </td><td>        -inf </td><td>         inf </td><td> True </td></tr><tr><td> sigma1 </td><td>  0.82863194 </td><td>  0.18223396 </td><td> (21.99%) </td><td> 1 </td><td>        -inf </td><td>         inf </td><td> True </td></tr><tr><td> sigma2 </td><td>  0.99878722 </td><td>  0.11821179 </td><td> (11.84%) </td><td> 1 </td><td>        -inf </td><td>         inf </td><td> True </td></tr><tr><td> xw </td><td>  3.51913583 </td><td>  0.43246203 </td><td> (12.29%) </td><td> 4 </td><td>        -inf </td><td>         inf </td><td> True </td></tr></table><h2>Correlations (unreported correlations are < 0.100)</h2><table><tr><td>B</td><td>sigma1</td><td>-0.6745</td></tr><tr><td>A2</td><td>xw</td><td>-0.6321</td></tr><tr><td>sigma2</td><td>xw</td><td>-0.5722</td></tr><tr><td>xc2</td><td>sigma1</td><td>0.5537</td></tr><tr><td>A1</td><td>A2</td><td>0.5293</td></tr><tr><td>A1</td><td>xw</td><td>-0.5152</td></tr><tr><td>xc1</td><td>sigma2</td><td>-0.4850</td></tr><tr><td>xc1</td><td>xc2</td><td>0.4211</td></tr><tr><td>xc2</td><td>sigma2</td><td>-0.4149</td></tr><tr><td>sigma1</td><td>sigma2</td><td>-0.4054</td></tr><tr><td>A1</td><td>B</td><td>-0.3567</td></tr><tr><td>xc1</td><td>B</td><td>0.3213</td></tr><tr><td>A1</td><td>sigma2</td><td>0.2476</td></tr><tr><td>B</td><td>xw</td><td>-0.2475</td></tr><tr><td>B</td><td>xc2</td><td>-0.2176</td></tr><tr><td>A1</td><td>xc1</td><td>-0.2079</td></tr><tr><td>A2</td><td>sigma1</td><td>0.1766</td></tr><tr><td>B</td><td>sigma2</td><td>0.1662</td></tr><tr><td>A2</td><td>B</td><td>-0.1332</td></tr><tr><td>sigma1</td><td>xw</td><td>0.1048</td></tr><tr><td>A2</td><td>xc2</td><td>0.1032</td></tr></table>
    </div>
    <br />
    <br />

.. GENERATED FROM PYTHON SOURCE LINES 63-67

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 is identical. Simliary,
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 67-78

.. code-block:: default


    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, A2=3, xc1=2, xc2=5, xw=4, B=5)
    res2 = lm_mod.fit(data=yn, **param_values)
    res2.plot_fit()
    plt.plot(x, y, label='true')
    plt.legend()

    res2



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


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

 Out:

 .. code-block:: none

    /build/lmfit-py-V3uHvC/lmfit-py-1.0.2/lmfit/model.py:968: UserWarning: The keyword argument sigma2 does not match any arguments of the model function. It will be ignored.
      warnings.warn("The keyword argument %s does not " % name +
    /build/lmfit-py-V3uHvC/lmfit-py-1.0.2/lmfit/model.py:968: UserWarning: The keyword argument A2 does not match any arguments of the model function. It will be ignored.
      warnings.warn("The keyword argument %s does not " % name +


.. raw:: html

    <div class="output_subarea output_html rendered_html output_result">
    <h2> Model</h2> Model(_lambdifygenerated) <h2>Fit Statistics</h2><table><tr><td>fitting method</td><td>leastsq</td><td></td></tr><tr><td># function evals</td><td>29</td><td></td></tr><tr><td># data points</td><td>40</td><td></td></tr><tr><td># variables</td><td>6</td><td></td></tr><tr><td>chi-square</td><td> 5.49246202</td><td></td></tr><tr><td>reduced chi-square</td><td> 0.16154300</td><td></td></tr><tr><td>Akaike info crit.</td><td>-67.4201137</td><td></td></tr><tr><td>Bayesian info crit.</td><td>-57.2868370</td><td></td></tr></table><h2>Variables</h2><table><tr><th> name </th><th> value </th><th> standard error </th><th> relative error </th><th> initial value </th><th> min </th><th> max </th><th> vary </th></tr><tr><td> A1 </td><td>  2.16429205 </td><td>  0.17552276 </td><td> (8.11%) </td><td> 2 </td><td>        -inf </td><td>         inf </td><td> True </td></tr><tr><td> xc1 </td><td>  2.13326031 </td><td>  0.14814919 </td><td> (6.94%) </td><td> 2 </td><td>        -inf </td><td>         inf </td><td> True </td></tr><tr><td> B </td><td>  5.17531388 </td><td>  0.29344865 </td><td> (5.67%) </td><td> 5 </td><td>        -inf </td><td>         inf </td><td> True </td></tr><tr><td> xc2 </td><td>  5.09911007 </td><td>  0.07468792 </td><td> (1.46%) </td><td> 5 </td><td>        -inf </td><td>         inf </td><td> True </td></tr><tr><td> sigma1 </td><td>  0.95831199 </td><td>  0.07211389 </td><td> (7.53%) </td><td> 1 </td><td>        -inf </td><td>         inf </td><td> True </td></tr><tr><td> xw </td><td>  3.56835239 </td><td>  0.40042300 </td><td> (11.22%) </td><td> 4 </td><td>        -inf </td><td>         inf </td><td> True </td></tr></table><h2>Correlations (unreported correlations are < 0.100)</h2><table><tr><td>A1</td><td>xw</td><td>-0.6832</td></tr><tr><td>xc1</td><td>B</td><td>0.6816</td></tr><tr><td>B</td><td>sigma1</td><td>-0.4525</td></tr><tr><td>xc1</td><td>sigma1</td><td>-0.4283</td></tr><tr><td>xc1</td><td>xc2</td><td>0.4184</td></tr><tr><td>sigma1</td><td>xw</td><td>-0.4158</td></tr><tr><td>B</td><td>xc2</td><td>0.3071</td></tr><tr><td>xc2</td><td>xw</td><td>-0.2282</td></tr><tr><td>B</td><td>xw</td><td>-0.1931</td></tr><tr><td>A1</td><td>B</td><td>-0.1919</td></tr><tr><td>A1</td><td>sigma1</td><td>0.1428</td></tr><tr><td>xc1</td><td>xw</td><td>-0.1390</td></tr></table>
    </div>
    <br />
    <br />


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

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


.. _sphx_glr_download_examples_example_sympy.py:


.. only :: html

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



  .. 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-jupyter

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


.. only:: html

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

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