3
$\begingroup$

Suppose we plot

Plot[Exp[x] Exp[-x], {x, 0, 1000}]

This equals $1$, as expected, until around $x = 750$ where the curve drops sharply to $0$. Clearly this is due to precision / accuracy issues. How do you fix this plot?

The obvious algebraic simplification here is not the point, as my actual example is closer to:

Plot[Exp[-x^2] Hypergeometric1F1[1/3, 1/2, x^2], {x, 0, 40}]

which fails around $x = 27$, where it drops abruptly to $0$. The Exp and Hypergeometric1F1 terms respectively shrink and grow extremely rapidly, but nearly cancel one another, so their product should remain close to $1$.

$\endgroup$
5
  • 1
    $\begingroup$ In Mathematica v11.0.1 both plots are smooth as expected! $\endgroup$ Jun 27, 2019 at 13:01
  • $\begingroup$ OK, could it be a version and/or platform specific problem then? I am using Mathematica v11.3.0.0 on 64 bit Windows 10 $\endgroup$ Jun 27, 2019 at 13:09
  • $\begingroup$ Might be a version problem! $\endgroup$ Jun 27, 2019 at 14:16
  • 1
    $\begingroup$ @UlrichNeumann The change happened in V11.3. See (170416)/(56728) $\endgroup$
    – Michael E2
    Jun 28, 2019 at 0:55
  • $\begingroup$ The approach here might be useful, too. $\endgroup$
    – Michael E2
    Jun 28, 2019 at 1:01

3 Answers 3

7
$\begingroup$

Use the Plot option Evaluated

Plot[Exp[x] Exp[-x], {x, 0, 1000}, Evaluated -> True]

Or Evaluate the argument

Plot[Evaluate[Exp[x] Exp[-x]], {x, 0, 1000}]

Or use arbitrary-precision rather than machine precision.

Plot[Exp[x] Exp[-x], {x, 0, 1000}, WorkingPrecision -> 20]
$\endgroup$
1
  • $\begingroup$ These all work on my machine. The last answer also works on my real example, with the hypergeometric function. Thank-you! $\endgroup$ Jun 27, 2019 at 13:44
3
$\begingroup$

The Exp and Hypergeometric terms respectively shrink and grow extremely rapidly, but nearly cancel one another, so their product should remain close to 1.

The right way to cure the cancellation problem of the OP is to use the Kummer transformation:

Exp[-x^2] Hypergeometric1F1[1/3, 1/2, x^2] /. 
Hypergeometric1F1[a_, b_, z_] :> Exp[z] Hypergeometric1F1[b - a, b, -z]
   Hypergeometric1F1[1/6, 1/2, -x^2]

which results in a function that is more numerically agreeable:

Plot[Hypergeometric1F1[1/6, 1/2, -x^2], {x, 0, 40}]

plot of Kummer function

$\endgroup$
2
$\begingroup$

I found a solution using a separate function, with an intermediate variable y:

myfunc[x_] := Module[ {y}, y=SetPrecision[x,20]; Exp[-y^2]Hypergeometric1F1[1/3,1/2,y^2] ]

Plot[ myfunc[x], {x,0,40}, PlotRange->{0,1} ]

Now the plot is smooth. Maybe this answer will be helpful to someone. It also seems inelegant, so perhaps there is a better solution.

$\endgroup$
1
  • $\begingroup$ You might want myfunc[x_?MachineNumberQ] := myfunc[SetPrecision[x, 20]; myfunc[x_?NumericQ] := Exp[-x^2] Hypergeometric1F1[1/3,1/2,x^2]; -- not sure about the ?NumericQ. It depends on whether you want myfunc[z] to evaluate to the symbolic expression, at which point you lose control of the precision. $\endgroup$
    – Michael E2
    Jun 28, 2019 at 0:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.