QQ['x,y'](0).degree() == -1

1 view
Skip to first unread message

Martin Albrecht

unread,
Aug 13, 2008, 2:17:16 PM8/13/08
to sage-...@googlegroups.com
Hi there,

on IRC right now we have a brief discussion based triggered by:

http://trac.sagemath.org/sage_trac/ticket/3840

I was puzzled by the choice of degree(0) == -1. Since we couldn't agree, I
though posting to [sage-devel] might be a good idea.

On IRC Carl pointed out:
- that this issue was touched on before:
http://groups.google.com/group/sage-devel/browse_thread/thread/f9d7b5016e237b22/7bafcc16315a21bb
- that Modern Computer Algebra defines degree(0) as -Infinity, since it
preserves: degree(ab) == degree(a) + degree(b)
- that -1 allows: cdef int d = p.degree() while -Infinity wouldn't

In any case, Sage's behaviour is inconsistent now:

sage: RR['x,y'](0).degree()
-1
sage: RR['x'](0).degree()
-1
sage: GF(2)['x'](0).degree()
-1
sage: QQ['x,y'](0).degree() # yep, I wrote that
0

I think that the last point isn't important enough to go for -1, so I'd vote
for -Infinity.

So my proposed game plan:
- I fix the libsingular wrapper to return -1
- Gary finishes his patch #3840
- [sage-devel] agrees on -Infinity or -1

Thoughts?
Martin
'

David Harvey

unread,
Aug 13, 2008, 2:23:17 PM8/13/08
to sage-...@googlegroups.com

With some reluctance, I vote for -Infinity.

*however*, it might be good to (eventually?) have a general mechanism
for making life easier for a cython caller. Perhaps _degree() is a
cdef where available, returning -1, and degree just a wrapper for
that? I don't like that so much either. Hmmmm.

david

Nick Alexander

unread,
Aug 13, 2008, 2:40:28 PM8/13/08
to sage-...@googlegroups.com
> In any case, Sage's behaviour is inconsistent now:
>
> sage: RR['x,y'](0).degree()
> -1
> sage: RR['x'](0).degree()
> -1
> sage: GF(2)['x'](0).degree()
> -1
> sage: QQ['x,y'](0).degree() # yep, I wrote that
> 0
>
> I think that the last point isn't important enough to go for -1, so
> I'd vote
> for -Infinity.

With some reluctance, I vote for -1. I've never been a fan of
testing for, and having to import, Infinity.

Nick

William Stein

unread,
Aug 13, 2008, 2:57:35 PM8/13/08
to sage-...@googlegroups.com


John Cannon votes for -1:
sage: magma.eval('Degree(PolynomialRing(RationalField())!0)')
'-1'

Henri Cohen votes for -2147483647:
sage: gp.eval('poldegree(0)')
'-2147483647'

Stephen Wolfram votes for -Infinity
sage: mathematica.eval('Exponent[x^2,x]')
2
sage: mathematica.eval('Exponent[0,x]')
-Infinity

Michael Monagon votes for -infinity:
> degree(x);
1
> degree(0*x);
-infinity

Joachim Neubuser votes for +infinity!
sage: gap.eval('x := Indeterminate(Rationals);')
'x_1'
sage: gap.eval('Degree(x)')
'1'
sage: gap.eval('Degree(0*x)')
'infinity'

I can't figure out how to get the degree of a poly in maxima.

William

-- William

Robert Bradshaw

unread,
Aug 13, 2008, 3:23:07 PM8/13/08
to sage-...@googlegroups.com

No one's gotten around to it yet, but degree really should be changed to a
cpdef method, and as such it makes much more sense to return a long (and
hence -1). It also makes it easier to write loops (e.g. 0 <= i <=
f.degree()) and determine the number of coefficients (f.degree() + 1).

I also don't enjoy writing code that has to import and test for infinity.

- Robert

William Stein

unread,
Aug 13, 2008, 3:29:39 PM8/13/08
to sage-...@googlegroups.com

I vote for -1 since... that's what I already voted for by making it -1
in the first place. I like the consistency with Magma.

-- William


--
William Stein
Associate Professor of Mathematics
University of Washington
http://wstein.org

Gary Furnish

unread,
Aug 13, 2008, 3:59:17 PM8/13/08
to sage-...@googlegroups.com
I vote -1 for the same reasons as Robert.

John H Palmieri

unread,
Aug 13, 2008, 5:16:02 PM8/13/08
to sage-devel
On Aug 13, 11:17 am, Martin Albrecht <m...@informatik.uni-bremen.de>
wrote:
> Hi there,
>
> on IRC right now we have a brief discussion based triggered by:
>
>    http://trac.sagemath.org/sage_trac/ticket/3840
>
> I was puzzled by the choice of degree(0) == -1. Since we couldn't agree, I
> though posting to [sage-devel] might be a good idea.
>
> On IRC Carl pointed out:
> - that this issue was touched on before:http://groups.google.com/group/sage-devel/browse_thread/thread/f9d7b5...
> - that Modern Computer Algebra defines degree(0) as -Infinity, since it
> preserves: degree(ab) == degree(a) + degree(b)
> - that -1 allows: cdef int d = p.degree() while -Infinity wouldn't
>
> In any case, Sage's behaviour is inconsistent now:
>
> sage: RR['x,y'](0).degree()
> -1
> sage: RR['x'](0).degree()
> -1
> sage: GF(2)['x'](0).degree()
> -1
> sage: QQ['x,y'](0).degree() # yep, I wrote that
> 0
>
> I think that the last point isn't important enough to go for -1, so I'd vote
> for -Infinity.
>
> So my proposed game plan:
>  - I fix the libsingular wrapper to return -1
>  - Gary finishes his patch #3840
>  - [sage-devel] agrees on -Infinity or -1
>
> Thoughts?
> Martin

I would vote for -Infinity, partly from a mathematical standpoint, and
also because this sort of bothers me:

sage: F = Frac(CC[['x']]) # or F.<x> = LaurentSeriesRing(CC)
sage: F(0).degree() == F(x**(-1)).degree()
True
sage: F(0).degree() > F(x**(-2)).degree()
True

(As a separate issue, this bothers me *much* more:

sage: K = Frac(QQ[['x']])
sage: K(x**(-1))
---------------------------------------------------------------------------
TypeError Traceback (most recent call
last)

...)

Carl Witty

unread,
Aug 13, 2008, 5:30:41 PM8/13/08
to sage-devel
On Aug 13, 2:16 pm, John H Palmieri <jhpalmier...@gmail.com> wrote:
> I would vote for -Infinity, partly from a mathematical standpoint, and
> also because this sort of bothers me:
>
> sage: F = Frac(CC[['x']])  # or F.<x> = LaurentSeriesRing(CC)
> sage: F(0).degree() == F(x**(-1)).degree()
> True
> sage: F(0).degree() > F(x**(-2)).degree()
> True

That's a compelling argument. Maybe David Harvey's suggestion of
separate interfaces for .degree() (mathematical, returns -infinity)
and for ._degree() (fast, computational, returns -1 or -2147483647) is
the right way to go?

> (As a separate issue, this bothers me *much* more:
>
> sage: K = Frac(QQ[['x']])
> sage: K(x**(-1))
> ---------------------------------------------------------------------------
> TypeError                                 Traceback (most recent call
> last)
>
> ...)

This is because you're using the 'x' from calculus; this works:
sage: K.<x> = Frac(QQ[['x']])
sage: K(x**(-1))
x^-1

Carl

Nick Alexander

unread,
Aug 13, 2008, 6:04:37 PM8/13/08
to sage-...@googlegroups.com

On 13-Aug-08, at 2:30 PM, Carl Witty wrote:

>
> On Aug 13, 2:16 pm, John H Palmieri <jhpalmier...@gmail.com> wrote:
>> I would vote for -Infinity, partly from a mathematical standpoint,
>> and
>> also because this sort of bothers me:
>>
>> sage: F = Frac(CC[['x']]) # or F.<x> = LaurentSeriesRing(CC)
>> sage: F(0).degree() == F(x**(-1)).degree()
>> True
>> sage: F(0).degree() > F(x**(-2)).degree()
>> True
>
> That's a compelling argument. Maybe David Harvey's suggestion of
> separate interfaces for .degree() (mathematical, returns -infinity)
> and for ._degree() (fast, computational, returns -1 or -2147483647) is
> the right way to go?

I'd be happy with this, if it returned -214... -- then the check is
_degree() < 0. The Laurent series argument is convincing.

Nick

Robert Bradshaw

unread,
Aug 13, 2008, 6:41:55 PM8/13/08
to sage-...@googlegroups.com

Yes, that Laurent series comparison is a bit bothersome. If it can be
avoided, however, I dislike having two ways of doing things, the "fast"
way and the "slow, obvious" way. I'm a big proponent of having the obvious
way be the fast way--that's the whole point of cpdef functions. It also
makes migrating code from Python to Cython more painful and uglier.

- Robert

David Harvey

unread,
Aug 13, 2008, 6:49:37 PM8/13/08
to sage-...@googlegroups.com

Here's what magma has to say about laurent series:

> R<x> := PolynomialRing(RationalField());
> Degree(R!0);
-1
> S<y> := LaurentSeriesRing(RationalField());
> Degree(S!0);

>> Degree(S!0);
^
Runtime error in 'Degree': Degree of zero or O(x^n) illegal

But the same error occurs for PowerSeriesRing as well, so there's
some consistency at least.

david

Ralf Hemmecke

unread,
Aug 13, 2008, 6:54:19 PM8/13/08
to sage-...@googlegroups.com

If I may say something...

What is the signature of degree in some domain D?

Is it

degree: D -> (Integer u {-Infinity})

or

degree: (D \ {0}) -> Integer

or

degree: D -> Integer

?

It is all clear (except in the last case) if it is somewhere specified
what the domain and codomain of 'degree' should be. In the last case it
is not so clear what degree(0) should be if D represents Laurent
polynomials.

One might also explicitly say that degree(0) is unspecified, i.e. that
degree is only a partial function.

Note, that -Infinity is not an integer and making

Integer u {-Infinity}

into a ring can be a bit difficult. (What is (-2)*(-Infinity)?)

Just a bit more oil for the fire...

Ralf

chris wuthrich

unread,
Aug 15, 2008, 4:32:30 AM8/15/08
to sage-devel
Without hesitation I vote against -1.

Either -Infinity or an error seems the mathematically correct answer
and I believe that sage should answer to a mathematician independent
of how complicated the implementation at the back is.

Chris.

John Cremona

unread,
Aug 15, 2008, 4:48:09 AM8/15/08
to sage-...@googlegroups.com
2008/8/15 chris wuthrich <christian...@gmail.com>:

I agree (and despite the conflict with Magma). For exactly the same
reason as this:

sage: 0.valuation(2)
+Infinity

The degree *is* a valuation (times minus 1), and must behave
consistently with its extension to the fraction field (rational
functions) and to completions (Laurent polynomials).

So I vote that the 0 polynomial should have degree -Infinity.

John


> Chris.
> >
>

Bill Hart

unread,
Aug 15, 2008, 2:57:24 PM8/15/08
to sage-devel
Mathematicians are always worried about degrees. Why can't they just
judge hard working polynomials according to the lengths they've gone
to satisfy us.

To be honest, I don't like deg(f) = -infinity, but I can't vote
against it in all conscience.

At the same time, I fully support Robert's arguments, but won't a
polynomial length function do the same job for him (and me)?

Of course length is not too useful in the function field and
completions, but then degree isn't that useful computationally
speaking, either, is it?

I vote for -1, unless length exists for polynomials, in which case I
vote for -infinity.

Of course technically it should be implemented via an http lookup of a
table of things no one could really figure out, stored in a database
so it can easily be changed. It should be reported as follows:

sage: f.degree()
Looking up value.....
This week the value is...
calculating............................................................................................
99%
---------------------------------------------------------------------------
AttributeError Traceback (most recent call
last)

/home/wbhart/<ipython console> in <module>()

AttributeError: 'sage.noob' object has no attribute 'frigginclue'

Bill.

On 13 Aug, 20:23, Robert Bradshaw <rober...@math.washington.edu>
wrote:

David Kohel

unread,
Aug 17, 2008, 10:38:12 PM8/17/08
to sage-devel
I agree with John and Chris that the mathematical definition of
degree agrees with -val(f(x)) where val is the valuation at the
prime oo = (1/x) at infinity. Hence one could argue that the
correct definition is -infinity, which gives the correct absolute
value |0|_oo = 0 where |f(x)|_oo = c^-deg(f(x)) for 0 < c < 1.
However, +infinity (or unsigned) is equally valid, since the
agreement with -val is indirect and degree should always be
positive.

The compatibility of degree with Laurent series rings is that,
under the map of x in k[x] to t^-1 in k((t)), one has deg = -val.
However this equality is an misleading, since it is a consequence
of the product rule which masks the fact that deg is a sum over
the zeros of the polynomial which can be calculated as the order
of the unique pole at infinity. The correct definition is that
deg(f(x))
is the degree as a function of the affine (or projective) line to
itself.
In general for rational function (in particular Laurent polynomials),
one wants

deg(f(x)/g(x)) = max(deg(f(x)),deg(g(x)),

where gcd(f(x),g(x)) = 1, as this gives the degree of the map
of P^1 to itself given by (x:1) -> (f(x)/g(x):1) = (f(x):g(x)). From
this point of view, the degree of 0 is +infinity, since this is the
degree of the map.

Thus, mathematically, I would argue that deg(0) = +infinity (or
unsigned infinity) is the correct value.

The argument against -infinity is that -val it gives the wrong
interpretation of deg, since it suggests the wrong, additive,
extension of degree to k(x):

deg(f(x)/g(x)) = -(val(f(1/t) - val(g(1/t))
= deg(f(x)) - deg(g(x))

which takes negative values. This singles out the prime at
infinity as special, rather than recognising that it is a
convenient prime at which compute the degree only for
polynomials, which have poles only at infinity. In fact this
was briefly the definition of degree on k(x) in Magma until
Nils Bruin spotted the error.

Computationally, I am less certain of what should be returned.
It should be made clear that -1 is the wrong answer, which is
being returned to trap errors. Another option could be to raise
an actual error, which is an option in SAGE/Python but not
Magma, which does not have a mechanism for trapping errors.
The argument for error is that degree is defined for finite
morphisms and infinity is just a marker for failure to have finite
degree.

I would argue that the return value should be documented,
but determined by compatibility with Python conventions.
Since error or infinity would be valid, and -1 wrong, should we
not return one of the former two? Since infinity exists, should
it be used? In programming, what are the considerations of
importing Infinity, testing for f(x) = 0, or trapping errors?

Having gone this far in maligning -1, in the spirit of Bill Hart's
comment about judging (hardworking, univariate, dense)
polynomials by their lengths, I should point out that for
polynomials only, the definition deg(f(x)) = len(f(x)) - 1 extends
"naturally" to deg(0) = -1. One could add a length function,
but then does:

sage: P.<x> = PolynomialRing(QQ,sparse=True)
sage: f = x^7 + x
sage: f.len()

return 8? (Probably, since f.list() has length 8.)

--David

P.S.
Since the original question concerned multivariate polynomials,
I note that Magma does not define Degree for multivariate
polynomials, which is mathematically correct since k((x,y)) is
not a DVR. Degree(f(x,y),1) and Degree(f(x,y),2) exist. On
the other hand it does provide TotalDegree. This distinction is
mathematically justifiable but annoying, since I usually forget,
and expect the total degree.

For multivariate polynomials, I would like to be able to specify
a grading on the variables n1,..,nt such that degree could
return the degree under the image of k[x1,..,xt] into k[t],
sending xi to t^ni. This would be natural in a category of
graded rings, but here I consider the design of Magma to
be incorrect:

> P<x,y> := PolynomialRing(QQ,[2,3]);
> P;
Graded Polynomial ring of rank 2 over Rational Field
Lexicographical Order
Variables: x, y
Variable weights: 2 3
> TotalDegree(x);
1
> TotalDegree(y);
1

since this ignores the weights [2,3] of the variables, which
should be used by [Total]Degree and the determination of
a compatible monomial ordering. But this is another design
question whose discussion opens a lot of new issues.
Reply all
Reply to author
Forward
0 new messages