1

I fit the experimental curve with the model using the following equation,

  i[V_,a_,b_, eo_] := Module[{c, T},
  c = 0;  (* in electronvolt *)
  T = 300; (* in Kelvin *) 
Return[N[NIntegrate[
              (4*a*b)/((e - eo)^2 + (a + b)^2)*(f[e - V/2, T, c] - f[e + V/2, T, c]), 
              {e, -∞, ∞}]]] 

where

f[e_, T_, c] := 1/(Exp[(e - c)/(8.617*10^-5*T)] + 1) 

Here the free parameters are a, b, e0.

fit = 
  FindFit[
    data[[1, 2 ;;, {1, 2}]], 
    {i[V, p, k, eo], {-0.5 < p < 0.5, -0.5 < k < 0.5, 0 < eo < 0.9}}, 
    {{p, 0.019}, {k, 0.019}, {eo, 0.65}}, V]

When I use Findfit, it displays the error message:

The integrand has evaluated to non-numerical values for all sampling points in the region with boundaries {{-∞, 0.}}.

At the end, the fit displays the value for a, b, c always nearby the starting value. Could anyone suggest a solution for this?

Karthiga
  • 11
  • 2

1 Answers1

4

As it was said in the comments there are problems with the function definitions. Here is better code:

Clear[i, f]
f[e_, T_, c_] := 1/(Exp[(e - c)/(8.617*10^-5*T)] + 1)
i[V_?NumericQ, a_?NumericQ, b_?NumericQ, eo_?NumericQ] :=
  Module[{c, T}, c = 0;(*in electronvolt*)T = 300;(*in Kelvin*)
   NIntegrate[(4*a*b)/((e - eo)^2 + (a + b)^2)*(f[e - V/2, T, c] - 
       f[e + V/2, T, c]), {e, -\[Infinity], \[Infinity]}, 
    PrecisionGoal -> 3, AccuracyGoal -> 3]
   ];

(Note that I have changed the precision and accuracy goals of NIntegrate to make the computations below easier. )

Since data was not provided let us make some. With this:

Block[{p = 0.019, k = 0.019, eo = 0.65},
 Plot[i[V, p, k, eo], {V, -2, 2}, PerformanceGoal -> "Quality", 
  MaxRecursion -> 8]]

we get:

enter image description here

Similarly to the code for the plot above this computes data with noise:

data = Block[{p = 0.019, k = 0.019, eo = 0.65},
   Table[{V + RandomVariate[NormalDistribution[0, 1/500]], 
     i[V, p, k, eo] + 
      RandomVariate[NormalDistribution[0, 1/500]]}, {V, -2, 2, 0.05}]];
ListPlot[data]

enter image description here

Let us do the fitting with NonliearFindFit:

fn = NonlinearModelFit[data, i[V, p, k, eo], {p, k, eo}, V]

enter image description here

Plot the points with the fit:

Show[ListPlot[data],
 ListLinePlot[{#, fn["Function"][#]} & /@ data[[All, 1]], 
  PlotStyle -> Red]]

enter image description here

and the errors:

ListPlot[{#[[1]], #[[2]] - fn["Function"][#[[1]]]} & /@ data, 
 Filling -> Axis]

enter image description here

Anton Antonov
  • 37,787
  • 3
  • 100
  • 178
  • It displays an error message >NonlinearModelFit::cvmit: Failed to converge to the requested accuracy or precision within 100 iterations. So I gave a starting value for p,k,e0 and it executed without any errors. – Karthiga Oct 09 '15 at 21:27
  • @Karthiga Great -- you used your real data, right? I did not get any messages while experimenting with the fake data... – Anton Antonov Oct 09 '15 at 21:34
  • @Anton-Ya i have tried with the real data. – Karthiga Oct 10 '15 at 10:37