# FindFit only fitting portions of data

I'm currently trying to fit some complicated data sets and I am having some luck. The higher temperature data works just fine with FindFit.

Unfortunately, however, the lower temperature data refuses to fit, regardless of how close the starting parameters are.

axisFlip = # /. {x_Line | x_GraphicsComplex :>
MapAt[#~Reverse~2 &, x, 1],
x : (PlotRange -> _) :> x~Reverse~2} &;
SetDirectory["F:\\IVsandtemplatesdesktop\\IVTD_T793_02_27_2015"];
filename = "T793_Dark_150_2015-02-26 18-17-09.txt";
dataimp = Import[filename, "Table"][[11 ;;]];
jvdata = {Thread[{dataimp[[;; , 1]], 0.001*Abs[dataimp[[;; , 2]]]}]};
jvdata = Select[Table[{jvdata[[1, i, 1]], jvdata[[1, i, 2]]}, {i, 1, Length[jvdata[[1, ;; , 1]]]}],
NumericQ[#[[1]]] && NumericQ[#[[2]]] && #[[2]] != 0 &];
jvdata = Sort[jvdata, #1[[1]] < #2[[1]] &];
vjdata = Transpose[{Sign[jvdata[[;; , 1]]] jvdata[[;; , 2]], jvdata[[;; , 1]]}];
vjdataforward = Select[vjdata, #[[2]] > 0 &];
vjdatareverse = Select[vjdata, #[[2]] < 0 &];

Clear[Jfunction];
Jfunction[V_?NumericQ, J01_?NumericQ, A1_?NumericQ, J02_?NumericQ,
A2_?NumericQ, Rs_?NumericQ, Rsh_?NumericQ, k_?NumericQ,
m_?NumericQ] :=
J /. FindRoot[
J == Abs[J01 (Exp[A1 (V - Sign[V] J Rs)] - 1)] +
Abs[J02 (Exp[A2 (V - Sign[V] J Rs)] - 1)] +
k Abs[(V - Sign[V] J Rs)]^m +
Abs[(V - Sign[V] J Rs)/Rsh], {J, -5, 4}, AccuracyGoal -> 6,
PrecisionGoal -> 6, MaxIterations -> 100000];

Clear[Vfunction];
Vfunction[J_?NumericQ, J01_?NumericQ, A1_?NumericQ, J02_?NumericQ,
A2_?NumericQ, Rs_?NumericQ, Rsh_?NumericQ, k_?NumericQ,
m_?NumericQ] :=
V /. FindRoot[
J == J01 (Exp[A1 (V - J Rs)] - 1) + J02 (Exp[A2 (V - J Rs)] - 1) +
Sign[J] k Abs[(V - J Rs)]^m + (V - J Rs)/
Rsh, {V, -3 HeavisideTheta[-J], 3 HeavisideTheta[J]},
AccuracyGoal -> 6, PrecisionGoal -> 6, MaxIterations -> 100000];

T = 150; (* Temperature in Kelvin *)
q = 1.602176565*10^-19;(*C*)
kb = 1.3806488*10^-23;(*J/K*)
J01init = 1.2*^-33;
A1init = 63;
J02init = 2.601488095513*^-12;
A2init = 13.339343747213;
Rsinit = 4500.0;
Rshinit = 5.9*^9;
kinit = 1.5*^-9;
minit = 2.6;

Show[
ListLogLinearPlot[MapAt[Abs[#] &, #, 1] & /@ vjdata, Joined -> True],
LogLinearPlot[{Vfunction[j, J01init, A1init, J02init, A2init,
Rsinit, Rshinit, kinit, minit],
Vfunction[-j, J01init, A1init, J02init, A2init, Rsinit, Rshinit,
kinit, minit]}, {j, Min[Abs[vjdata[[;; , 1]]]],
1.5*Max[Abs[vjdata[[;; , 1]]]]},
PlotStyle -> Directive[Dashed, Red]]
] // axisFlip

fit = Quiet[
FindFit[vjdata, {Vfunction[j, J01, Abs[A1], J02, Abs[A2], Abs[Rs],
Abs[Rsh], Abs[k], Abs[m]]},
{{J01, J01init}, {A1, A1init}, {J02, J02init}, {A2, A2init}, {Rs,
Rsinit}, {Rsh, Rshinit}, {k, kinit}, {m, minit}}, j,
MaxIterations -> 10000(*,EvaluationMonitor :> Print[
"J01:",J01," A1:",A1," J02:",J02," A2:",A2," Rs:",Rs," Rsh:",Rsh,
" k:",k," m:",m]*)]]

• Your notebook includes pages and pages of code. Very few people will have the time and patience to wade through that much code and results to even try to understand what you are trying to do. You want to generate a minimal working example instead: add the specific data that is giving your trouble and the code that you are using to attempt the fit directly to your question. Mar 20, 2016 at 1:15
• Haha fair enough. I shall edit and include just one temperature Mar 20, 2016 at 1:17
• Okay so finished editing. For some reason it wouldn't let me keep my link in the topic so I'm adding the shortened notebook and data set link here: drive.google.com/… Mar 20, 2016 at 1:39
• What happens if you use Method -> NMinimize? Mar 20, 2016 at 2:08
• @Anthony The definition of Jfunction in your code above seems irrelevant to your current issue, so it should probably be removed for the sake of clarity and readability. Similarly, jvdata seems to be unused. Mar 20, 2016 at 3:17

I'm afraid that this is a comment, rather than a proper answer.

Your problem may actually lie within your Vfunction, rather than with FindFit, but it has been hidden by the fact that you wrapped FindFit in Quiet, thus suppressing all errors and warnings.

If you add Method -> NMinimize to FindFit and remove the Quiet wrapper, you will receive repeated warnings:

fit = FindFit[
vjdata,
Vfunction[j, J01, Abs[A1], J02, Abs[A2], Abs[Rs], Abs[Rsh], Abs[k], Abs[m]],
{{J01, J01init}, {A1, A1init}, {J02, J02init}, {A2, A2init}, {Rs, Rsinit}, {Rsh, Rshinit}, {k, kinit}, {m, minit}},
j,
MaxIterations -> 10, Method -> NMinimize
]


FindRoot::cvmit: Failed to converge to the requested accuracy or precision within 100000 iterations. >>

This must come from within your Vfunction expression, which is repeatedly evaluated by FindFit, since it is the only expression invoked here that has a maximum number of iterations set to 100,000.

This may be due to some "brittleness" in your Vfunction, i.e. very strong sensitivity to the input parameters. Since you have a very good idea of what the values of the parameters should be, you may want to try and restrict the search regions on those parameters e.g. using constraints.