2
$\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$.

| improve this question | | | | |
$\endgroup$
  • 1
    $\begingroup$ In Mathematica v11.0.1 both plots are smooth as expected! $\endgroup$ – Ulrich Neumann Jun 27 '19 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$ – Colin MacLaurin Jun 27 '19 at 13:09
  • $\begingroup$ Might be a version problem! $\endgroup$ – Ulrich Neumann Jun 27 '19 at 14:16
  • 1
    $\begingroup$ @UlrichNeumann The change happened in V11.3. See (170416)/(56728) $\endgroup$ – Michael E2 Jun 28 '19 at 0:55
  • $\begingroup$ The approach here might be useful, too. $\endgroup$ – Michael E2 Jun 28 '19 at 1:01
5
$\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]
| improve this answer | | | | |
$\endgroup$
  • $\begingroup$ These all work on my machine. The last answer also works on my real example, with the hypergeometric function. Thank-you! $\endgroup$ – Colin MacLaurin Jun 27 '19 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

| improve this answer | | | | |
$\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.

| improve this answer | | | | |
$\endgroup$
  • $\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 '19 at 0:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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