22
$\begingroup$

The latest version 11.3.0.0 of Mathematica returns Indeterminate when evaluating Log[Exp[-800.]]. I believe this was not happening with earlier versions (for example with 11.2). Is it possible to change some settings in order to have expressions like this one work as before?

$\endgroup$
11
  • 3
    $\begingroup$ Use arbitrary precision rather than machine precision: Log[Exp[-800.`15]] or Log[Exp[SetPrecision[-800., 15]]]. Or use exact numbers Log[Exp[-800. // Rationalize]] $\endgroup$
    – Bob Hanlon
    Commented Apr 4, 2018 at 15:19
  • 4
    $\begingroup$ That is the correct answer. The result of Exp[-800.] is too small to be represented as a machine number. Unlike previous versions, 11.3 does not perform machine underflow trapping and will not switch to arbitrary precision automatically. $\endgroup$
    – ilian
    Commented Apr 4, 2018 at 16:30
  • 5
    $\begingroup$ Any idea why they did this? Mathematica seems to work fine for the past 30 years.. $\endgroup$
    – Valerio
    Commented Apr 4, 2018 at 17:53
  • 3
    $\begingroup$ @ilian What's the effect of SetSystemOptions["CatchMachineUnderflow" -> True] now? Might that not restore the previous behaviour? $\endgroup$ Commented Apr 4, 2018 at 22:25
  • 6
    $\begingroup$ @Valerio It is part of a larger effort to modernize and improve machine arithmetic for better performance, scalability and consistency. There are a few slides about machine underflow in this talk. $\endgroup$
    – ilian
    Commented Apr 4, 2018 at 23:27

2 Answers 2

8
$\begingroup$

After contacting Wolfram's Technical Support, Kyle Martin suggested the following solution (I asked permission to post his comments):

One might consider overloading the functions that give you trouble to do underflow checking manually. This would mean it is only necessary to update the functions prior to your program, but not each instance of the function within the program. It is possible that at scale this solution may degrade performance of these functions, however. The following code demonstrates how this might be done specifically for our Exp function, and it extends similarly otherwise.

Compiled functions for machine precision evaluation:

(compiledExp[x_Real] := #[x]) & @ Compile[{{x, _Real}}, Exp[x]];
(compiledExp[x_Complex] := #[x]) & @ Compile[{{x, _Complex}}, Exp[x]];

Convert to arbitrary precision from machine precision:

bigExp[x_?MachineNumberQ] := Exp[SetPrecision[x, $MachinePrecision]];

Wrapper function to trap machine underflow and take appropriate action:

munderflowExp[x_] :=
  With[{y = compiledExp[x]},(* Machine evaluation *)
   If[
     y == 0,(* Condition for machine underflow *)
     bigExp[x],(* Action to take on machine underflow converting to a bignum result *)
     y(* Machine precision result when underflow does not occur *)
   ]
  ];

Override the default function for Exp at machine precision with an alternative function:

Unprotect[Exp];
Exp[x_?MachineNumberQ] := munderflowExp[x];
Protect[Exp];

Now:

Log[Exp[-800.]]
(* = -800.0000000000000 *)
$\endgroup$
4
$\begingroup$

Turning a great comment into an answer (as instructed). It is a new feature of v11.3.

Use arbitrary precision rather than machine precision: Log[Exp[-800.``15]] or Log[Exp[SetPrecision[-800., 15]]]. Or use exact numbers Log[Exp[-800. // Rationalize]] – Bob Hanlon Apr 4 at 15:19

The option SetSystemOptions["CheckMachineUnderflow" -> True], only switches on/off the error messages, but does not give back the old behavior.

The change is probably related to improving preformance [1,2].

$\endgroup$

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.