I have a peak profile data like this:

DD = 100; theta2B = 13.742; Lamda = 0.999047433;
ϕ[DD_, theta2_] := 2 Pi DD (Sin[theta2/360*Pi] - Sin[theta2B/360*Pi]) /Lamda;
profile = 1/ϕ[DD, theta2]^2 - Sin[2 ϕ[DD, theta2]]/ϕ[DD, theta2]^3 + (
1 - Cos[2 ϕ[DD, theta2]])/(2 ϕ[DD, theta2]^4);
data = Transpose[{Table[i, {i, 7, 20, 0.01}], 
Table[profile, {theta2, 7, 20, 0.01}]}];
ListPlot[data, PlotRange -> All]

And I have Gaussian, Lorentzian, and Hat functions like this:

GUA[x_] := PDF[NormalDistribution[13.742, fwhm1/Sqrt[8 Log[2]]], x]
LUA[x_] := PDF[CauchyDistribution[13.742, fwhm2/2], x]
HAT[x_] := UnitStep[x + fwhm3/2] - UnitStep[x - fwhm3/2]

Now I want to fit the convolution of GUA[x], LUA[x], and HAT[x] to above peak profile data. The fwhm1 fwhm2 and fwhm3 need be defined from the best fitting.

Does anyone know how to do this?

P.S. I searched the documentation centre and found that the function Convolve cannot generate an analysis formula of GUA[x] * LUA[x] * HAT[x], where * indicates convolution).

  • $\begingroup$ Just need FindFit? $\endgroup$ – Apple Jul 29 '14 at 13:14
  • 1
    $\begingroup$ Yes, you can do it this way. But there is VoigtDistribution already available, which saves you the trouble. $\endgroup$ – Oleksandr R. Jul 29 '14 at 13:52
  • $\begingroup$ @Chenminqi Thanks for your comments, I knew FindFit, my problem is I cannot convolve the three functions together. Once the convolution is done, I can then use FindFIt to refine fwhm1 fwhm2 fwhm3. $\endgroup$ – Xiaodong Wang Jul 31 '14 at 4:47
  • $\begingroup$ @OleksandrR. Thanks for your comments. It looks like just something like below will take MMA forever to finish calculation: Voigt[x_] := PDF[VoigtDistribution[fwhm2/2, fwhm1/Sqrt[8 Log[2]]], x]; HAT[x_] := UnitStep[x + fwhm3/2] - UnitStep[x - fwhm3/2]; Convolve[Voigt[x], HAT[x], x, y] $\endgroup$ – Xiaodong Wang Jul 31 '14 at 4:55

Try the following. These are two models: one is with a single Gaussian and the second is with two ones accounting for the shoulders along with the corresponding fittings.

 model1 = a*Exp[-b*(x - c)^2];
model2 = a*Exp[-b*(x - c)^2] + d*Exp[-e*(x - c)^2];
ff1 = FindFit[data, model1, {a, b, {c, 14}}, x];
ff2 = FindFit[data, model2, {a, b, {c, 14}, d, e}, x];

Here is the fit visualization:

  lstPl = 
   ListPlot[data, PlotRange -> All, 
    PlotStyle -> {Blue, PointSize[0.01]}],
  Plot[{model1 /. ff1, model2 /. ff2}, {x, -8, 18}, 
   PlotStyle -> {Red, Green}, PlotRange -> All]


which should look as follows:

enter image description here

You easily recognize that blue is the data, red is the first and green - the second model. The place where only green is visible is the one where green exactly covers the red one.

Other distributions can be treated analogously.

Finally, the shoulders are evidently fitted not quite well. If it matters, try to play with another second distribution in the model2. That is a Gaussian plus a non-Gaussian. I tried the Lorenz one, but it does not help considerably. It is up to you, however, to think which one should do a better job.

Have fun!

  • $\begingroup$ No -1, but this is not correct; here you are just fitting arbitrary models whereas OP is clear that he has a model that is a convolution of a Voigt function and a top-hat function. I was going to answer this one myself at one point but I forgot, and then the other question came up that solved the same problem using NIntegrate. I think the solution in the other question is perfectly fine, so I VTC. $\endgroup$ – Oleksandr R. Jan 25 '15 at 16:52

Not the answer you're looking for? Browse other questions tagged or ask your own question.