I want to fit my data in gnuplot, with a fitting relation that has the modified Bessel function of the 2nd kind in it. So let's say it kind of looks like this:
f(x)= A*x + b*besselk(1,b)
(I wrote it in terms of matlab or octave and the coefficients, I want to find with the fit, are A and b, so one of them is IN the bessel). But the problem is gnuplot doesn't have modified bessel function of 2nd kind.
Anyone have any idea how I can do that?
The best fitting strategy is usually to reduce your non-linear or non-polynomial problem to a linear or polynomial one. In particular, the linear problem always has one and only one solution. So we would ideally fit
f(x) = A*x + B
whereB = b * besy1(b)
- this is for Bessel functions of the second kind, see edit below for modified Bessel functions of the second kind, which are not available in Gnuplot. You do that like this:Once you have
B
you can locate theb
that corresponds to the intersection ofy = x * besy1(x)
withB
atx = b
. Becausebesy1(x)
is oscillatory you might have several results, but depending on the range where your data is given you can choose the correct one. Say you gotB = 1.2
from the fit, then the intersections in the[0:10]
interval are as follows:If your region of interest is around
x = 4.65
, where there is the approximate location of one of the intersections, then look for the exact intersect. The distance betweenx * besy1(x)
andB
will approach zero in this region and so the distance squared can be approximated by a parabola with a well defined minimum:Your optimum
x = b
is the position of this minimum. You can export this as data and fit to a parabolaf(x) = a2*x**2 + b2*x + c2
with the minimum given byf'(x) = 0
, that is,x = -b2 / (2.*a2)
:This gives
x = 4.65447163370989
for the minimum's location, which corresponds to the optimumb
inB = b*besy1(b)
.The accuracy of this will depend on the goodness of the quadratic fit, which will in turn depend on how narrow about the minimum your range of x values is. In this case, the range
[4.6:4.7]
led to the quadratic fit being quite good but not perfect (you could narrow it down even further):Edit
For modified Bessel functions of the second kind, or other complicated functions not available in Gnuplot, you could use an external parser. For example see my answer on how to use an external python code to parse functions: Passing Python functions to Gnuplot.
You can use
scipy
to access your function modifying the Python script from my other answer (file nametest.py
):and within Gnuplot use this as
then all the above procedure works just replacing
besy1(x)
bykn(1,x)
.