Context: I isolated the following minimal working example after getting weird warnings while looking at the limiting behavior of the GumbelDistribution
.
Issue: If we try to plot a function that gets doubly exponentially small in the negative direction, we get an underflow warning for sufficient negative values:
Plot[Exp[-Exp[-x]], {x, -6.6, 0}]
General::munfl: Exp[-734.996] is too small to represent as a normalized machine number; precision may be lost.
Unsurprisingly, this warning goes away if we don't try to get too negative:
Plot[Exp[-Exp[-x]], {x, -6.5, 0}] (* No warning generated *)
(I picked the number 6.6 so we would be right on this threshold.)
At first I thought this issue might have been related to the changes in Mathematica 11.3 related to how precision errors are tracked (see here and links therein). However, increasing the working precision of the original example doesn't help:
Plot[Exp[-Exp[-x]], {x, -6.6, 0}, WorkingPrecision -> 500]
General::munfl: Exp[-734.996] is too small to represent as a normalized machine number; precision may be lost.
And the issue persists even if we eliminate all finite-precision numbers from the input:
Plot[Exp[-Exp[-x]], {x, -7, 0}]
General::munfl: Exp[-1096.48] is too small to represent as a normalized machine number; precision may be lost.
Plot[Exp[-Exp[-x]], {x, -7, 0}, WorkingPrecision -> 500]
General::munfl: Exp[-1096.48] is too small to represent as a normalized machine number; precision may be lost.
Therefore, using Rationalize[]
, as suggested in answers to other questions, doesn't help. But what does help is setting the precision of x
to something finite!
Plot[Exp[-Exp[-SetPrecision[x, 500]]], {x, -7, 0}] (* No warning generated *)
Even weirder, the issue also goes away if we just make the substitution x
$\to$-x
in the original example:
Plot[Exp[-Exp[x]], {x, 0, 6.6}] (* No warning generated *)
Indeed, this mere reflection in the x
variable avoids the error even for extremely small numbers (which in this case corresponds to large x
):
Plot[Exp[-Exp[x]], {x, 0, 1000}] (* No warning generated *)
Question: What's going on? If I set the option WorkingPrecision -> 500
, why is SetPrecision[x, 500]
still necessary? And why is all of that that unnecessary under the substitution x
$\to$-x
?