Sage: Ticket #13360: Should not allow coercion from polynomials to symbolic ring
https://trac.sagemath.org/ticket/13360
<p>
I've been struggling with some unexpected results in my computations with polynomials over the symbolic ring. Eventually, I came to the conclusion that it should not be possible to <em>coerce</em> polynomials to the symbolic ring. (Note: I'm not saying that you can't <em>convert</em> to the symbolic ring!) Here's some reasons for disallowing it.
</p>
<p>
I've also attached an initial patch implementing this. It needs more work though, because the same thing holds for <code>LaurentSeries</code> and <code>PowerSeries</code>.
</p>
<p>
Reasons for not allowing <a class="missing wiki">PolynomialRing?</a> -> SR coercion:
</p>
<p>
1) This inconsistency:
</p>
<pre class="wiki"> sage: R.<t> = QQ[]
sage: SR(t^2)
t^2
sage: R.<t> = SR[]
sage: SR(t^2)
Traceback (most recent call last):
...
TypeError: not a constant polynomial
</pre><blockquote>
<p>
I think the first one should raise a <a class="missing wiki">TypeError?</a>, too.
</p>
</blockquote>
<p>
2) This one:
</p>
<pre class="wiki"> sage: R.<t> = ZZ[]
sage: (t + 1/2).parent() # automatic base extension
Univariate Polynomial Ring in t over Rational Field
sage: R.<t> = ZZ[]
sage: (t + pi).parent() # expect base extension SR[t]
Symbolic Ring
</pre><blockquote>
<p>
It is not hard to imagine that this gives all kinds of unexpected results when trying to manipulate these kind of rings programmatically. This must have cost me days and days.
</p>
</blockquote>
<p>
3) There is also a better way to convert a polynomial to the symbolic ring,
namely just substituting a symbolic variable:
</p>
<pre class="wiki">sage: R.<t> = PolynomialRing(ZZ,'t')
sage: f = t^2 - t
sage: t = var('t')
sage: f(t)
(t - 1)*t
sage: f(t).parent()
Symbolic Ring
</pre><p>
This has the advantage that the conversion is explicit.
</p>
<p>
4) Philosophically, I would say that the name of the variable is just a display label, but as it is, it has the side effect of determining what variable to coerce to. Then if you want to return a polynomial from a library routine, you can't be sure that it won't collide with a user-defined variable upon coercion.
</p>
en-usSagehttps://trac.sagemath.org/chrome/site/logo_sagemath_trac.png
https://trac.sagemath.org/ticket/13360
Trac 1.1.6tkluckSat, 11 Aug 2012 20:40:30 GMTattachment set
https://trac.sagemath.org/ticket/13360
https://trac.sagemath.org/ticket/13360
<ul>
<li><strong>attachment</strong>
set to <em>trac_13360_no_coercion_from_polynomials_to_expressions.patch</em>
</li>
</ul>
TickettkluckSat, 11 Aug 2012 20:40:39 GMTattachment set
https://trac.sagemath.org/ticket/13360
https://trac.sagemath.org/ticket/13360
<ul>
<li><strong>attachment</strong>
set to <em>trac_13360_no_coercion_from_polynomials_to_expressions_002.patch</em>
</li>
</ul>
TickettkluckSat, 11 Aug 2012 20:45:33 GMTdescription changed
https://trac.sagemath.org/ticket/13360#comment:1
https://trac.sagemath.org/ticket/13360#comment:1
<ul>
<li><strong>description</strong>
modified (<a href="/ticket/13360?action=diff&version=1">diff</a>)
</li>
</ul>
TickettkluckSat, 11 Aug 2012 21:01:40 GMTstatus changed
https://trac.sagemath.org/ticket/13360#comment:2
https://trac.sagemath.org/ticket/13360#comment:2
<ul>
<li><strong>status</strong>
changed from <em>new</em> to <em>needs_review</em>
</li>
</ul>
TicketnbruinSat, 11 Aug 2012 21:16:37 GMT
https://trac.sagemath.org/ticket/13360#comment:3
https://trac.sagemath.org/ticket/13360#comment:3
<p>
3) You probably agree that *conversion* from polynomial rings to SR should be possible. However, I'm afraid that requires coercion to easily work in the following example:
</p>
<pre class="wiki">A.<a>=QQ[]
B.<b>=A[]
f=a^2*b+a*b^2
SR(f)
</pre><p>
Even though there is an explicit conversion asked, I think the system uses coercion on the coefficients of f, which are elements of the polynomial ring A. The same thing applies even more essentially to evaluating f at a symbolic expression.
</p>
<pre class="wiki">f(SR('x'))
</pre><p>
It's always one level further down where coercions are really useful.
</p>
<p>
For your other examples:
</p>
<p>
1), 2) <code>SR[]</code>
</p>
<p>
That should really be an error already. Nothing useful will even come from defining polynomials *over* the symbolic ring.
</p>
<p>
[<strong>EDIT</strong>: As shown below, people DO find uses for them.]
</p>
<p>
SR is not a fully implemented ring. For instance, equality testing is spotty at best. It's not really an integral domain either:
</p>
<pre class="wiki">max_symbolic(x,0)*min_symbolic(x,0)
</pre><p>
4) To some degree I agree with your philosophy, but Sage's coercion system doesn't. The variable names are part of the identity, e.q. <code>QQ['x']</code> and <code>QQ['x']</code> are identical objects, but <code>QQ['x']</code> and <code>QQ['y']</code> aren't (they aren't even equal). Similarly, elements from <code>QQ['x']</code> coerce into <code>QQ['x','y']</code> but not into <code>QQ['a','b']</code>. Coercing by name into SR is completely in step with that, whatever collisions that causes.
It may be possible to override this behaviour by installing custom coercions.
</p>
TickettkluckSun, 12 Aug 2012 09:05:59 GMT
https://trac.sagemath.org/ticket/13360#comment:4
https://trac.sagemath.org/ticket/13360#comment:4
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/13360#comment:3" title="Comment 3">nbruin</a>:
</p>
<blockquote class="citation">
<p>
3) You probably agree that *conversion* from polynomial rings to SR should be possible.
</p>
</blockquote>
<p>
Thanks for commenting, nbruin! Yes I agree (I actually mention that in italics right at the top).
</p>
<blockquote class="citation">
<p>
However, I'm afraid that requires coercion to easily work in the following example:
</p>
<pre class="wiki">A.<a>=QQ[]
B.<b>=A[]
f=a^2*b+a*b^2
SR(f)
</pre></blockquote>
<p>
I would suggest replacing this with
</p>
<pre class="wiki">sage: a,b=var('a,b')
sage: f(a,b)
</pre><p>
Which relates to ...
</p>
<blockquote class="citation">
<p>
Even though there is an explicit conversion asked, I think the system uses coercion on the coefficients of f, which are elements of the polynomial ring A. The same thing applies even more essentially to evaluating f at a symbolic expression.
</p>
<pre class="wiki">f(SR('x'))
</pre></blockquote>
<p>
I'm glad you mention this example. For me, this is not the same thing. In a way, it is <em>exactly</em> the distinction I'm trying to make with this ticket. I think your example should be allowed whereas coercion shouldn't.
</p>
<blockquote class="citation">
<p>
For your other examples:
</p>
<p>
1), 2) <code>SR[]</code>
</p>
<p>
That should really be an error already. Nothing useful will even come from defining polynomials *over* the symbolic ring.
</p>
</blockquote>
<p>
The sage documentation explicitly states that this is supported (at least in the case of the <code>PowerSeriesRing</code>).
</p>
<p>
As for it not being useful, I strongly disagree with that. As soon as you need coefficients like pi or sin(3), this is the only way to go. For example, to come back to your code:
</p>
<pre class="wiki">sage: A.<a>=QQ[]
sage: B.<b>=A[]
sage: f=a^2*b+a*b^2
sage: f(b=pi) # would expect an expansion in a, like pi*a^2 + pi^2*a
(pi*a = a^2)*pi
sage: f(b=pi).parent() # I would expect: SR[a]
Symbolic Ring
</pre><p>
Or, for a more specialized example: I'm doing calculations with Lax matrices in integrable systems. Then you want to calculate Laurent series in the spectral parameter, whereas all other variables are manipulated symbolically (i.e. functions can be applied to them). Just doing those calculations in the symbolic ring is much slower, you would need to collect and expand all the time, and the symbolic ring cannot keep track of big ohs.
</p>
<p>
Of course, this ticket is exactly about inconsistencies arising from polynomial rings over SR. If you believe those should raise an error already, than it is logical to say that that is the source of the inconsistency. If, like me, you believe that it is very useful, then you open a ticket like this one. :-)
</p>
<blockquote class="citation">
<p>
4) To some degree I agree with your philosophy, but Sage's coercion system doesn't. The variable names are part of the identity, e.q. <code>QQ['x']</code> and <code>QQ['x']</code> are identical objects, but <code>QQ['x']</code> and <code>QQ['y']</code> aren't (they aren't even equal). Similarly, elements from <code>QQ['x']</code> coerce into <code>QQ['x','y']</code> but not into <code>QQ['a','b']</code>. Coercing by name into SR is completely in step with that, whatever collisions that causes.
</p>
</blockquote>
<p>
I think this is unfortunate, but I agree that the philosophy is in line with this.
</p>
TickettkluckSun, 12 Aug 2012 09:15:17 GMT
https://trac.sagemath.org/ticket/13360#comment:5
https://trac.sagemath.org/ticket/13360#comment:5
<blockquote class="citation">
<blockquote class="citation">
<p>
4) To some degree I agree with your philosophy, but Sage's coercion system doesn't. The variable names are part of the identity, e.q. <code>QQ['x']</code> and <code>QQ['x']</code> are identical objects, but <code>QQ['x']</code> and <code>QQ['y']</code> aren't (they aren't even equal). Similarly, elements from <code>QQ['x']</code> coerce into <code>QQ['x','y']</code> but not into <code>QQ['a','b']</code>. Coercing by name into SR is completely in step with that, whatever collisions that causes.
</p>
</blockquote>
<p>
I think this is unfortunate, but I agree that the philosophy is in line with this.
</p>
</blockquote>
<p>
As an afterthought: the symbolic ring offers <code>SR.symbol()</code> which guarantees a unique variable that doesn't clash with user-defined ones. There's no such thing for polynomial rings. On the other hand, you could make your library code accept a variable name in its argument spec. Then it's the user's responsibility to prevent a name clash.
</p>
TicketnbruinSun, 12 Aug 2012 17:30:36 GMT
https://trac.sagemath.org/ticket/13360#comment:6
https://trac.sagemath.org/ticket/13360#comment:6
<p>
OK, you seem to have some use cases where polynomials over SR do have some use. Indeed, basic arithmetic (but not division!) should be OK. I think what you need is that elements from polynomial rings *over SR* are not coercible into SR. A solution like this would need an expert in the coercion system to implement correctly, because the coercion system is one area of sage where a small and seemingly innocuous change can easily have huge consequences (for performance, correctness or both) for the entire system.
</p>
<p>
Roughly: if R.coerce_map_from(SR) is not None then SR.coerce_map_from(R['a',...]) should be None. I think that would remove most of the unexpected results.
</p>
TicketnovoseltSun, 12 Aug 2012 18:07:57 GMT
https://trac.sagemath.org/ticket/13360#comment:7
https://trac.sagemath.org/ticket/13360#comment:7
<p>
Polynomials with coefficients in SR are very useful and it is a pity that their support is not ideal - hopefully it will improve.
</p>
<p>
I do not agree that construction in 1) should give errors: as it is written, it is explicit conversion of a polynomial to the symbolic ring and I was annoyed by <code>TypeError: not a constant polynomial</code> recently, having to write <code>SR(str(f))</code>.
</p>
TicketnbruinSun, 12 Aug 2012 19:49:09 GMT
https://trac.sagemath.org/ticket/13360#comment:8
https://trac.sagemath.org/ticket/13360#comment:8
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/13360#comment:7" title="Comment 7">novoselt</a>:
</p>
<blockquote class="citation">
<p>
I do not agree that construction in 1) should give errors: as it is written, it is explicit conversion of a polynomial to the symbolic ring and I was annoyed by <code>TypeError: not a constant polynomial</code> recently, having to write <code>SR(str(f))</code>.
</p>
</blockquote>
<p>
How about
</p>
<pre class="wiki">R=SR['t']
f=SR('t') * R.0
</pre><p>
It's much better if <code>SR(f)</code> gives an error for that. The error you're seeing is the failure of a non-constant polynomial to be converted to an element of its base ring, as expected. Really, what you're looking for is a "specialization" of your polynomial, effected by an evaluation:
</p>
<pre class="wiki">f(SR('t'))
</pre><p>
No reason to convert to strings.
</p>
<p>
Polynomial rings should really not be coercible to their base rings, and probably also not generally convertible to them (apart from constants). Sage's concept of coercion really relies on there not being "loops" in the coercion graph. They wreak havoc with finding common covering structures.
</p>
TicketnovoseltSun, 12 Aug 2012 20:16:48 GMT
https://trac.sagemath.org/ticket/13360#comment:9
https://trac.sagemath.org/ticket/13360#comment:9
<p>
I think it is completely unambiguous what do I mean by <code>SR(f)</code> if <code>f</code> is a polynomial - I want a symbolic expression equal to this polynomial with the same names for variables. It is an explicit call to perform a conversion, not a coercion. If it is necessary to handle this conversion separately, it should be done internally, transparent for the user.
</p>
<p>
<code>f(SR('t'))</code> is unintuitive and what am I supposed to do if I have a hundred variables in my polynomial ring? Cook up some dictionary substitution for evaluation which will be even less intuitive? I don't see how it would be better than <code>SR(str(f))</code>, and the best form would be <code>SR(f)</code>.
</p>
<p>
I understand that loopy rings may cause difficulties in the framework, yet it is not a reason to cripple the symbolic ring. I think that pretty much anything has to be convertible to it. A possible solution for the situation in question may be "symbolic ring with black-listed names", so that if I want to consider a polynomial ring in <code>t</code> with symbolic coefficients, I explicitly create "<code>SR</code> that will never use <code>t</code>". Or perhaps a white-list version "<code>SR</code> that can only use <code>{a, d, beta}</code> for variable names" is better, especially if one creates iterated polynomial rings. Then there will be no collision between base ring and <code>SR</code> and clearly all such restricted rings are canonically coercible to <code>SR</code>, but not back. Note that such rings will also allow unambiguous conversion <strong>to</strong> polynomial rings with symbolic coefficients.
</p>
TickettkluckSun, 12 Aug 2012 20:59:38 GMT
https://trac.sagemath.org/ticket/13360#comment:10
https://trac.sagemath.org/ticket/13360#comment:10
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/13360#comment:9" title="Comment 9">novoselt</a>:
</p>
<blockquote class="citation">
<p>
I think it is completely unambiguous what do I mean by <code>SR(f)</code> if <code>f</code> is a polynomial - I want a symbolic expression equal to this polynomial with the same names for variables. It is an explicit call to perform a conversion, not a coercion. If it is necessary to handle this conversion separately, it should be done internally, transparent for the user.
</p>
</blockquote>
<p>
Even though I wrote this patch, I'm not too familiar with the coercion/conversion system. You may be right that it is easy to support <code>SR(f)</code> as an explicit conversion without coercions being possible. Because both coercion and conversion call the <code>_symbolic_</code> method, my patch may be too zealous in removing this support.
</p>
<p>
For me, however, point 2) is so important that I would accept losing <code>SR(f)</code> if 2) cannot be handled otherwise. In that case, it would make sense to add a method to <code>PolynomialRingElement</code> that does the substitution behind the scenes.
</p>
<p>
I'll see what happens if I revert the modifications to <code>_symbolic_</code> while retaining the ones to the coercion system.
</p>
TickettkluckSun, 12 Aug 2012 21:05:42 GMT
https://trac.sagemath.org/ticket/13360#comment:11
https://trac.sagemath.org/ticket/13360#comment:11
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/13360#comment:8" title="Comment 8">nbruin</a>:
</p>
<blockquote class="citation">
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/13360#comment:7" title="Comment 7">novoselt</a>:
</p>
<blockquote class="citation">
<p>
I do not agree that construction in 1) should give errors: as it is written, it is explicit conversion of a polynomial to the symbolic ring and I was annoyed by <code>TypeError: not a constant polynomial</code> recently, having to write <code>SR(str(f))</code>.
</p>
</blockquote>
<p>
How about
</p>
<pre class="wiki">R=SR['t']
f=SR('t') * R.0
</pre><p>
It's much better if <code>SR(f)</code> gives an error for that.
</p>
</blockquote>
<p>
This is actually a really good example. On second thought, I'm inclined to stand by my initial argument for removal of these conversions, too. I'm open to other views, though.
</p>
TickettkluckSun, 12 Aug 2012 21:16:43 GMT
https://trac.sagemath.org/ticket/13360#comment:12
https://trac.sagemath.org/ticket/13360#comment:12
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/13360#comment:6" title="Comment 6">nbruin</a>:
</p>
<blockquote class="citation">
<p>
I think what you need is that elements from polynomial rings *over SR* are not coercible into SR.
</p>
</blockquote>
<p>
From the code, I think that is exactly what's happening now. However, that is what leads to point 2). If an expert in the coercion system can make it such that <code>t + pi</code> coerces the summands into <code>SR[t]</code> instead of into <code>SR</code>, then maybe that would be a solution, too.
</p>
<p>
I'm sorry for spamming you guys by saying all this in three messages instead of one.
</p>
TickettkluckSun, 12 Aug 2012 22:48:36 GMTattachment set
https://trac.sagemath.org/ticket/13360
https://trac.sagemath.org/ticket/13360
<ul>
<li><strong>attachment</strong>
set to <em>trac_13359_expression_nonzero_shouldnt_call_variables_unless_necessary_0002.patch</em>
</li>
</ul>
TicketnbruinSun, 12 Aug 2012 23:27:44 GMT
https://trac.sagemath.org/ticket/13360#comment:13
https://trac.sagemath.org/ticket/13360#comment:13
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/13360#comment:12" title="Comment 12">tkluck</a>:
</p>
<blockquote class="citation">
<p>
From the code, I think that is exactly what's happening now. However, that is what leads to point 2). If an expert in the coercion system can make it such that <code>t + pi</code> coerces the summands into <code>SR[t]</code> instead of into <code>SR</code>, then maybe that would be a solution, too.
</p>
</blockquote>
<p>
I expect most people would find that undesirable. The most "economic" way of constructing <code>t+pi</code> if <code>t=ZZ['t'].0</code> is to make the symbolic expression <code>t+pi</code>. It is not necessary to create the more complicated parent <code>SR['t']</code> for this. Remember, polynomial rings over SR should be avoided for the most part. They are allowed to be constructed and have some limited use as you show, but sage should definitely not create them unless they are explicitly asked for.
</p>
TickettkluckSun, 12 Aug 2012 23:54:14 GMT
https://trac.sagemath.org/ticket/13360#comment:14
https://trac.sagemath.org/ticket/13360#comment:14
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/13360#comment:13" title="Comment 13">nbruin</a>:
</p>
<blockquote class="citation">
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/13360#comment:12" title="Comment 12">tkluck</a>:
I expect most people would find that undesirable. The most "economic" way of constructing <code>t+pi</code> if <code>t=ZZ['t'].0</code> is to make the symbolic expression <code>t+pi</code>. It is not necessary to create the more complicated parent <code>SR['t']</code> for this. Remember, polynomial rings over SR should be avoided for the most part. They are allowed to be constructed and have some limited use as you show, but sage should definitely not create them unless they are explicitly asked for.
</p>
</blockquote>
<p>
Are you sure? How about this example:
</p>
<pre class="wiki">sage: R.<t> = ZZ[]
sage: (t + QQbar(sqrt(2))).parent()
Univariate Polynomial Ring in t over Algebraic Field
sage: (t + sqrt(2)).parent()
Symbolic Ring
</pre><p>
Are you referring to any specific policy when saying "remember, polynomial rings over SR should be avoided"? Because I think they don't have to be and I'm trying to make their use as unsurprising as possible.
</p>
TicketnbruinMon, 13 Aug 2012 06:59:57 GMT
https://trac.sagemath.org/ticket/13360#comment:15
https://trac.sagemath.org/ticket/13360#comment:15
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/13360#comment:14" title="Comment 14">tkluck</a>:
</p>
<blockquote class="citation">
<blockquote>
<p>
Are you sure? How about this example:
</p>
<pre class="wiki"> sage: R.<t> = ZZ[]
sage: (t + QQbar(sqrt(2))).parent()
Univariate Polynomial Ring in t over Algebraic Field
</pre></blockquote>
</blockquote>
<p>
Exactly. <code>t</code> is transcendental over <code>ZZ</code> and hence over <code>QQ</code>, and QQbar contains no transcendentals. So it's clear an extension is needed.
</p>
<blockquote class="citation">
<pre class="wiki"> sage: (t + sqrt(2)).parent()
Symbolic Ring
</pre></blockquote>
<p>
There is a transcendental in <code>SR</code> with the print name <code>t</code>, so that is a natural image for <code>t</code> the polynomial variable over <code>ZZ</code>. So both <code>t</code> and <code>sqrt(2)</code> fit in <code>SR</code>, so that's where the answer lives.
</p>
<p>
For your application, it seems that you would like to restrict <code>SR</code> to what one would consider constants in calculus, such as <code>sin(2)</code> etc. A kind of transcendental version of QQbar. The problem is that <code>SR</code> is not such a ring. It also contains all kinds of non-constant transcendentals. In fact, it would normally appear that SR contains all constructible transcendentals (for the right meaning of constructible).
</p>
<p>
That's where <code>SR['T']</code> is special: You are clearly asking for a transcendental that doesn't lie in <code>SR</code>.
As you remark, sage already (justly) recognizes that by not allowing coercion of <code>T</code> into <code>SR</code>. So in my opinion sage already has exactly the right support for such rings.
</p>
TickettkluckMon, 13 Aug 2012 08:25:50 GMT
https://trac.sagemath.org/ticket/13360#comment:16
https://trac.sagemath.org/ticket/13360#comment:16
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/13360#comment:15" title="Comment 15">nbruin</a>:
</p>
<blockquote class="citation">
<p>
Exactly. <code>t</code> is transcendental over <code>ZZ</code> and hence over <code>QQ</code>, and QQbar contains no transcendentals. So it's clear an extension is needed.
</p>
<blockquote class="citation">
<pre class="wiki"> sage: (t + sqrt(2)).parent()
Symbolic Ring
</pre></blockquote>
<p>
There is a transcendental in <code>SR</code> with the print name <code>t</code>, so that is a natural image for <code>t</code> the polynomial variable over <code>ZZ</code>. So both <code>t</code> and <code>sqrt(2)</code> fit in <code>SR</code>, so that's where the answer lives.
</p>
</blockquote>
<p>
This is a nice way of viewing it, and I cannot say that you are totally wrong. Still, someone who actually wants this can easily easily convert to the <code>SR</code> (by substitution or by me introducing a dedicated method), whereas someone who wants the behaviour I'm suggesting has no way of making that happen. In this sense, the current behaviour makes Sage less flexible than it needs to be, with the benefit of making it slightly less surprising for a user doing smaller on the command line.
</p>
<p>
For that user, however, it really makes no big difference whether the result is in <code>SR</code> or in <code>SR[t]</code>: it is just as possible to plot, evaluate, etc, elements of <code>SR[t]</code> w.r.t. to <code>t</code> as it is for elements of <code>SR</code>. I will concede that there may come a point when it will surprise them, though.
</p>
<blockquote class="citation">
<p>
For your application, it seems that you would like to restrict <code>SR</code> to what one would consider constants in calculus, such as <code>sin(2)</code> etc. A kind of transcendental version of QQbar.
</p>
</blockquote>
<p>
No, definitely not, that's just the simple examples I've been giving. In my use case, the coefficients are all functions of symbolic variables.
</p>
<blockquote class="citation">
<p>
The problem is that SR is not such a ring. It also contains all kinds of non-constant transcendentals.
</p>
</blockquote>
<p>
I'm not sure what difference that makes from the point of view of adding a transcendental not in <code>SR</code>.
</p>
<blockquote class="citation">
<p>
That's where <code>SR['T']</code> is special: You are clearly asking for a transcendental that doesn't lie in <code>SR</code>.
As you remark, sage already (justly) recognizes that by not allowing coercion of <code>T</code> into <code>SR</code>. So in my opinion sage already has exactly the right support for such rings.
</p>
</blockquote>
<p>
Let me just give one more example. <code>ZZ</code> is an initial object for unitary rings, so this function:
</p>
<pre class="wiki">def transformation(polynomial):
R.<t> = ZZ[]
return sum ( polynomial[i] * t^i for i in range(polynomial.degree())
</pre><p>
will be the identity for all polynomials over any base ring, except for the symbolic ring. This map may not seem useful in practise, but imagine applying some map to the coefficients, or anything more interesting. The point is that the above may be a special case of some complicated transformation you're doing on polynomials.
</p>
<p>
I know that one could probably work around this by
</p>
<pre class="wiki"> R.<t> = polynomial.base_ring()[]
</pre><p>
instead, but since we're talking about the coercion system, I'm trying to show examples where I think it doesn't work as expected. I'm also thinking of the case where a library algorithm I didn't write would work excellently on <code>SR[]</code> based on the above assumption, except for the nonstandard handling of Sage of <code>SR</code> as a base ring. Then it is a shame if Sage's coercion system would force you to dig into the algorithm because it would have required the programmer to continuously check for the anomalous condition 'base_ring == SR'.
</p>
TicketnovoseltMon, 13 Aug 2012 13:14:35 GMT
https://trac.sagemath.org/ticket/13360#comment:17
https://trac.sagemath.org/ticket/13360#comment:17
<p>
Well, it is about as anomalous as the set of all sets: it is the only ring with canonical coersions into it from arbitrarily construction that uses it as a base ring.
</p>
<p>
I am really starting to think that my previous idea of introducing white/black-listed symbolic rings would be a good solution and it should not be too hard to implement (although I don't know much about how SR is done).
</p>
<p>
SR is similar to <code>automatic_names(True)</code> - any name appearing in a string fed to it will be treated as a new variable. If I could write something like
</p>
<pre class="wiki">sage: R = SR(allowed_names="a b beta")
sage: R("sqrt(a) * sin(beta)")
sqrt(a) * sin(beta)
sage: R("sqrt(a) * cos(alpha)")
...
NameError: alpha is not a variable in this symbolic ring
</pre><p>
it would definitely suit my purposes and I think it would allow adjusting coercion in such a way, that treating polynomials in t over this R or adding a polynomial over integers and elements of R behaves consistently with regular rings.
</p>
<p>
By the way, I think that this is a bug:
</p>
<pre class="wiki">sage: QQ["t"]["t"]
Univariate Polynomial Ring in t over Univariate Polynomial Ring in t over Rational Field
</pre><p>
Nobody in mathematics uses the same variable in the same expression with the same meaning, so there is no reason to support it. Moreover, this may indicate a logical error and a user would appreciate catching it. So I think that constructions that "add names" should check that they are absent in the base ring. This way it would be prohibited to create <code>SR["t"]</code>, but all polynomials can remain coercible to <code>SR</code>.
</p>
<p>
I suppose adding such a check is also not extremely difficult, but care should be taken when constructing polynomials "for internal purposes". There should be some standard way to get from a ring a name that can work as a "new name". And it should raise an exception for SR.
</p>
<p>
I also think that for any element of any ring we should have <code>R(str(f)) == f</code> which is impossible to hope for if we do not insist on distinct names for generators.
</p>
TicketnbruinMon, 13 Aug 2012 17:05:51 GMT
https://trac.sagemath.org/ticket/13360#comment:18
https://trac.sagemath.org/ticket/13360#comment:18
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/13360#comment:16" title="Comment 16">tkluck</a>:
</p>
<blockquote class="citation">
<p>
Let me just give one more example. <code>ZZ</code> is an initial object for unitary rings, so this function:
</p>
<pre class="wiki">def transformation(polynomial):
R.<t> = ZZ[]
return sum ( polynomial[i] * t^i for i in range(polynomial.degree())
</pre><p>
will be the identity for all polynomials over any base ring, except for the symbolic ring. This map may not seem useful in practise, but imagine applying some map to the coefficients, or anything more interesting. The point is that the above may be a special case of some complicated transformation you're doing on polynomials.
</p>
</blockquote>
<p>
That example doesn't work because sage refuses in a lot of cases to construct a suitable parent. Try:
</p>
<pre class="wiki">transformation(ZZ['a']['b']([1,2,3]))
</pre><p>
If it did work, it would only work for base rings that don't have a generator named <code>t</code> in them
already. So for any of
</p>
<pre class="wiki">Q['t','s']['a','b']
`QuadraticField(5,name='t')
PowerSeriesRing(QQ,name='t')['u','v']
</pre><p>
this would give a different answer than the functorial one I think you're expecting.
</p>
<p>
The fact that sage attaches meaning to print names of variables really does have some profound effects.
</p>
<blockquote class="citation">
<p>
I know that one could probably work around this by
</p>
<pre class="wiki"> R.<t> = polynomial.base_ring()[]
</pre></blockquote>
<p>
Indeed. It's much better to be explicit than making the system guess where you want your answer to live.
</p>
<p>
I would probably do
</p>
<pre class="wiki"> t=polynomial.parent().0
return sum ( polynomial[i] * t^i for i in range(polynomial.degree())
</pre><p>
in order to avoid introducing new (hard coded) names unnecessarily.
</p>
TicketjdemeyerTue, 13 Aug 2013 15:35:53 GMTmilestone changed
https://trac.sagemath.org/ticket/13360#comment:19
https://trac.sagemath.org/ticket/13360#comment:19
<ul>
<li><strong>milestone</strong>
changed from <em>sage-5.11</em> to <em>sage-5.12</em>
</li>
</ul>
TicketjdemeyerFri, 06 Dec 2013 14:13:44 GMTdescription changed
https://trac.sagemath.org/ticket/13360#comment:20
https://trac.sagemath.org/ticket/13360#comment:20
<ul>
<li><strong>description</strong>
modified (<a href="/ticket/13360?action=diff&version=20">diff</a>)
</li>
</ul>
<p>
One problem with your solution 3) is that the symbolic polynomial is not given in expanded form. I'm wondering if there is a proper way to evaluate a polynomial at a symbolic argument and get the symbolic polynomial in expanded form. I don't want to use <code>expand()</code>, because maybe I only want to expand the polynomial, not the argument in case the argument is something complicated.
</p>
Ticketvbraun_spamThu, 30 Jan 2014 21:20:52 GMTmilestone changed
https://trac.sagemath.org/ticket/13360#comment:21
https://trac.sagemath.org/ticket/13360#comment:21
<ul>
<li><strong>milestone</strong>
changed from <em>sage-6.1</em> to <em>sage-6.2</em>
</li>
</ul>
TicketrwsThu, 03 Apr 2014 08:53:08 GMTstatus changed; work_issues set
https://trac.sagemath.org/ticket/13360#comment:22
https://trac.sagemath.org/ticket/13360#comment:22
<ul>
<li><strong>status</strong>
changed from <em>needs_review</em> to <em>needs_work</em>
</li>
<li><strong>work_issues</strong>
set to <em>address review</em>
</li>
</ul>
Ticketvbraun_spamTue, 06 May 2014 15:20:58 GMTmilestone changed
https://trac.sagemath.org/ticket/13360#comment:23
https://trac.sagemath.org/ticket/13360#comment:23
<ul>
<li><strong>milestone</strong>
changed from <em>sage-6.2</em> to <em>sage-6.3</em>
</li>
</ul>
TicketrwsThu, 05 Jun 2014 15:12:16 GMT
https://trac.sagemath.org/ticket/13360#comment:24
https://trac.sagemath.org/ticket/13360#comment:24
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/13360#comment:17" title="Comment 17">novoselt</a>:
</p>
<blockquote class="citation">
<p>
By the way, I think that this is a bug:
</p>
<pre class="wiki">sage: QQ["t"]["t"]
Univariate Polynomial Ring in t over Univariate Polynomial Ring in t over Rational Field
</pre></blockquote>
<p>
This is now <a class="new ticket" href="https://trac.sagemath.org/ticket/16447" title="defect: do not use identical var names when constructing rings (new)">#16447</a>
</p>
Ticketvbraun_spamSun, 10 Aug 2014 16:51:03 GMTmilestone changed
https://trac.sagemath.org/ticket/13360#comment:25
https://trac.sagemath.org/ticket/13360#comment:25
<ul>
<li><strong>milestone</strong>
changed from <em>sage-6.3</em> to <em>sage-6.4</em>
</li>
</ul>
Ticket