4
$\begingroup$

I'd like to understand why one of these inputs gives me an error and the other doesn't:

s1 = 
 NDSolve[
   {x'[t] == x[t], x[0] == SetPrecision[1., 10]}, 
   {x}, {t, 0, 1}, 
   WorkingPrecision -> $MachinePrecision
 ][[1]]

NDSolve::precw: The precision of the differential equation ({{(x^[Prime])[t]==x[t],x[0]==1.000000000},{},{},{},{}}) is less than WorkingPrecision (15.954589770191003`). >>

(* Out: {x -> InterpolatingFunction[{{0, 1.000000000000000}}, <>]} *)

versus

s2 = 
 NDSolve[
   {x'[t] == x[t], x[0] == SetPrecision[1., 10]}, 
   {x}, {t, 0, 1}, 
   WorkingPrecision -> MachinePrecision
 ][[1]]

(* Out: {x -> InterpolatingFunction[{{0., 1.}}, <>]} *)

Notice that the only difference is the fact that $MachinePrecision got changed to MachinePrecision. Also, oddly enough, the resulting answers are not identical:

x1[t_] = Evaluate[x[t] /. s1];
x2[t_] = Evaluate[x[t] /. s2];

Plot[x1[t] - x2[t], {t, 0, 1}]

plot

$\endgroup$
  • 2
    $\begingroup$ Using $MachinePrecision in the current version of Mathematica forces the (admittedly counterintuitive in this case) use of the arbitrary-precision numerics. MachinePrecision is the right setting to use if you want to stay within machine precision computations, but you do run the risk of hitting instabilities if you are the unlucky sort. $\endgroup$ – J. M. will be back soon Jun 8 '16 at 5:13
  • $\begingroup$ If that's the case, why does changing the precision to 20 eliminate the error? Do you mean to switch those two statements? $\endgroup$ – Max Jun 8 '16 at 5:19
  • 1
    $\begingroup$ This confused me for a bit as well. Here is how I understand it now; perhaps it will help you too. $MachinePrecision is the number of digits of precision that is roughly equivalent to running a native machine-precision calculation on your system. You can evaluate it, and it will return a real number, on my system for instance ca. 15.9. Now think of it this way: WorkingPrecision -> someNumber forces the use of the arbitrary precision engine, with someNumber digits of precision. ... $\endgroup$ – MarcoB Jun 8 '16 at 6:22
  • 1
    $\begingroup$ ... Similarly WorkingPrecision -> $MachinePrecision triggers the use of the arbitrary precision system, with a number of digits of precision that mimics the native machine's precision, but now with error tracking thanks to the arbitrary precision engine. A comparative example can be found in the "Possible Issues" section of the docs on $MachinePrecision. $\endgroup$ – MarcoB Jun 8 '16 at 6:24
  • 3
    $\begingroup$ Additionally arb.-prec. numbers use extra guard bits, so that rounding error is different with MachinePrecision & $MachinePrecision. $\endgroup$ – Michael E2 Jun 8 '16 at 7:02
6
$\begingroup$

I was looking for a previous question of which this might be a duplicate; although many previous discussions hinge on precision issues, and the difference has been mentioned in comments, I could not dredge up an explicit discussion of $MachinePrecision vs MachinePrecision through the SE search engine, so I thought I might sum up the discussion in comments, in hopes that it may be useful as an easier-to-find future reference.


The difference between MachinePrecision and $MachinePrecision took me some time to grasp at first. I also find that the documentation does a poor job of explaining the difference between the two. Here is how I understand it now; perhaps it will help others too.

$MachinePrecision is the number of digits of precision that is equivalent to running a native machine-precision calculation on your system (i.e. using machine numbers). You can evaluate it, and it will return a machine-precision real number:

$MachinePrecision
(* Out: 15.9546 *)

On the one hand, MachinePrecision is a switch to indicate that numerical functions should use machine numbers as implemented in the hardware of your particular computer, and no precision tracking. This is by far the fastest option, and it is chosen by default.

Now consider that setting WorkingPrecision -> someNumber forces the use of the arbitrary precision engine, with someNumber digits of precision and error tracking.

Similarly, then, WorkingPrecision -> $MachinePrecision triggers the use of the arbitrary precision system, with a number of digits of precision that mimics the native machine's precision, but now with error tracking thanks to the arbitrary precision engine.

A comparative example can be found in the "Possible Issues" section of the docs on $MachinePrecision.

Michael also mentioned in his comment that arbitrary-precision numbers use extra guard bits, so that rounding error is different between MachinePrecision and $MachinePrecision.


Here are a few relevant previous discussions from this site:

$\endgroup$
  • 1
    $\begingroup$ A historical note: in versions before 5, N[x, $MachinePrecision] was the way to produce a machine precision evaluation of a number. For some reason, version 5 introduced MachinePrecision as a separate entity which effectively did what $MachinePrecision used to do, and now $MachinePrecision is then left to produce arbitrary-precision results. $\endgroup$ – J. M. will be back soon Jun 8 '16 at 17:26
  • 1
    $\begingroup$ @J.M. As though the situation was not complicated enough already :-) More seriously, if you (or anybody) have any corrections / additions to what I wrote above, please feel free to edit away! I was surprised not to find an authoritative answer on this subject already, so I wonder if I might have simply missed it in my search. $\endgroup$ – MarcoB Jun 8 '16 at 17:30

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.