I calculate a scaled error function defined as
f[x_] := Erfc[x]*Exp[x^2]
but it can not calculate f[30000.]
. f[20000.]
is not very small (0.0000282
). I think Mathematica is supposed to switch to high precision instead of machine precision, but it does not. It says:
General::unfl: Underflow occurred in computation. >>
General::ovfl: Overflow occurred in computation. >>
How can I calculate f
for large values of x
? Even with N[f[30000], 50]
, it does not use high precision and fails.
Answer
If you have an analytic formula for f[x_] := Erfc[x]*Exp[x^2]
not using Erfc[x]
you could do what you expect. However it is somewhat problematic to do in this form because Erfc[x] < $MinNumber
for x == 27300.
$MinNumber
1.887662394852454*10^-323228468
N[Erfc[27280.], 20]
5.680044213569341*10^-323201264
Edit
A very good approximation of your function f[x]
for values x > 27280
you can get making use of these bounds ( see e.g. Erfc on Mathworld) :
which hold for x > 0
.
Here we find values of the lower and upper bounds with relative errors for various x
:
T = Table[
N[#, 15]& @ {2 /(Sqrt[Pi] (x + Sqrt[2 + x^2])),
2 /(Sqrt[Pi] ( x + Sqrt[x^2 + 4/Pi])),
1 - ( x + Sqrt[x^2 + 4/Pi])/(x + Sqrt[2 + x^2]),
{x, 30000 Table[10^k, {k, 0, 5}]}];
Grid[ Array[ InputField[ Dynamic[T[[#1, #2]]], FieldSize -> 13] &, {6, 3}]]
Therefore we propose this definition of the function f
(namely the arithetic mean of its bounds for x > 27280
) :
f[x_]/; x >= 0 := Piecewise[ { { Erfc[x]*Exp[x^2], x < 27280 },
{ 1 /( Sqrt[Pi] ( x + Sqrt[2 + x^2]))
+ 1 /( Sqrt[Pi] ( x + Sqrt[x^2 + 4/Pi])), x >= 27280}}
]
f[x_] /; x < 0 := 2 - f[-x]
I.e. we use the original definition of the function f
for 0 < x < 27280
, the approximation for x > 27280
and for x < 0
we use the known symmetry of the Erfc
function, which is relevant when we'd like to calculate f[x]
for x < - 27280
. Now we can safely use this new definition for a much larger domain :
{f[300], f[300.], f[30000.], f[-30000.]}
{E^90000 Erfc[300], 0.0018806214974, 0.0000188063, 1.99998}
and now we can make plots of f
around of the gluing point ( x = 27280.
)
GraphicsRow[{ Plot[ f[x], {x, 2000, 55000},
Epilog -> {PointSize[0.02], Red, Point[{27280., f[27280.]}]},
PlotStyle -> Thick, AxesOrigin -> {0, 0}],
Plot[ f[x], {x, 27270, 27290},
Epilog -> {PointSize[0.02], Red, Point[{27280., f[27280.]}]},
PlotStyle -> Thick]}]
Comments
Post a Comment