I have a question about fitting data with a model. I have a quite complicated model, based on Arctans, modified Bessel functions, etc, that I want to fit to my data, a table of couples (minimal example).
The first method that I used (brute force) with NonLinearModelFit
works but return some warnings that I don't know how to avoid, and the fitting parameters, especially the last one are wrong.
Here is the code that I used:
ClearAll["Global`.*"];
g = 4.295676165008085`*^-6;
y = a/b;
c[x_] := v/( (1 + x*y)*(1 + (x*y)^2) );
d0 = v*a^3;
e[x_] := d0 * (-ArcTan[x*y] + 0.5* Log[1 + (x*y)^2] +
Log[1 + (x*y)]);
f[x_] := Sqrt[g*e[x]/(x*a)]
(*h[x_] := Sqrt[3*g*h1/a]*(3*x)^2*(BesselI[0, 3*x]*BesselK[0, 3*x] -
BesselI[1, 3*x]*BesselK[1, 3*x])*)
(*after reedit*)
h[x_] :=
Sqrt[3*g*h1/a]*(3*x)*Sqrt[(BesselI[0, 3*x]*BesselK[0, 3*x] - BesselI[1, 3*x]*BesselK[1, 3*x])]
j[x_] := (x*a*h[x]^2)/g
(*k[x_] := Sqrt[g*k1/a]*x^2*(BesselI[0, x]*BesselK[0, x] - BesselI[1, x]*BesselK[1, x])*)
(*after reedit*)
k[x_]=
Sqrt[g*k1/a]*x* Sqrt[(BesselI[0, x]*BesselK[0, x] - BesselI[1, x]*BesselK[1, x])]
l[x_] := (x*a*k[x]^2)/g
(*free parameters of my fit : h1,k1,a,b,v*)
firstbin =
{{0.0745682, 5.77, 2.59}, {0.090855, 2.26, 3.66},
{0.0815721, 13.1, 8.53}, {0.0505227, 7.89362, 1.16673},
{0.0626294, 9.1, 10.4523}, {0.0772834, 3.89214, 5.4580},
{0.084189, 3.7676, 0.714178}, {0.0927923, 1.7, 5.5},
{0.0713416, 9.703, 2.34}, {0.0876698, 7.1589, 2.84105},
{0.0376569, 8.85545, 5.53406}, {0.045388, 6.4866, 1.61059},
{0.0559153, 4.67013, 1.75362}, {0.0801532, 9.81, 1.6915},
{0.061584, 2.875, 1.90919}, {0.0930765, 4.5325456, 2.74357},
{0.0832263, 7.306, 2.11707}, {0.0394981, 1.95511, 1.67028},
{0.126419, 13.54, 3.29974}, {0.185348, 12.6713, 2.9279},
{0.184662, 8.1504, 2.96985}, {0.154398, 8.72227, 3.84503},
{0.199546,10.1779, 1.97452}};
z = Table[Log[10, firstbin[[i, 2]]], {i, 1, Length[firstbin]}];
rnorm1 = Table[firstbin[[i, 1]], {i, 1, Length[firstbin]}];
data1 = Table[{rnorm1[[i]], z[[i]]}, {i, 1, Length[z]}];
u[x_] = h[x] + f[x] + k[x];
fitLine1 =
NonlinearModelFit[
data1,
{u[s], (k1/a > 0 && b > 0 && (a/b) > 0 && (h1/a) > 0)},
{h1, k1, a, b, v},
s]
fitLine1[s]
NonlinearModelFit::eit: The algorithm does not converge to the tolerance of 4.806217383937354`*^-6 in 500 iterations. The best estimated solution, with feasibility residual, KKT residual, or complementary residual of {0.000037871,0.000885062,8.34782*10^-8}, is returned. >>
fitLine1["ParameterTable"]
FittedModel::constr: The property values {ParameterTable} assume an unconstrained model. The results for these properties may not be valid, particularly if the fitted parameters are near a constraint boundary. >>
This method works in 14.802 sec (determined with Timing), so it is quite long (I mean I think there is faster methods).
I tried with another method, but it gave me:
NonlinearModelFit::nrnum: The function value [...]is not a real number at {h1,k1,a,b,v} = {1.,1.,1.,1.,1.}. >>
Here is the code :
u[h1_?NumberQ, k1_?NumberQ, a_?NumberQ, b_?NumberQ, v_?NumberQ] :=
(u[h1, k1, a, b, v] = h[s] + f[s] + k[s])
fitLine1 =
NonlinearModelFit[
data1,
{u[h1, k1, a, b, v][s], (k1/a > 0 && b > 0 && (a/b) > 0 && (h1/a) > 0)},
{h1, k1, a, b, v},
s]
I don't know why this doesn't work ( as I precised some conditions on the fit parameters), and if there is a way to make an optimal fit of my data?
PS: in the attached file, I put the table of parameters concerning my first attempt