#10772: 0**0 = 1 for number fields, matrices, and more
--------------------------------+-------------------------------------------
Reporter: mstreng | Owner: AlexGhitza
Type: defect | Status: new
Priority: major | Milestone:
Component: basic arithmetic | Keywords: 0, power, pow, number field,
matrix, convention, python
Author: Marco Streng | Upstream: N/A
Reviewer: | Merged:
Work_issues: |
--------------------------------+-------------------------------------------
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
[http://groups.google.com/group/sage-
nt/browse_thread/thread/67e53f8e5d5061d2 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.
--
Ticket URL: <http://trac.sagemath.org/sage_trac/ticket/10772>
Sage <http://www.sagemath.org>
Sage: Creating a Viable Open Source Alternative to Magma, Maple, Mathematica,
and MATLAB
--
You received this message because you are subscribed to the Google Groups
"sage-trac" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/sage-trac?hl=en.