Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0**0 = 1 for number fields, matrices, and more #10772

Closed
mstreng opened this issue Feb 11, 2011 · 3 comments
Closed

0**0 = 1 for number fields, matrices, and more #10772

mstreng opened this issue Feb 11, 2011 · 3 comments

Comments

@mstreng
Copy link

mstreng commented Feb 11, 2011

Python has the convention x**0 = 1 even for x=0. Sage follows this convention in some cases, but raises an error in others. This patch generalizes Python's convention to sage.structure.element.generic_power_c, which includes number field elements and matrices. This fixes inconsistent behaviour for matrices and a bug for number fields (see examples below). See also this discussion.

Example 1:

sage: K.<a> = NumberField(x^4+x+1)
sage: r = [ZZ,QQ,RR,CC,int,float,K]
sage: N = len(r)^2; N
49
sage: for a in r:
....:     for b in r:
....:         try:
....:             if a(0)^b(0) != 1:
....:                 (a,b,a(0)^b(0))
....:                 N = N - 1
....:         except (ArithmeticError, TypeError, AttributeError, RuntimeError) as e:
....:             (a,b,e)
....:             N = N - 1
....: 
(Integer Ring, Complex Field with 53 bits of precision, NaN - NaN*I)
(Integer Ring, Number Field in a with defining polynomial x^4 + x + 1, ArithmeticError('0^0 is undefined.',))
(Rational Field, Complex Field with 53 bits of precision, NaN - NaN*I)
(Rational Field, Number Field in a with defining polynomial x^4 + x + 1, ArithmeticError('0^0 is undefined.',))
Exception RuntimeError: 'maximum recursion depth exceeded in __subclasscheck__' in <type 'exceptions.TypeError'> ignored
Exception RuntimeError: 'maximum recursion depth exceeded in __subclasscheck__' in <type 'exceptions.TypeError'> ignored
Exception RuntimeError: 'maximum recursion depth exceeded while calling a Python object' in <type 'exceptions.GeneratorExit'> ignored
Exception RuntimeError: 'maximum recursion depth exceeded while calling a Python object' in <type 'exceptions.GeneratorExit'> ignored
Exception GeneratorExit in <generator object <genexpr> at 0x6d2e1e0> ignored
(Real Field with 53 bits of precision, Number Field in a with defining polynomial x^4 + x + 1, RuntimeError('maximum recursion depth exceeded while calling a Python object',))
(Complex Field with 53 bits of precision, Integer Ring, ArithmeticError('0^0 is undefined.',))
(Complex Field with 53 bits of precision, Rational Field, NaN - NaN*I)
(Complex Field with 53 bits of precision, Real Field with 53 bits of precision, NaN - NaN*I)
(Complex Field with 53 bits of precision, Complex Field with 53 bits of precision, NaN - NaN*I)
(Complex Field with 53 bits of precision, <type 'int'>, ArithmeticError('0^0 is undefined.',))
(Complex Field with 53 bits of precision, <type 'float'>, NaN - NaN*I)
(Complex Field with 53 bits of precision, Number Field in a with defining polynomial x^4 + x + 1, TypeError(<type 'sage.rings.complex_number.ComplexNumber'>,))
(<type 'int'>, Real Field with 53 bits of precision, TypeError("unsupported operand type(s) for ** or pow(): 'int' and 'sage.rings.real_mpfr.RealNumber'",))
(<type 'int'>, Complex Field with 53 bits of precision, AttributeError("'int' object has no attribute 'log'",))
(<type 'int'>, Number Field in a with defining polynomial x^4 + x + 1, TypeError('An embedding into RR or CC must be specified.',))
(<type 'float'>, Complex Field with 53 bits of precision, AttributeError("'float' object has no attribute 'log'",))
(<type 'float'>, Number Field in a with defining polynomial x^4 + x + 1, TypeError('An embedding into RR or CC must be specified.',))
(Number Field in a with defining polynomial x^4 + x + 1, Integer Ring, ArithmeticError('0^0 is undefined.',))
(Number Field in a with defining polynomial x^4 + x + 1, Rational Field, ArithmeticError('0^0 is undefined.',))
(Number Field in a with defining polynomial x^4 + x + 1, Real Field with 53 bits of precision, ArithmeticError('0^0 is undefined.',))
(Number Field in a with defining polynomial x^4 + x + 1, Complex Field with 53 bits of precision, TypeError('An embedding into RR or CC must be specified.',))
(Number Field in a with defining polynomial x^4 + x + 1, <type 'int'>, ArithmeticError('0^0 is undefined.',))
(Number Field in a with defining polynomial x^4 + x + 1, <type 'float'>, ArithmeticError('0^0 is undefined.',))
(Number Field in a with defining polynomial x^4 + x + 1, Number Field in a with defining polynomial x^4 + x + 1, ArithmeticError('0^0 is undefined.',))
sage: N
25

So in about half of these cases (25/49) we follow Python's convention 0^0=1 and the other half of the time we get an assortment of errors and NaN. This patch removes the 10 occurrences of ArithmeticError from the list. Other tickets can deal with the other cases.

Example 2:

sage: a = Matrix([[1,0],[0,0]]); a
[1 0]
[0 0]
b = Matrix([[0,0],[0,0]]); b
[0 0]
[0 0]
sage: a^0
[1 0]
[0 1]
sage: b^0
ArithmeticError: 0^0 is undefined.

Here Sage finds a!=0, and concludes a^0 = a.parent()(1). Note that the lower right entry of a^0 should be 0^0, and is 1.
Next, Sage finds b==0, and concludes that b^0 is illegal. Both the upper left and lower right entry of b are the same as the lower right entry of a, so the behaviour of a^0 and b^0 in Sage is inconsistent: either both should yield an ArithmeticError or neither should.
The patch adopts Python's convention so that the output of b^0 is the 2x2 identity matrix and this example becomes consistent.

Example 3:

sage: K.<a> = NumberField(x^3+x+1)
sage: K.relativize(1, 'c')
Number Field in c0 with defining polynomial x^3 + x + 1 over its base field
sage: K.relativize(0, 'c')
ArithmeticError: 0^0 is undefined.

This is explained by

sage: NumberField(x-1, 'a').power_basis()
[1]
sage: NumberField(x, 'a').power_basis()
ArithmeticError: 0^0 is undefined.

And it gets worse: a number field with defining polynomial x is part of the output of K.subfields()

sage: s = K.subfields()
sage: for i in [1,0]:
....:     K.relativize(s[i][1], 'c')
....: 
Number Field in c0 with defining polynomial x - a1 over its base field
ArithmeticError: 0^0 is undefined.

This last example is clearly a bug. An automatic consequence of generalizing Python's convention 0^0=1 is that this bug vanishes.

Interestingly, the patch adds no code.

Component: basic arithmetic

Keywords: 0, power, pow, matrix, convention, python

Author: Marco Streng

Reviewer: Robert Bradshaw

Merged: sage-4.7.alpha2

Issue created by migration from https://trac.sagemath.org/ticket/10772

@mstreng
Copy link
Author

mstreng commented Feb 11, 2011

comment:1

Attachment: trac_10772-0pow0.patch.gz

@jdemeyer
Copy link

Reviewer: Robert Bradshaw

@jdemeyer
Copy link

Merged: sage-4.7.alpha2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants