{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%matplotlib inline" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\nFit Specifying a Function to Compute the Jacobian\n=================================================\n\nSpecifying an analytical function to calculate the Jacobian can speed-up the\nfitting procedure.\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\n\n\ndef func(pars, x, data=None):\n a, b, c = pars['a'], pars['b'], pars['c']\n model = a * np.exp(-b*x) + c\n if data is None:\n return model\n return model - data\n\n\ndef dfunc(pars, x, data=None):\n a, b = pars['a'], pars['b']\n v = np.exp(-b*x)\n return np.array([v, -a*x*v, np.ones(len(x))])\n\n\ndef f(var, x):\n return var[0] * np.exp(-var[1]*x) + var[2]\n\n\nparams = Parameters()\nparams.add('a', value=10)\nparams.add('b', value=10)\nparams.add('c', value=10)\n\na, b, c = 2.5, 1.3, 0.8\nx = np.linspace(0, 4, 50)\ny = f([a, b, c], x)\ndata = y + 0.15*np.random.normal(size=x.size)\n\n# fit without analytic derivative\nmin1 = Minimizer(func, params, fcn_args=(x,), fcn_kws={'data': data})\nout1 = min1.leastsq()\nfit1 = func(out1.params, x)\n\n# fit with analytic derivative\nmin2 = Minimizer(func, params, fcn_args=(x,), fcn_kws={'data': data})\nout2 = min2.leastsq(Dfun=dfunc, col_deriv=1)\nfit2 = func(out2.params, x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Comparison of fit to exponential decay with/without analytical derivatives\nto model = a*exp(-b*x) + c\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "print('''\n\"true\" parameters are: a = %.3f, b = %.3f, c = %.3f\n\n==============================================\nStatistic/Parameter| Without | With |\n----------------------------------------------\nN Function Calls | %3i | %3i |\nChi-square | %.4f | %.4f |\n a | %.4f | %.4f |\n b | %.4f | %.4f |\n c | %.4f | %.4f |\n----------------------------------------------\n''' % (a, b, c,\n out1.nfev, out2.nfev,\n out1.chisqr, out2.chisqr,\n out1.params['a'], out2.params['a'],\n out1.params['b'], out2.params['b'],\n out1.params['c'], out2.params['c']))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "and the best-fit to the synthetic data (with added noise) is the same for\nboth methods:\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "plt.plot(x, data, 'ro')\nplt.plot(x, fit1, 'b')\nplt.plot(x, fit2, 'k')\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 }