# FindRoot - Convergence Failure

In my problem which I try to solve with FindRoot in Mathematica version 12 I usually get the following errors

FindRoot::lstol: The line search decreased the step size to within tolerance specified by AccuracyGoal and PrecisionGoal but was unable to find a sufficient decrease in the merit function. You may need more than MachinePrecision digits of working precision to meet these tolerances.

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

The functions are:

Ft[m_] :=
1/(2 \[Pi]) (Sqrt[Abs[m]]/2 +
Log[Exp[\[Beta] Sqrt[Abs[m]]] - 1]/\[Beta]);

F1[m1_, m2_] :=
Ft[m1] ((gc[[1]])/6 Ft[m1] + (gc[[2]])/6 Ft[m2]) + (gc[[1]])/
12 (Ft[m1])^2 + (gc[[2]])/12 (Ft[m2])^2 - m1 + \[Mu];

F2[m1_, m2_] :=
Ft[m2] ((gc[[3]])/6 Ft[m2] + (gc[[2]])/6 Ft[m1]) + (gc[[3]])/
12 (Ft[m2])^2 + (gc[[2]])/12 (Ft[m1])^2 - m2 + \[Mu];


Where I identified:

g = {1, -10, 1000};
G = 16 \[Pi]^2 (2 10^-6);
gc = G g;
\[Mu] = 10;


For each $$\beta$$ I use FindRoot to solve $$m_1$$ and $$m_2$$ for both F1 and F2. Sadly as you can see below I get a jump which I can't get rid of by increasing the number of iterations or precision... the FindRoot code is as follows:

roots = FindRoot[{F1[a, b], F2[a, b]}, {{a, m1guess}, {b, m2guess}},
AccuracyGoal -> Infinity];


The plot of the following function

Where $$T=1/\beta$$ I guess it comes from the fact that the slope grows to infinity and some of the equations contains Log terms. Is there anything I can use to solve it? I should also mention that for each $$\beta$$ I use the previous solution as an initial guess.

The full code:

g = {1, -10, 1000};
G = 16 \[Pi]^2 (2 10^-6);
gc = G g;
\[Mu] = 10;
\[Beta] = 10^(10);(*beta definition, arbitrary one*)

Ft[m_] :=
1/(2 \[Pi]) (Sqrt[Abs[m]]/2 +
Log[Exp[\[Beta] Sqrt[Abs[m]]] - 1]/\[Beta]);
F1[m1_, m2_] :=
Ft[m1] ((gc[[1]])/6 Ft[m1] + (gc[[2]])/6 Ft[m2]) + (gc[[1]])/
12 (Ft[m1])^2 + (gc[[2]])/12 (Ft[m2])^2 - m1 + \[Mu];
F2[m1_, m2_] :=
Ft[m2] ((gc[[3]])/6 Ft[m2] + (gc[[2]])/6 Ft[m1]) + (gc[[3]])/
12 (Ft[m2])^2 + (gc[[2]])/12 (Ft[m1])^2 - m2 + \[Mu];

(*Arbitraty initial guess*)
m1guess = 1000;
m2guess = 10000;
Iter = 5000; (*Number of iterations to calculate*)
(*Initializing Lists*)
shiftb = N@
Subdivide[260, 270, Iter];
m1val = List[]; (*numerical m1*)
m2val = List[]; (*numerical m2*)
For[t = 1, t < Iter, t++,
\[Beta] =
1/shiftb[[
t]];
roots = FindRoot[{F1[a, b],
F2[a, b]}, {{a, m1guess}, {b,
m2guess}}];
m1temp = a /. roots[[1]];
m2temp = b /. roots[[2]];
m1val = Insert[m1val, {1/\[Beta], m1temp},
t];
m2val = Insert[m2val, {1/\[Beta], m2temp}, t];
m1guess = m1temp ;
m2guess = m2temp ;

]

(*Graphs*)
(*Mass 1 2 as function of temperature*)

ListLinePlot[m1val,
PlotLabel ->
"\!$$\*SuperscriptBox[SubscriptBox[\(M$$, $$1$$], $$2$$]\) vs. \
Temperature" ,
AxesLabel -> {Style["T", FontSize -> 20],
Style["M1", FontSize -> 20]},
PlotStyle -> {Thick, Thickness[0.001]},
BaseStyle -> {FontFamily -> "lmromandemi10-regular",
FontSize -> 20}, LabelStyle -> Black, ImageSize -> 1000]

ListLinePlot[m2val,
PlotLabel ->
"\!$$\*SuperscriptBox[SubscriptBox[\(M$$, $$2$$], $$2$$]\) vs. \
Temperature" ,
AxesLabel -> {Style["T", FontSize -> 20],
Style["M2", FontSize -> 20]},
PlotStyle -> {Thick, Thickness[0.001]},
BaseStyle -> {FontFamily -> "lmromandemi10-regular",
FontSize -> 20}, LabelStyle -> Black, ImageSize -> 1000]

• I get the FindRoot::lstol error with the simpler, unproblematic function, FindRoot[x^2 - 2, {x, 1}, AccuracyGoal -> Infinity]. I think roots = FindRoot[obj, {x, 1}, AccuracyGoal -> Infinity]; obj /. roots should result in 0. to satisfy the goal AccuracyGoal -> Infinity. – Michael E2 Sep 21 at 12:58
• BTW, you're missing the definitions of some variables, and so your problem cannot be reproduced. – Michael E2 Sep 21 at 13:02
• Basically this problem happens even when AccuracyGoal -> Infinity does not appear. I added the missing parameter $\beta$ to the question – Noam Chai Sep 21 at 14:23
• And the full code to reproduce the problem, Thanks! – Noam Chai Sep 21 at 14:34

The short answer is that nothing is wrong. FindRoot compares the function value to the AccuracyGoal to determine whether an approximate root satisfies the user's convergence criteria. A function value of 0. is needed for AccuracyGoal -> Infinity and WorkingPrecision -> MachinePrecision.

Rounding error in the objective function limits the AccuracyGoal that can be achieved. Further, the discrete nature of floating-point numbers means than in a bounded neighborhood of the true root, there are only finitely many possible inputs. There will be among the corresponding finitely many values of the function one that is closest to zero. The closest value also limits the AccuracyGoal that can be achieved. For β = 10^(10), the smallest values for F1 and F2 near the root are both around $$5\times10^{-13}$$. So an AccuracyGoal of around 12 or lower is achievable at MachinePrecision, and it is in fact achieved by FindRoot.

[Further technical analysis: The Jacobian near the root for β = 10^(10) given by D[{F1[a, b], F2[a, b]} // ComplexExpand, {{a, b}}] /. roots is approximately the identity matrix and therefore the error in the function $$(F_1,F_2)$$ is about identical to the error $$(\Delta a, \Delta b)$$ in $$(a,b)$$. Specifically, for small changes, we have $$\Delta F_1 \approx \Delta a$$, $$\Delta F_2 \approx \Delta b$$. The error $$(\Delta a, \Delta b)$$ in the best available approximation to the root $$(a^*,b^*)$$ is roughly bounded by $$10^{-16}(a^*,b^*) \approx (10^{-12},10^{-12})$$, which again suggests AccuracyGoal -> 12. ]

If that is not good enough, then the advice of the error message should be followed:

FindRoot::lstol:...You may need more than MachinePrecision digits of working precision....


Using WorkingPrecision -> 16 or higher gives a result that agrees with the MachinePrecision result to machine precision. If you ultimately need to convert the results to machine precision (for use, say, in another computational environment), then you gain nothing by using a higher working precision.

Test runs:

β = 10^(10);
roots = FindRoot[{F1[a, b], F2[a, b]}, {{a, 10000}, {b, 10000}},
AccuracyGoal -> Infinity]
{F1[a, b], F2[a, b]} /. roots
(*
FindRoot::lstol:....
{a -> 9999.59, b -> 10044.8}
{5.18807*10^-13, 5.54223*10^-13}  <-- accuracy measure
*)

(* No FindRoot::lstol message with WorkingPrecision -> 32
* The error with high precision roots reverts to the MachinePrecision
*   error, when the roots are converted to machine precision *)
roots = FindRoot[{F1[a, b], F2[a, b]}, {{a, 10000}, {b, 10000}},
AccuracyGoal -> Infinity, WorkingPrecision -> 32]
{F1[a, b], F2[a, b]} /. N@roots
(*
{a -> 9999.5936625079398893847134814908,
b -> 10044.750719932014027892806500930}

{5.18807*10^-13, 5.54223*10^-13}  <-- accuracy measure
*)

(* No FindRoot::lstol message with AccuracyGoal -> 12 *)
roots = FindRoot[{F1[a, b], F2[a, b]}, {{a, 10000}, {b, 10000}},
AccuracyGoal -> 12]
(*  {a -> 9999.59, b -> 10044.8}  *)

• Thank you for your comment. – Noam Chai Sep 21 at 16:49
• Thank you for your comment. I guess you chose my arbitrary value $\beta=10^{10}$ to explain your claims. Basically I don't have any problem around this value. Yes, the code works fine to the accuracy that it meant to work, but the problem that I have is around $\beta=1/264$ or around $T=264$. – Noam Chai Sep 21 at 17:07
• In that range I get an horizontal line that I think comes from the method that I use (Newton) since (I guess) in order to converge to the right accuracy and in this range the code have to take infinite amount of steps... at that range I get the error : Failed to converge to the requested accuracy or precision within 100 \ iterations.. I don't think it's the right value, how can I validate it or correct it? – Noam Chai Sep 21 at 17:08