22

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?

J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574
Valerio
  • 1,982
  • 13
  • 23
  • 3
    Use arbitrary precision rather than machine precision: Log[Exp[-800.\15]]orLog[Exp[SetPrecision[-800., 15]]]. Or use exact numbersLog[Exp[-800. // Rationalize]]` – Bob Hanlon Apr 04 '18 at 15:19
  • @Bob Hanlon thanks but I would like a solution that would not imply modifying my code. This new "problem" appears in many instances of my code. – Valerio Apr 04 '18 at 16:28
  • 4
    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. – ilian Apr 04 '18 at 16:30
  • @ilian is it possible to set Mathematica up so that this works as in previous versions? – Valerio Apr 04 '18 at 16:32
  • Not in an automatic way, but the modifications required may not be that heavy either. It really depends on the specific code. – ilian Apr 04 '18 at 16:49
  • 5
    Any idea why they did this? Mathematica seems to work fine for the past 30 years.. – Valerio Apr 04 '18 at 17:53
  • 3
    @ilian What's the effect of SetSystemOptions["CatchMachineUnderflow" -> True] now? Might that not restore the previous behaviour? – Patrick Stevens Apr 04 '18 at 22:25
  • 3
    @PatrickStevens That option does not exist anymore. – ilian Apr 04 '18 at 22:44
  • 6
    @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. – ilian Apr 04 '18 at 23:27
  • Related to https://mathematica.stackexchange.com/q/180786/2036 – Johu Aug 29 '18 at 17:24
  • 1
    Unfortunately this change seems to have worsened the performance of NMinimize and similar functions: some extremization scripts of mine that worked fine before 11.3 now give erroneous results. – pglpm Apr 21 '19 at 14:48

2 Answers2

8

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 *)
Valerio
  • 1,982
  • 13
  • 23
4

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].

Johu
  • 4,918
  • 16
  • 43