Turn off ZeroDivisionError?

J

John Nagle

Mark said:
Seriously, in some of my crazier moments I've considered trying to
write a PEP on this, so I'm very interested in figuring out exactly
what it is that people want. The devil's in the details, but the
basic ideas would be:

(1) aim for consistent behaviour across platforms in preference to
exposing differences between platforms
(2) make default arithmetic raise Python exceptions in preference to
returning infs and nans. Essentially, ValueError would be raised
anywhere that IEEE 754(r) specifies raising the divide-by-zero or
invalid signals, and OverflowError would be raised anywhere that IEEE
754(r) specifies raising the overflow signal. The underflow and
inexact signals would be ignored.
(3) have a thread-local floating-point environment available from
Python to make it possible to turn nonstop mode on or off, with the
default being off. Possibly make it possible to trap individual
flags.

Any thoughts on the general directions here? It's far too late to
think about this for Python 2.6 or 3.0, but 3.1 might be a possibility.

You also need to think about how conditionals interact with
quiet NANs. Properly, comparisons like ">" have three possibilities:
True, False, and "raise". Many implementations don't do that well,
which means that you lose trichotomy. "==" has issues; properly,
"+INF" is not equal to itself.

If you support quiet NANs, you need the predicates like "isnan".

I've done considerable work with code that handled floating
point exceptions in complex ways. I've done animation simulations
(see "www.animats.com") where floating point overflow could occur,
but just meant that part of the computation had to be rerun with a
smaller time step. So I'm painfully familiar with the interaction
of IEEE floating point, Windows FPU exception modes, and C++ exceptions.
On x86, with some difficulty, you can turn an FPU exception into a
C++ exception using Microsoft's compilers. But that's not portable.
x86 has exact exceptions, but most other superscalar machines
(PowerPC, Alpha, if anybody cares) do not.

For Python, I'd suggest throwing a Python exception on all errors
recognized by the FPU, except maybe underflow. If you're doing
such serious number-crunching that you really want to handle NANs,
you're probably not writing in Python anyway.

John Nagle
 
M

Mark Dickinson

You also need to think about how conditionals interact with
quiet NANs. Properly, comparisons like ">" have three possibilities:

True. There was a recent change to Decimal to make comparisons (other
than !=, ==) with NaNs do the "right thing": that is, raise a Python
exception, unless the Invalid flag is not trapped, in which case they
return False (and also raise the Invalid flag). I imagine something
similar would make sense for floats.
True, False, and "raise". Many implementations don't do that well,
which means that you lose trichotomy. "==" has issues; properly,
"+INF" is not equal to itself.

I don't understand: why would +INF not be equal to itself? Having
INF == INF be True seems like something that makes sense both
mathematically and computationally.
If you support quiet NANs, you need the predicates like "isnan".

They're on their way! math.isnan and math.isinf will be in Python
2.6.
C++ exception using Microsoft's compilers. But that's not portable.
x86 has exact exceptions, but most other superscalar machines
(PowerPC, Alpha, if anybody cares) do not.

Interesting. What do you mean by 'exact exception'?
For Python, I'd suggest throwing a Python exception on all errors
recognized by the FPU, except maybe underflow.

Yes: I think this should be the default behaviour, at least. It was
agreed quite a while ago amongst the Python demigods that the IEEE
overflow, invalid and divide-by-zero signals should ideally raise
Python exceptions, while underflow and inexact should be ignored. The
problem is that that's not what Python does at the moment, and some
people rely on being able to get NaNs and infinities the old ways.
If you're doing
such serious number-crunching that you really want to handle NANs,
you're probably not writing in Python anyway.

If you're worried about speed, then I agree you probably shouldn't be
writing in Python. But I can imagine there are use-cases for nonstop
arithmetic with nans and infs where speed isn't the topmost concern.

Mark
 
G

Grant Edwards

I disagree completely. I do a lot of number crunching in
Python where I want IEEE NaN and Inf behavior. Speed is a
completely orthogonal issue.
If you're worried about speed, then I agree you probably
shouldn't be writing in Python.

Even if you are worried about speed, using tools like like
numpy can do some pretty cool stuff.
But I can imagine there are use-cases for nonstop arithmetic
with nans and infs where speed isn't the topmost concern.

Frankly, I don't see that speed has anything to do with it at
all. I use Python for number-crunching because it's easy to
program in. When people complain about not getting the right
results, replying with "if you want something fast, don't use
Python" makes no sense.
 
M

Mark Dickinson

Some dodgy quoting here: that wasn't me!
I disagree completely. I do a lot of number crunching in
Python where I want IEEE NaN and Inf behavior. Speed is a
completely orthogonal issue.

Exactly.

Mark
 
G

Grant Edwards

Some dodgy quoting here: that wasn't me!

Yup. That's indicated by the xtra level of ">". Sorry if that
mislead anybody -- I accidentally deleted the nested attribute
line when I was trimming things.
 
S

Steve Holden

Mark said:
You also need to think about how conditionals interact with
quiet NANs. Properly, comparisons like ">" have three possibilities:

True. There was a recent change to Decimal to make comparisons (other
than !=, ==) with NaNs do the "right thing": that is, raise a Python
exception, unless the Invalid flag is not trapped, in which case they
return False (and also raise the Invalid flag). I imagine something
similar would make sense for floats.
True, False, and "raise". Many implementations don't do that well,
which means that you lose trichotomy. "==" has issues; properly,
"+INF" is not equal to itself.

I don't understand: why would +INF not be equal to itself? Having
INF == INF be True seems like something that makes sense both
mathematically and computationally.
[...]

There are an uncountable number of infinities, all different.

regards
Steve
 
J

Jeff Schwab

Steve said:
Mark said:
You also need to think about how conditionals interact with
quiet NANs. Properly, comparisons like ">" have three possibilities:

True. There was a recent change to Decimal to make comparisons (other
than !=, ==) with NaNs do the "right thing": that is, raise a Python
exception, unless the Invalid flag is not trapped, in which case they
return False (and also raise the Invalid flag). I imagine something
similar would make sense for floats.
True, False, and "raise". Many implementations don't do that well,
which means that you lose trichotomy. "==" has issues; properly,
"+INF" is not equal to itself.

I don't understand: why would +INF not be equal to itself? Having
INF == INF be True seems like something that makes sense both
mathematically and computationally.
[...]

There are an uncountable number of infinities, all different.

+ALEPH0?
 
C

Carl Banks

You also need to think about how conditionals interact with
quiet NANs. Properly, comparisons like ">" have three possibilities:
True, False, and "raise". Many implementations don't do that well,
which means that you lose trichotomy. "==" has issues; properly,
"+INF" is not equal to itself.

I'm pretty sure it is. It certainly is on my machine at the moment:
True

Are you confusing INF with NAN, which is specified to be not equal to
itself (and, IIRC, is the only thing specified to be not equal to
itself, such that one way to test for NAN is x!=x).

For Python, I'd suggest throwing a Python exception on all errors
recognized by the FPU, except maybe underflow. If you're doing
such serious number-crunching that you really want to handle NANs,
you're probably not writing in Python anyway.

Even if that were entirely true, there are cases where (for example)
you're using Python to glue together numerical routines in C, but you
need to do some preliminary calculations in Python (where there's no
edit/compile/run cycle but there is slicing and array ops), but want
the same floating point behavior.

IEEE conformance is not an unreasonable thing to ask for, and "you
should be using something else" isn't a good answer to "why not?".


Carl Banks
 
G

Grant Edwards

Even if that were entirely true, there are cases where (for
example) you're using Python to glue together numerical
routines in C, but you need to do some preliminary
calculations in Python (where there's no edit/compile/run
cycle but there is slicing and array ops), but want the same
floating point behavior.

Or when you're verifying/testing algorithms implemented on
another platform that follows the IEEE standard.

Or when propagating quiet NaNs and Infinities is by far the
simplest way to do what needs to be done. Being able to feed
NaN values into a set of calculations and have outputs
dependant on invalid inputs turn out to be NaNs is just _so_
much simpler than either

1) Having a complete set of boolean logic code in parallel to
the calculations that keeps track of what's valid and
what's not.

2) Writing a floating point class with some sort of "valid
flag" that travels along with the values.
IEEE conformance is not an unreasonable thing to ask for,

Especially when the hardware already provides it (or at least
provides something close enough to satisfy most of us who
whinge about such things).
and "you should be using something else" isn't a good answer
to "why not?".

even for Usenet. ;)
 
M

Mark Dickinson

There are an uncountable number of infinities, all different.

If you're talking about infinite cardinals or ordinals in set theory,
then yes. But that hardly seems relevant to using floating-point as a
model for the doubly extended real line, which has exactly two
infinities.

Mark
 
S

Steve Holden

Mark said:
If you're talking about infinite cardinals or ordinals in set theory,
then yes. But that hardly seems relevant to using floating-point as a
model for the doubly extended real line, which has exactly two
infinities.
True enough, but aren't they of indeterminate magnitude? Since infinity
== infinity + delta for any delta, comparison for equality seems a
little specious.

regards
Steve
 
M

Mark Dickinson

True enough, but aren't they of indeterminate magnitude? Since infinity
== infinity + delta for any delta, comparison for equality seems a
little specious.

The equality is okay; it's when you start trying to apply arithmetic
laws like

a+c == b+c implies a == b

that you get into trouble. In other words, the doubly-extended real
line is a perfectly well-defined and well-behaved *set*, and even a
nice (compact) topological space with the usual topology. It's just
not a field, or a group under addition, or ...

Mark
 
S

Steven D'Aprano

For Python, I'd suggest throwing a Python exception on all errors
recognized by the FPU, except maybe underflow. If you're doing such
serious number-crunching that you really want to handle NANs, you're
probably not writing in Python anyway.

Chicken, egg.

The reason people aren't writing in Python is because Python doesn't
support NANs, and the reason Python doesn't support NANs is because the
people who want support for NANs aren't using Python.

Oh, also because it's hard to do it in a portable fashion. But maybe
Python doesn't need to get full platform independence all in one go?

# pseudo-code
if sys.platform == "whatever"
float = IEEE_float
else:
warnings.warn("no support for NANs, beware of exceptions")


There are use-cases for NANs that don't imply the need for full C speed.
Number-crunching doesn't necessarily imply that you need to crunch
billions of numbers in the minimum time possible. Being able to do that
sort of "crunch-lite" in Python would be great.
 
S

Steven D'Aprano

I don't understand: why would +INF not be equal to itself? Having INF
== INF be True seems like something that makes sense both
mathematically and computationally.
[...]

There are an uncountable number of infinities, all different.


But the IEEE standard only supports one of them, aleph(0).

Technically two: plus and minus aleph(0).
 
M

Mark Dickinson

I don't understand: why would +INF not be equal to itself? Having INF
== INF be True seems like something that makes sense both
mathematically and computationally.
[...]
There are an uncountable number of infinities, all different.

But the IEEE standard only supports one of them, aleph(0).

Technically two: plus and minus aleph(0).

Not sure that alephs have anything to do with it. And unless I'm
missing something, minus aleph(0) is nonsense. (How do you define the
negation of a cardinal?)

From the fount of all wisdom: (http://en.wikipedia.org/wiki/
Aleph_number)

"""The aleph numbers differ from the infinity ($B!g(B) commonly found in
algebra and calculus. Alephs measure the sizes of sets; infinity, on
the other hand, is commonly defined as an extreme limit of the real
number line (applied to a function or sequence that "diverges to
infinity" or "increases without bound"), or an extreme point of the
extended real number line. While some alephs are larger than others, $B!g(B
is just $B!g(B."""

Mark
 
P

Paul Rubin

Mark Dickinson said:
Not sure that alephs have anything to do with it.

They really do not. The extended real line can be modelled in set
theory, but the "infinity" in it is not a cardinal as we would
normally treat them in set theory. Almost all of what we usually call
real analysis can be done in fairly weak subsystems of second order
arithmetic, which is a countable theory. There is a fairly interesting
rant arguing basically that set theory itself is bogus (not in the
sense of being wrong, but in the sense of being unnecessary for
most mathematics):

http://math.stanford.edu/~feferman/papers/psa1992.pdf
 
P

Paul Rubin

Jeff Schwab said:
Georg Cantor disagrees. Whether Aleph 1 is the cardinality of the set
of real numbers is provably undecidable.

You misunderstand, the element called "infinity" in the extended real
line has nothing to do with the cardinality of the reals, or of
infinite cardinals as treated in set theory. It's just an element of
a structure that can be described in elementary terms or can be viewed
as sitting inside of the universe of sets described by set theory.
See:

http://en.wikipedia.org/wiki/Point_at_infinity

Aleph 1 didn't come up in the discussion earlier either. FWIW, it's
known (provable from the ZFC axioms) that the cardinality of the reals
is an aleph; ZFC just doesn't determine which particular aleph it is.
The Wikipedia article about CH is also pretty good:

http://en.wikipedia.org/wiki/Continuum_hypothesis

the guy who proved CH is independent also expressed a belief that it
is actually false.
 
S

Steven D'Aprano

I don't understand: why would +INF not be equal to itself? Having
INF == INF be True seems like something that makes sense both
mathematically and computationally.
[...]
There are an uncountable number of infinities, all different.

But the IEEE standard only supports one of them, aleph(0).

Technically two: plus and minus aleph(0).

Not sure that alephs have anything to do with it. And unless I'm
missing something, minus aleph(0) is nonsense. (How do you define the
negation of a cardinal?)

*shrug* How would you like to?

The natural numbers (0, 1, 2, 3, ...) are cardinal numbers too. 0 is the
cardinality of the empty set {}; 1 is the cardinality of the set
containing only the empty set {{}}; 2 is the cardinality of the set
containing a set of cardinality 0 and a set of cardinality 1 {{}, {{}}}
.... and so on.

Since we have generalized the natural numbers to the integers

.... -3 -2 -1 0 1 2 3 ...

without worrying about what set has cardinality -1, I see no reason why
we shouldn't generalize negation to the alephs. The question of what set,
if any, has cardinality -aleph(0) is irrelevant. Since the traditional
infinity of the real number line comes in a positive and negative
version, and we identify positive ∞ as aleph(0) [see below for why], I
don't believe there's any thing wrong with identifying -aleph(0) as -∞.

Another approach might be to treat the cardinals as ordinals. Subtraction
isn't directly defined for ordinals, ordinals explicitly start counting
at zero and only increase, never decrease. But one might argue that since
all ordinals are surreal numbers, and subtraction *is* defined for
surreals, we might identify aleph(0) as the ordinal omega ω then the
negative of aleph(0) is just -ω, or {|{ ... -4, -3, -2, -1 }}. Or in
English... -aleph(0) is the number more negative than every negative
integer, which gratifyingly matches our intuition about negative infinity.

There's lots of hand-waving there. I expect a real mathematician could
make it all vigorous. But a lot of it is really missing the point, which
is that the IEEE standard isn't about ordinals, or cardinals, or surreal
numbers, but about floating point numbers as a discrete approximation to
the reals. In the reals, there are only two infinities that we care
about, a positive and negative, and apart from the sign they are
equivalent to aleph(0).

From the fount of all wisdom: (http://en.wikipedia.org/wiki/
Aleph_number)

"""The aleph numbers differ from the infinity (∞) commonly found in
algebra and calculus. Alephs measure the sizes of sets; infinity, on the
other hand, is commonly defined as an extreme limit of the real number
line (applied to a function or sequence that "diverges to infinity" or
"increases without bound"), or an extreme point of the extended real
number line. While some alephs are larger than others, ∞ is just ∞."""

That's a very informal definition of infinity. Taken literally, it's also
nonsense, since the real number line has no limit, so talking about the
limit of something with no limit is meaningless. So we have to take it
loosely.

In fact, it isn't true that "∞ is just ∞" even in the two examples they
discuss. There are TWO extended real number lines: the projectively
extended real numbers, and the affinely extended real numbers. In the
projective extension to the reals, there is only one ∞ and it is
unsigned. In the affine extension, there are +∞ and -∞.

If you identify ∞ as "the number of natural numbers", that is, the number
of numbers in the sequence 0, 1, 2, 3, 4, ... then that's precisely what
aleph(0) is. If there's a limit to the real number line in any sense at
all, it is the same limit as for the integers (since the integers go all
the way to the end of the real number line).

(But note that there are more reals between 0 and ∞ than there are
integers, even though both go to the same limit: the reals are more
densely packed.)
 
M

Mark Dickinson

*shrug* How would you like to?
Since we have generalized the natural numbers to the integers

... -3 -2 -1 0 1 2 3 ...

without worrying about what set has cardinality -1, I see no reason why
we shouldn't generalize negation to the alephs.

The reason is that it doesn't give a useful result. There's a natural
process for turning a commutative monoid into a group (it's the
adjoint to the forgetful functor from groups to commutative monoids).
Apply it to the "set of cardinals", leaving aside the set-theoretic
difficulties with the idea of the "set of cardinals" in the first
place, and you get the trivial group.
There's lots of hand-waving there. I expect a real mathematician could
make it all vigorous.

Rigorous? Yes, I expect I could.

And surreal numbers are something entirely different again.
That's a very informal definition of infinity. Taken literally, it's also
nonsense, since the real number line has no limit, so talking about the
limit of something with no limit is meaningless. So we have to take it
loosely.

The real line, considered as a topological space, has limit points.
Two of them.

Mark
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top