MPolynomialRing and indeterminate names

7 views
Skip to first unread message

Marc Roeder

unread,
May 22, 2008, 7:43:24 AM5/22/08
to sage-support
Dear sage community,

I am new to sage, so please forgive me if I am reporting well-known
behaviour here.
When generating multivariate polynomial rings, some (seemingly) odd
things can happen:

1. Sage seems to guess the meaning of 'x' in some cases:

sage: QX=MPolynomialRing(QQ,2,'xy'); QX
Multivariate Polynomial Ring in x, y over Rational Field
sage: x in QX # no variables assinged to indeterminates yet...
False
sage: indets=QX.objgens()[1];indets
(x, y)
sage: x in indets
True

But x and indets[0] have different types.

2. indeterminates are sometimes shared between rings:
sage: R.<x,y>=QQ[];R
Multivariate Polynomial Ring in x, y over Rational Field
sage: R2=MPolynomialRing(QQ,2,'xy')
sage: R==R2
True
sage: R2=MPolynomialRing(QQ,1,'x')
sage: x in R2
False

This looks inconsistent. Shouldn't R2 have it's own set of
indeterminates? If the user wants to have the same display names for
indeterminates of different rings that shouldn't be sage's problem.

Thanks very much,
marc

William Stein

unread,
May 22, 2008, 9:43:56 AM5/22/08
to sage-s...@googlegroups.com
On Thu, May 22, 2008 at 4:43 AM, Marc Roeder <roede...@gmail.com> wrote:
>
> Dear sage community,
>
> I am new to sage, so please forgive me if I am reporting well-known
> behaviour here.
> When generating multivariate polynomial rings, some (seemingly) odd
> things can happen:
>
> 1. Sage seems to guess the meaning of 'x' in some cases:
>
> sage: QX=MPolynomialRing(QQ,2,'xy'); QX
> Multivariate Polynomial Ring in x, y over Rational Field
> sage: x in QX # no variables assinged to indeterminates yet...
> False

That is the predefined symbolic x that is defined at startup
before you do anything. Unless you explicitly assign the
gens of QX to variables (or set auto injection on),
they won't be bound to variables.

sage: type(x)
<class 'sage.calculus.calculus.SymbolicVariable'>
sage: QX=MPolynomialRing(QQ,2,'xy')
sage: type(x)
<class 'sage.calculus.calculus.SymbolicVariable'>
sage: QX.gens()
(x, y)
sage: type(QX.gens()[0])
<type 'sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular'>

You might like the inject_on() mode:

sage: inject_on()
Redefining: Frac FreeMonoid GF FractionField FiniteField
PolynomialRing quotient NumberField LaurentSeriesRing quo
sage: QX=PolynomialRing(QQ,2,'xy')
Defining x, y
sage: type(x)
<type 'sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular'>
sage: type(y)
<type 'sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular'>


WARNING: inject_on only works with the PolynomialRing command, not the
MPolynomialRing command. Either the latter should be supported, or
the command should be removed entirely. We are tracking this issue here:
http://trac.sagemath.org/sage_trac/ticket/3271


> sage: indets=QX.objgens()[1];indets
> (x, y)
> sage: x in indets
> True
>
> But x and indets[0] have different types.

"foo in bar" means that foo compares to be equal (under natural
coercions) to bar. E.g., the rational number 3/1 is equal to the
integer 3, so

sage: 3/1 in [3, 5]
True

even though the types are different. The same happens above
in your example.

>
> 2. indeterminates are sometimes shared between rings:
> sage: R.<x,y>=QQ[];R
> Multivariate Polynomial Ring in x, y over Rational Field
> sage: R2=MPolynomialRing(QQ,2,'xy')
> sage: R==R2
> True
> sage: R2=MPolynomialRing(QQ,1,'x')
> sage: x in R2
> False

See above. There is *no* canonial inclusion map
from the second ring to the first in Sage.

This is different than the following example:

sage: QX=PolynomialRing(QQ,2,'xy')
sage: x in [ QX.0] # here x is he default symbolic var
True

Here the "in" is true since there is a canonical ceorcion
map from QX into the ring of all symbolic expressions.

>
> This looks inconsistent. Shouldn't R2 have it's own set of
> indeterminates?

It does.

> If the user wants to have the same display names for
> indeterminates of different rings that shouldn't be sage's problem.

It isn't.

>
> Thanks very much,
> marc
>
> >
>

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

Simon King

unread,
May 22, 2008, 10:03:09 AM5/22/08
to sage-support
Dear Marc,

let me try some explanations.

On May 22, 1:43 pm, Marc Roeder <roeder.m...@gmail.com> wrote:
> sage: QX=MPolynomialRing(QQ,2,'xy')
> sage: x in QX # no variables assinged to indeterminates yet...
> False

If you start Sage, x is already defined:
sage: type(x)
<class 'sage.calculus.calculus.SymbolicVariable'>

The apparent reason is that 'x' is a typical name for a symbolic
variable. However, when one isn't aware that x is pre-defined, strange
things may happen.

Now, defining
sage: QX=MPolynomialRing(QQ,2,'xy')
does *not* change x!

Sage makes a clear distinction between the default symbolic variable
with identifier 'x' and the ring variable with the name 'x'. The ring
variable can be accessed with
sage: QX.gen(0)
x
sage: x is QX.gen(0)
False

> sage: indets=QX.objgens()[1];indets
> (x, y)
> sage: x in indets
> True
> But x and indets[0] have different types.

You are right:
sage: type(QX.objgens()[1][0])
<type
'sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular'>
sage: type(x)
<class 'sage.calculus.calculus.SymbolicVariable'>
sage: x in QX.objgens()[1]
True

I think this is a confusing behaviour that probably has the following
reason:
sage: x==QX.gen(0)
x == x

This is a symbolic equation (since x is symbolic) that evaluates to
True, and consequently you get the wrong answer that the symbolic
variable x belongs to indets.

In x==QX.gen(0) apparently the two *different* objects with coinciding
names got mixed up. Do the more experienced Sage users agree with me
that this is not nice (or a bug)?

> 2. indeterminates are sometimes shared between rings:
> sage: R.<x,y>=QQ[];R

By the way, if you use that syntax, the symbolic variable x is
overwritten, and now x is known to Sage as a ring generator:
sage: R.<x,y>=QQ[]
sage: type(x)
<type
'sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular'>

> sage: R2=MPolynomialRing(QQ,2,'xy')
> sage: R==R2
> True

Yes, they are the same, in the sense that they have the same base ring
and the same variable names in the same *order*.
Compare
sage: R3=MPolynomialRing(QQ,2,'yx')
sage: R==R3
False

Even more, R and R2 are not only the same but *identical*:
sage: R is R2
True

Therefore, x (which is now defined as a generator of R) is also
generator of R2 (since R2 is identical with R2), but it is not a
generator of R3:
sage: x in R3
False

> sage: R2=MPolynomialRing(QQ,1,'x')
> sage: x in R2
> False

Yes, in this example R2 is not identical with R, and by consequence x
does not belong to R2.

In conclusion, i believe that
1) pre-defining x may be confusing, but this is Sage tradition
2) sage: bool(var('x')=='x')
True
is a bug, IMO.
3) your observations concerning generators of R,R2 can be explained by
the distinction between "the same" and "identical".

Yours
Simon

William Stein

unread,
May 22, 2008, 10:09:45 AM5/22/08
to sage-s...@googlegroups.com

NO. That is not what is going on. The explanation is that there is
a canonical map from QX to the symbolic ring. The in command
doesn't get confused by x == QX.gen(0) being a symbolic equality,
since it calls bool on that.

>
> In x==QX.gen(0) apparently the two *different* objects with coinciding
> names got mixed up. Do the more experienced Sage users agree with me
> that this is not nice (or a bug)?

I definitely do not agree with you.

It makes a lot of things much more concise. Sage is to be *used*,
not to be some hard-to-use abstract formal system.

> 2) sage: bool(var('x')=='x')
> True
> is a bug, IMO.

I disagree. There is a canonical coercion to the symbolic ring.

> 3) your observations concerning generators of R,R2 can be explained by
> the distinction between "the same" and "identical".

Yes.

Simon King

unread,
May 22, 2008, 11:50:28 AM5/22/08
to sage-support
Dear William,

On May 22, 4:09 pm, "William Stein" <wst...@gmail.com> wrote:
> I disagree. There is a canonical coercion to the symbolic ring.

It seems that i need to learn more about canonical coercion. I thought
that a coercion map goes between two parent structures, according to
http://modular.math.washington.edu/sage/doc/html/prog/node17.html
But the strings do not form a parent structure (or at least,
'x'.parent() is not defined).

In fact there is no coercion around:
sage: x.parent()._coerce_('x')
Traceback
...
<type 'exceptions.TypeError'>: cannot coerce type '<type 'str'>' into
a SymbolicExpression.

Consequently, we have
sage: x == 'x***2'
False

According to http://modular.math.washington.edu/sage/doc/html/prog/node17.html,
var('x')=='x' should return False as well, since there is no coercion
between strings and SymbolicExpression.

So, in what sense is var('x')=='x' involving a canonical coercion
map?

Is there a definition of "coercion map" and of "canonical", except the
page http://modular.math.washington.edu/sage/doc/html/prog/node17.html?

Yours
Simon

William Stein

unread,
May 22, 2008, 12:09:36 PM5/22/08
to sage-s...@googlegroups.com
On Thu, May 22, 2008 at 8:50 AM, Simon King <ki...@mathematik.uni-jena.de> wrote:
>
> Dear William,
>
> On May 22, 4:09 pm, "William Stein" <wst...@gmail.com> wrote:
>> I disagree. There is a canonical coercion to the symbolic ring.
>
> It seems that i need to learn more about canonical coercion. I thought
> that a coercion map goes between two parent structures, according to
> http://modular.math.washington.edu/sage/doc/html/prog/node17.html
> But the strings do not form a parent structure (or at least,
> 'x'.parent() is not defined).

That's right.

>
> In fact there is no coercion around:

There is a non-canonical coercion:

sage: SR('x')
x

That's used when constructing the symbolic equation:

sage: x == 'x'
x == x

Normally equality testing should only use canonical coercions:

sage: QQ(1) == GF(7)(1)
False
sage: GF(7)(QQ(1))
1


> sage: x.parent()._coerce_('x')
> Traceback
> ...
> <type 'exceptions.TypeError'>: cannot coerce type '<type 'str'>' into
> a SymbolicExpression.
>
> Consequently, we have
> sage: x == 'x***2'
> False
>
> According to http://modular.math.washington.edu/sage/doc/html/prog/node17.html,
> var('x')=='x' should return False as well, since there is no coercion
> between strings and SymbolicExpression.

var('x') == 'x' is a constructor for a symbolic equation, so it should
return a symbolic equation.

>
> So, in what sense is var('x')=='x' involving a canonical coercion
> map?

It turns out that this involves the noncanonical coercion map.

> Is there a definition of "coercion map" and of "canonical", except the
> page http://modular.math.washington.edu/sage/doc/html/prog/node17.html?

Yes.

-- William

Simon King

unread,
May 22, 2008, 12:49:13 PM5/22/08
to sage-support
On May 22, 6:09 pm, "William Stein" <wst...@gmail.com> wrote:
> > In fact there is no coercion around:
>
> There is a non-canonical coercion:
>
> sage: SR('x')
> x

According to http://modular.math.washington.edu/sage/doc/html/prog/node17.html,
this is *not* a (non-canonical) coercion but object creation.

> var('x') == 'x' is a constructor for a symbolic equation, so it should
> return a symbolic equation.

I know. But http://modular.math.washington.edu/sage/doc/html/prog/node17.html
also mentions the __cmp__-method, which should return -1 since there
is no _coerce_ defined.
sage: x.__cmp__('x') # with double underscore
0
sage: x._cmp_('x') # with single underscore
1

Compare
sage: QQ(1)._cmp_(GF(7)(1)) # single underscore
-1
sage: QQ(1).__cmp__(GF(7)(1)) # double underscore
Traceback
which shouldn't happen by Python convention!

> > Is there a definition of "coercion map" and of "canonical", except the
> > page http://modular.math.washington.edu/sage/doc/html/prog/node17.html?
>
> Yes.

Namely?
Simon
Reply all
Reply to author
Forward
0 new messages