You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
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.
Python has the convention
x**0 = 1
even forx=0
. Sage follows this convention in some cases, but raises an error in others. This patch generalizes Python's convention tosage.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:
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 andNaN
. This patch removes the 10 occurrences ofArithmeticError
from the list. Other tickets can deal with the other cases.Example 2:
Here Sage finds
a!=0
, and concludesa^0 = a.parent()(1)
. Note that the lower right entry ofa^0
should be0^0
, and is1
.Next, Sage finds
b==0
, and concludes thatb^0
is illegal. Both the upper left and lower right entry ofb
are the same as the lower right entry ofa
, so the behaviour ofa^0
andb^0
in Sage is inconsistent: either both should yield anArithmeticError
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:
This is explained by
And it gets worse: a number field with defining polynomial
x
is part of the output ofK.subfields()
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
The text was updated successfully, but these errors were encountered: