Skip to main content
added 34 characters in body
Source Link
The Vee
  • 1.8k
  • 12
  • 16

The "something small" is approximately $MaxNumber / 10^$MachinePrecision (not so small, on second thought). Now it holds that

The "something small" is approximately $MaxNumber / 10^$MachinePrecision. Now it holds that

The "something small" is approximately $MaxNumber / 10^$MachinePrecision (not so small, on second thought). Now it holds that

deleted 1 character in body
Source Link
The Vee
  • 1.8k
  • 12
  • 16

so it would make sense to accept Overflow[] for a bound of an interval, at least an open one. As the comments to the original version of this answer show, since there are only unions and intersections in Mathematica's interval arithmetic, even that works in the presence of Overflow[]. Of course, some problems will arise with a symbol whichthat effectively represents an out of bounds error, like comparison with itself, but by any means $MaxNumber should be a member of the above interval.

so it would make sense to accept Overflow[] for a bound of an interval, at least an open one. As the comments to the original version of this answer show, since there are only unions and intersections in Mathematica's interval arithmetic, even that works in the presence of Overflow[]. Of course, some problems will arise with a symbol which effectively represents an out of bounds error, like comparison with itself, but by any means $MaxNumber should be a member of the above interval.

so it would make sense to accept Overflow[] for a bound of an interval, at least an open one. As the comments to the original version of this answer show, since there are only unions and intersections in Mathematica's interval arithmetic, even that works in the presence of Overflow[]. Of course, some problems will arise with a symbol that effectively represents an out of bounds error, like comparison with itself, but by any means $MaxNumber should be a member of the above interval.

Paragraphs reordered
Source Link
The Vee
  • 1.8k
  • 12
  • 16

A new and mostly rewritten version of the original answer which was flawed. See edit history if interested.

As any operation making $MaxNumber higher (more precisely: higher enough for its Precision to notice) results in an overflow, the Interval created here has the form

The "something small" is approximately $MaxNumber / 10^$MachinePrecision. Firstly,Now it holds that

0 < Underflow[] < $MinNumber <= anything positive finite <= $MaxNumber < Overflow[] < ∞,

so it would make sense to accept Overflow[] denotes an error, notfor a bound. If you wanted of an interval, at least an open one. As the comments to the original version of this answer show, since there are only unions and intersections in Mathematica's interval arithmetic, even that stretches fromworks in the presence of Overflow[]. Of course, some problems will arise with a certain number onwardssymbol which effectively represents an out of bounds error, you would uselike comparison with itself, but by any means Infinity$MaxNumber insteadshould be a member of the above interval.

In this sense it is perfectly legitimate thatI have done a bit of hacking on DumpSaves and discovered the operation results infollowing: Mathematica sorts FalseIntervals just likeinto those that have numerical inputs and those that don't. I would call the latter "incomplete" because this category includes not only IntervalMemberQIntervals with undefinedunassigned symbols for example.appearing in the bounds but also those with {a, Overflow[]}Slot does not denote a valid interval so nothing lies within that by definitions and Blanks. You don't needAny incomplete $MaxNumberInterval and the further tricks to confirm thatautomatically returns False on IntervalMemberQ: try

(* This gets only evaluated after substitution *)
f[a_, b_, c_] := IntervalMemberQ[Interval[{a, b}], c];
f[1, 3, 2] (* True *)

(* This is evaluated immediately with the incomplete Interval *)
g[a_, b_, c_] = IntervalMemberQ[Interval[{a, b}], c];
g[1, 3, 2] (* False *)

or even better-behaved inputs like

f = IntervalMemberQ[Interval[{2#1, Overflow[]#2}], 3]#3] &;
f[1, 3, 2] (* True *)

g = Evaluate[IntervalMemberQ[Interval[{#1, #2}], #3]] &;
g[1, 3, 2] (* False *)

result in False (even though 2 < 3 < Overflow[] gives True: this underlinesMy speculation is that this has to do with optimization: with a numeric IntervalMemberQInterval has its own logic that must work well with unions, all the bounds are compared, sorted along the real line and merged as appropriate as shown by the example

Interval[{-1, √2}, {0, π}, {7, 8}, {-5, -4}]

(* Interval[{-5, -4}, {-1, π}, {7, 8}] *)

This can't be done with incomplete intervals. It might be an "expensive" operation so it's not a shorthandgood to do it once the interval becomes complete, and if two of these are intersected, unified, or compared, take this condition for a chained inequality)granted.

SoNow what happens in the real questionoriginal examples is why the uncompressed formula gives True rather than why inthat the other cases you get"incomplete" bit gets set when FalseOverflow[]. I think the answer to this is that Mathematica is giving you a favour by determining the obvious membership ofmanually provided as a number within its own neighbourhood priorbound to evaluating the bounds proper Interval (there may be a quick check for similar basic situations among internaleven though DownValuesOverflow[] ofis even explicitly recognized as numeric by IntervalMemberQNumericQ and compares with other numbers well). Then, if you force it evaluate themSomehow the (which bothInterval produced by Uncompress@*CompressInterval@$MaxNumber is still marked as numerical, though, and this is preserved under interval operations. This explains the situations with Uncompress@Compress@ and Identity/@ doneapplied on the pre-made Interval part alone do)since these force reevaluation of its parts.

In pattern and slot substitutions, a new object is formed so the overflow situation setsincomplete bit is reexamined (and the optimizations done, if complete). But as long as the object stays unchanged there is no reason to touch this metainformation. Importantly, this flag is not a part of the expression tree displayed to the user and is ignored in comparisons. So if two objects only differ in this (due to an incoherent assignment at one or the other's creation) they look identical and resultsare even considered equal in all further membership queries to evaluate=== and similar commands. It is enough difference, however, to prevent FalseShare from merging them.

As a side noteOf course, youthere are usually warned whenmany good points supporting Mathematica's decision not to allow Overflow[] appears. The corresponding warning indeed appears when you try the same withas a bound for $MinNumberInterval:

Interval@$MinNumber

General::unfl: Underflow occurred in computation. >>

I would say – if it iswas a minor glitchdesign choice in the first place, that is. But one way or the other, this occurrence ofbehaviour should be consistent. I agree the inconsistency is a bug, most likely originating in Overflow[]Interval is not reported properly.

As any operation making $MaxNumber higher results in an overflow, the Interval created here has the form

The "something small" is approximately $MaxNumber / 10^$MachinePrecision. Firstly, Overflow[] denotes an error, not a bound. If you wanted an interval that stretches from a certain number onwards, you would use Infinity instead.

In this sense it is perfectly legitimate that the operation results in False just like IntervalMemberQ with undefined symbols for example. {a, Overflow[]} does not denote a valid interval so nothing lies within that by definition. You don't need $MaxNumber and the further tricks to confirm that even better-behaved inputs like

IntervalMemberQ[Interval[{2, Overflow[]}], 3]

result in False (even though 2 < 3 < Overflow[] gives True: this underlines that IntervalMemberQ has its own logic that must work well with unions, it's not a shorthand for a chained inequality).

So the real question is why the uncompressed formula gives True rather than why in the other cases you get False. I think the answer to this is that Mathematica is giving you a favour by determining the obvious membership of a number within its own neighbourhood prior to evaluating the bounds proper (there may be a quick check for similar basic situations among internal DownValues of IntervalMemberQ). Then, if you force it evaluate them (which both Uncompress@*Compress and Identity/@ done on the Interval part alone do), the overflow situation sets in and results in all further membership queries to evaluate to False.

As a side note, you are usually warned when Overflow[] appears. The corresponding warning indeed appears when you try the same with $MinNumber:

Interval@$MinNumber

General::unfl: Underflow occurred in computation. >>

I would say it is a minor glitch that this occurrence of Overflow[] is not reported properly.

A new and mostly rewritten version of the original answer which was flawed. See edit history if interested.

As any operation making $MaxNumber higher (more precisely: higher enough for its Precision to notice) results in an overflow, the Interval created here has the form

The "something small" is approximately $MaxNumber / 10^$MachinePrecision. Now it holds that

0 < Underflow[] < $MinNumber <= anything positive finite <= $MaxNumber < Overflow[] < ∞,

so it would make sense to accept Overflow[] for a bound of an interval, at least an open one. As the comments to the original version of this answer show, since there are only unions and intersections in Mathematica's interval arithmetic, even that works in the presence of Overflow[]. Of course, some problems will arise with a symbol which effectively represents an out of bounds error, like comparison with itself, but by any means $MaxNumber should be a member of the above interval.

I have done a bit of hacking on DumpSaves and discovered the following: Mathematica sorts Intervals into those that have numerical inputs and those that don't. I would call the latter "incomplete" because this category includes not only Intervals with unassigned symbols appearing in the bounds but also those with Slots and Blanks. Any incomplete Interval automatically returns False on IntervalMemberQ: try

(* This gets only evaluated after substitution *)
f[a_, b_, c_] := IntervalMemberQ[Interval[{a, b}], c];
f[1, 3, 2] (* True *)

(* This is evaluated immediately with the incomplete Interval *)
g[a_, b_, c_] = IntervalMemberQ[Interval[{a, b}], c];
g[1, 3, 2] (* False *)

or even

f = IntervalMemberQ[Interval[{#1, #2}], #3] &;
f[1, 3, 2] (* True *)

g = Evaluate[IntervalMemberQ[Interval[{#1, #2}], #3]] &;
g[1, 3, 2] (* False *)

My speculation is that this has to do with optimization: with a numeric Interval, all the bounds are compared, sorted along the real line and merged as appropriate as shown by the example

Interval[{-1, √2}, {0, π}, {7, 8}, {-5, -4}]

(* Interval[{-5, -4}, {-1, π}, {7, 8}] *)

This can't be done with incomplete intervals. It might be an "expensive" operation so it's good to do it once the interval becomes complete, and if two of these are intersected, unified, or compared, take this condition for granted.

Now what happens in the original examples is that the "incomplete" bit gets set when Overflow[] is manually provided as a bound to the Interval (even though Overflow[] is even explicitly recognized as numeric by NumericQ and compares with other numbers well). Somehow the Interval produced by Interval@$MaxNumber is still marked as numerical, though, and this is preserved under interval operations. This explains the situations with Uncompress@Compress@ and Identity/@ applied on the pre-made Interval since these force reevaluation of its parts.

In pattern and slot substitutions, a new object is formed so the incomplete bit is reexamined (and the optimizations done, if complete). But as long as the object stays unchanged there is no reason to touch this metainformation. Importantly, this flag is not a part of the expression tree displayed to the user and is ignored in comparisons. So if two objects only differ in this (due to an incoherent assignment at one or the other's creation) they look identical and are even considered equal in === and similar commands. It is enough difference, however, to prevent Share from merging them.

Of course, there are many good points supporting Mathematica's decision not to allow Overflow[] as a bound for Interval – if it was a design choice in the first place, that is. But one way or the other, this behaviour should be consistent. I agree the inconsistency is a bug, most likely originating in Interval.

Source Link
The Vee
  • 1.8k
  • 12
  • 16
Loading