Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I noticed that Exp have a strange behaviour with big negative numbers

Exp[-Range[1, 700, 0.001]] // Developer`PackedArrayQ // AbsoluteTiming
Exp[-Range[1, 800, 0.001]] // Developer`PackedArrayQ // AbsoluteTiming

{0.014877, True}

{1.551377, False}

I understand than Exp[-800.0] is less than $MinMachineNumber, so I expected that the answer will be 0.0, but it is 3.668*10^-348 wich is not a machine number.

MachineNumberQ@Exp[-800.0]

False

What is the best way to work with these numbers? N@Exp do nothing.

My current solution is

NExp = Exp@Clip[#, {-100.0, 100.0}] &;

NExp[-Range[1, 800, 0.001]] // Developer`PackedArrayQ // AbsoluteTiming

{0.016354, True}

Moreover, I notice that Exp works fine with complex numbers (only in v9)

Exp[0.0 I - Range[1, 700, 0.001]] // Developer`PackedArrayQ // AbsoluteTiming
Exp[0.0 I - Range[1, 800, 0.001]] // Developer`PackedArrayQ // AbsoluteTiming

{0.049367, True}

{0.066757, True}

Edit:

I saw the answer with suggestion of compilation but for some reason it was removed. It is not very fast solution but it works. So I post it here

NExp = Compile[{{x, _Real}}, Exp[x], RuntimeAttributes -> {Listable}];

NExp[-Range[1, 800, 0.001]]) // Developer`PackedArrayQ // AbsoluteTiming

{0.114772, True}

share|improve this question
    
You mean, you want numbers outside the machine number zone to be clipped and kept as machine numbers? –  Rojo Sep 8 '13 at 0:26
    
@Rojo Yes, it is. I want it to be automatically and will not unpack arrays. Values like Exp[-800] appears in the studying something like Fermi-Dirac distribution for small temperatures. But these values is just zero. –  ybeltukov Sep 8 '13 at 1:18
    
In version 7 I get {0.0080005, True} and {0.0160009, True} as the output of the first two lines. Apparently this is version specific; what are you running? –  Mr.Wizard Sep 8 '13 at 8:00
    
@Mr.Wizard I ran it in v9, but in v7 I have the same result. May be it is platform-specific? I have Gentoo Linux. –  ybeltukov Sep 8 '13 at 11:16
add comment

marked as duplicate by Simon Woods, rm -rf Sep 8 '13 at 15:15

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

1 Answer

Will something like this work?

SetPrecision[Chop[N@#], MachinePrecision] & /@ Exp[-Range[1, 800]] //
   Developer`ToPackedArray // Developer`PackedArrayQ // AbsoluteTiming
{0.004003, True}

The number has to first be converted to a numerical form with N or Chop won't do anything to it. Even if the number is large enough it isn't guaranteed to be converted to a machine precision number so we force that by calling SetPrecision. Conversion to a packed array isn't guaranteed either, so we have to call ToPackedArray. But, ToPackedArray won't convert a list if there will be a precision loss.

For a single value the following returns True.

MachineNumberQ@SetPrecision[Chop[N@Exp[-800]], MachinePrecision]
True
share|improve this answer
    
This is interesting solution, but for my Range[1,800,0.001] it tooks about 3 seconds. It is 200 times slower than my solution... –  ybeltukov Sep 8 '13 at 11:10
add comment

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