# Levenberg-Marquardt method for fitting

I have a model function:

T145[x_, y_, t_, b_, l_, d_] := Intens/(2*π*K0)*NIntegrate[Sqrt[1 + m1^2]*
Erfc[Sqrt[(x - α)^2 + (y - β)^2 + (z - (m1*α-
d))^2]/Sqrt[Dif*4*t]]/(Sqrt[(x - α)^2 + (y - β)^2 + (z - (m1*α - d))^2]), {β, -b/2, b/2}, {α, linfα,l*lsup1}]


The data I want to fit are signals with added white noise:

simulatedData = noise + perfectData


The data was taken from the model:

Table[T145[x, 0, 1, 0.001, 0.001, 0.0001], {x, -0.0015, 0.002, 0.000015}]


I want to make the fit by varying b, l, d and with y=0, using the Levenberg-Marquardt algorithm:

|simulatedData - model|^2


I tried this way:

model = Intens/(2*π*K0)* NIntegrate[Sqrt[1 + m1^2]*Erfc[Sqrt[(x - \
[Alpha])^2 + (y - β)^2 + (z - (m1*α \ -
d))^2]/Sqrt[Dif*4*t]]/(Sqrt[(x - α)^2 + (y - β)^2 + (z - \
(m1*α - d))^2]), {β, -b/2, b/2}, {α, linfα, l*lsup1}];
data = Table[simulatedData, {x, -0.0015, 0.002, 0.000015}];
f = FindFit[data, model, {{y, 0}, t}, {b, l, d}, Method -> "LevenbergMarquardt"]


but the only thing I can see are the white noise points. Where am I wrong?

Edit:

After a few attempts I came to this conclusion:

data=Flatten[Table[simulatedData, {x, -0.0015, 0.002}]]

{0.038851, 0.144917, 0.0520862, 0.0260821, 0.169863, 0.489559, 0.631739, 0.90251, 1.74839, 3.48679, 5.71152, 6.07218, 5.12118, 4.02579, 2.85571, 1.80068, 1.18341, 0.633595, 0.499316, 0.265712, -0.029918, 0.00666698, -0.0514624, 0.00929437}

t=1;

f=FindFit[data,
Intens/(2*π*K0)*NIntegrate[Sqrt[1 + m1^2]*Erfc[
Sqrt[(x - α)^2 + (y - β)^2 + (z - (m1*α \ - d))^2]/
Sqrt[Dif*4*t]]/(Sqrt[(x - α)^2 + (y - β)^2 + (z - \ (m1*α - d))^2]),
{β, -b/2, b/2}, {α, linfα, l*lsup1}],
{y, b, l, d}, x]


I'm getting this error:

FindFit::fmgz: Encountered a gradient that is effectively zero. The result returned may not be a minimum; it may be a maximum or a saddle point.


Furthermore, the values of y, b, l, d are:

{y -> 1., b -> 1., l -> 1., d -> 1.}


which are patently wrong. Did I do something wrong in writing the code?

• Lots of things are undefined in your code. We can't meaningfully help if we can't run the code. Jan 13, 2020 at 17:45

Unfortunately some parameters are not available so I cannot run your code, but here is a toy example:

(* Generate some noisy data *)
noisy = {#, #^2 - 2 # - 15 + RandomReal[{-2, 2}]} & /@ Range[-5, 5];

(* construct the sum of squares to be minimized *)
sumOfSquares = (#2 - (a #1^2 + b #1 + c))^2 & @@@ noisy // Total;

(* Minimize the sum of squares using the Levenberg - Marquardt method*)
min = FindMinimum[sumOfSquares, {a, b, c}, Method -> "LevenbergMarquardt"]

(* Plot the resulting fit (line) together with the raw data (points) *)
Plot[
Evaluate[a x^2 + b x + c /. Last@%], {x, -5, 5},
Epilog -> {PointSize[0.02], Red, Point@noisy},
] • Apologizes. Here the missing parameters: Intens=25000; Dif=0.0000001; K0=0.5 ang1=45*Pi/180 m1=-Tan[ang1] lsup1=Cos[ang1]; linf\[Alpha]=0.0 . Then I added white noise with mean 0 and std 0.1Random[NormalDistribution[0, 0.1]. Jan 14, 2020 at 8:50

Thanking a user of WolframCommunity (but thanks also to those who answered and helped me here), I put the solution to the problem.

NIntegrate only works when the boundaries are numerical. Therefore when you use it as a fit function you have to be sure the function only evaluates if the input parameters are numerical.

fm[x_, y_, t_, b_, l_, d_] /;  NumberQ[x] && NumberQ[b] && NumberQ[l] && NumberQ[d] := Intens/(2*\[Pi]*K0)*NIntegrate[ Sqrt[1 + m1^2]*Erfc[Sqrt[(x - \[Alpha])^2 + (y - \[Beta])^2 + (z - (m1*\[Alpha] - d))^2]/ Sqrt[Dif*4*t]]/(Sqrt[(x - \[Alpha])^2 + (y - \[Beta])^2 + (z - (m1*\\[Alpha] - d))^2]), {\[Beta], -b/2, b/2}, {\[Alpha], linf\[Alpha],l*lsup1}]

Block[{y = 0, t = 1, b = 0.0015, l = 0.0011, d = 0.00013},  data = Table[{x, fm[x, y, t, b, l, d] + Random[NormalDistribution[0, 0.1]]}, {x, -0.0015, 0.002, 0.000015}]];

fit = FindFit[data, fm[x, 0, 1, b, l, d], {{b, 10.^-3}, {l, 10.^-3}, {d, 10.^-4}}, x, Method -> "LevenbergMarquardt"]