{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%matplotlib inline" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\nFit Using Inequality Constraint\n===============================\n\nSometimes specifying boundaries using ``min`` and ``max`` are not sufficient,\nand more complicated (inequality) constraints are needed. In the example below\nthe center of the Lorentzian peak is constrained to be between 0-5 away from\nthe center of the Gaussian peak.\n\nSee also: https://lmfit.github.io/lmfit-py/constraints.html#using-inequality-constraints\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import matplotlib.pyplot as plt\nimport numpy as np\n\nfrom lmfit import Minimizer, Parameters, report_fit\nfrom lmfit.lineshapes import gaussian, lorentzian\n\n\ndef residual(pars, x, data):\n model = (gaussian(x, pars['amp_g'], pars['cen_g'], pars['wid_g']) +\n lorentzian(x, pars['amp_l'], pars['cen_l'], pars['wid_l']))\n return model - data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Generate the simulated data using a Gaussian and Lorentzian line shape:\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "np.random.seed(0)\nx = np.linspace(0, 20.0, 601)\n\ndata = (gaussian(x, 21, 6.1, 1.2) + lorentzian(x, 10, 9.6, 1.3) +\n np.random.normal(scale=0.1, size=x.size))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Create the fitting parameters and set an inequality constraint for ``cen_l``.\nFirst, we add a new fitting parameter ``peak_split``, which can take values\nbetween 0 and 5. Afterwards, we constrain the value for ``cen_l`` using the\nexpression to be ``'peak_split+cen_g'``:\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pfit = Parameters()\npfit.add(name='amp_g', value=10)\npfit.add(name='amp_l', value=10)\npfit.add(name='cen_g', value=5)\npfit.add(name='peak_split', value=2.5, min=0, max=5, vary=True)\npfit.add(name='cen_l', expr='peak_split+cen_g')\npfit.add(name='wid_g', value=1)\npfit.add(name='wid_l', expr='wid_g')\n\nmini = Minimizer(residual, pfit, fcn_args=(x, data))\nout = mini.leastsq()\nbest_fit = data + out.residual" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Performing a fit, here using the ``leastsq`` algorithm, gives the following\nfitting results:\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "report_fit(out.params)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "and figure:\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "plt.plot(x, data, 'bo')\nplt.plot(x, best_fit, 'r--', label='best fit')\nplt.legend(loc='best')\nplt.show()" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.6" } }, "nbformat": 4, "nbformat_minor": 0 }