Sage: Ticket #14630: Add `simplify_real` method to symbolic expressions
https://trac.sagemath.org/ticket/14630
<p>
Symbolic expressions in sage are by default assumed complex. There is a maxima variable, called the "simplification domain," which affects whether or not it simplifies <code>sqrt(x^2)</code> to <code>abs(x)</code>. Since our expressions are complex, we set the simplification domain to complex, but provide no easy way to change it.
</p>
<p>
By adding a <code>simplify_real()</code> method to Expression, we give the user a way to perform the aforementioned simplification by declaring his expression real.
</p>
<p>
This might provide a quick fix for <a class="closed ticket" href="https://trac.sagemath.org/ticket/14305" title="defect: Doctest: Immediate simplifications of symbolic powers (closed: fixed)">#14305</a>. See also:
</p>
<p>
<a class="ext-link" href="https://groups.google.com/forum/?fromgroups=#!topic/sage-support/jhCJujRtNA4/discussion"><span class="icon"></span>https://groups.google.com/forum/?fromgroups=#!topic/sage-support/jhCJujRtNA4/discussion</a>
</p>
en-usSagehttps://trac.sagemath.org/chrome/site/logo_sagemath_trac.png
https://trac.sagemath.org/ticket/14630
Trac 1.1.6mjoThu, 23 May 2013 00:53:04 GMTstatus changed; author set
https://trac.sagemath.org/ticket/14630#comment:1
https://trac.sagemath.org/ticket/14630#comment:1
<ul>
<li><strong>status</strong>
changed from <em>new</em> to <em>needs_review</em>
</li>
<li><strong>author</strong>
set to <em>Michael Orlitzky</em>
</li>
</ul>
<p>
MathJAX is throwing a "Math Processing Error" -- I'm not sure whether it's busted or I screwed up but the docs definitely need a review.
</p>
TicketkcrismanThu, 23 May 2013 12:56:32 GMT
https://trac.sagemath.org/ticket/14630#comment:2
https://trac.sagemath.org/ticket/14630#comment:2
<p>
You need to do <code>\left|x\\right|</code>.
</p>
<hr />
<p>
I'm not sure about all the stuff in the doc and the code, but I think that some of the doc is doing the code and vice versa? For instance,
</p>
<pre class="wiki"># Forget all assumptions
</pre><p>
but you don't do that in the code. And the corresponding part in the doc seems to imply that in order to use <code>simplify_real</code> you have to assume variables are real... I may be misunderstanding something here. I think this could be a good way to solve the issue at hand.
</p>
<p>
My question is how this will interact with the other simplifications. I seem to recall that in some of the more controversial (e.g. <code>radcan</code>-related) simplifications we do, part of the issue is whether the variable is real... that recollection may be outdated. Anyway, I could imagine that <code>simplify_foo</code> simplified differently whether one was real or complex, though I hesitate to add <code>simplify_foo_real</code> for all <code>foo</code>!
</p>
TicketmjoFri, 24 May 2013 23:42:10 GMTattachment set
https://trac.sagemath.org/ticket/14630
https://trac.sagemath.org/ticket/14630
<ul>
<li><strong>attachment</strong>
set to <em>sage-trac_14630.patch</em>
</li>
</ul>
<p>
Add simplify_real() method to Expression
</p>
TicketmjoSat, 25 May 2013 00:02:29 GMT
https://trac.sagemath.org/ticket/14630#comment:3
https://trac.sagemath.org/ticket/14630#comment:3
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/14630#comment:2" title="Comment 2">kcrisman</a>:
</p>
<blockquote class="citation">
<p>
You need to do <code>\left|x\\right|</code>.
</p>
</blockquote>
<p>
<br />
</p>
<p>
Fixed in the new patch, but my MathJAX still doesn't work, so please give it a look.
</p>
<p>
<br />
</p>
<blockquote class="citation">
<p>
I'm not sure about all the stuff in the doc and the code, but I think that some of the doc is doing the code and vice versa? For instance,
</p>
<pre class="wiki"># Forget all assumptions
</pre><p>
but you don't do that in the code.
</p>
</blockquote>
<p>
<br />
</p>
<p>
Whoops, I forgot to call <code>forget()</code>; the comment was correct. I fixed it and added a doctest to ensure that no new assumptions remain after the call.
</p>
<p>
<br />
</p>
<blockquote class="citation">
<p>
And the corresponding part in the doc seems to imply that in order to use <code>simplify_real</code> you have to assume variables are real... I may be misunderstanding something here. I think this could be a good way to solve the issue at hand.
</p>
</blockquote>
<p>
<br />
</p>
<p>
I didn't mean that the user has to <code>assume()</code> anything, only that we have to assume things are real in the traditional sense. You can call <code>simplify_real()</code> on an expression containing complex variables, but the answer might not make sense.
</p>
<p>
<br />
</p>
<blockquote class="citation">
<p>
My question is how this will interact with the other simplifications. I seem to recall that in some of the more controversial (e.g. <code>radcan</code>-related) simplifications we do, part of the issue is whether the variable is real... that recollection may be outdated. Anyway, I could imagine that <code>simplify_foo</code> simplified differently whether one was real or complex, though I hesitate to add <code>simplify_foo_real</code> for all <code>foo</code>!
</p>
</blockquote>
<p>
<br />
</p>
<p>
Expressions <em>should</em> be complex everywhere. I believe there are one or two functions which treat them as real, but they're documented to do that, so it's fine. Radcan via <code>simplify_radical()</code> will still produce crazy answers that are invalid for complex numbers, but there isn't much that can be done about that now except revoke the name "simplify" from "simplify_radical."
</p>
<p>
Not many expressions are actually affected by the domain and 'real' assumptions. We can get most of the benefit of <code>simplify_foo_real()</code> by doing <code>simplify_foo().simplify_real()</code>. Simplifications can be combined/repeated to produce better answers, and we already have a situation where calling e.g. <code>simplify_full()</code> twice might give you a better answer than calling it once. So you're kind of on your own regarding how many simplifications to try and in what order.
</p>
TicketslutherWed, 29 May 2013 13:44:49 GMT
https://trac.sagemath.org/ticket/14630#comment:4
https://trac.sagemath.org/ticket/14630#comment:4
<p>
What about adding a parameter to all the simplify_* functions instead of adding more functions?
Like "def simplify(real_domain=False):..."
</p>
TicketmjoThu, 30 May 2013 17:52:07 GMT
https://trac.sagemath.org/ticket/14630#comment:5
https://trac.sagemath.org/ticket/14630#comment:5
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/14630#comment:4" title="Comment 4">sluther</a>:
</p>
<blockquote class="citation">
<p>
What about adding a parameter to all the simplify_* functions instead of adding more functions?
Like "def simplify(real_domain=False):..."
</p>
</blockquote>
<p>
If instead of <code>simplify_rational</code>, <code>simplify_log</code>, etc. we had <code>simplify(rational=True, log=True,...)</code> that's what I would have done. As it is, if you want to do both rational and log simplifications, you just have to do <code>expr.simplify_rational().simplify_log()</code>.
</p>
<p>
Particularly with <code>simplify_real()</code>, it only does one specific thing that isn't done by other methods so you can be somewhat confident that <code>simplify_foo().simplify_real()</code> will give you both simplifications. In other words I don't think you'd get a nicer expression back by setting the simplification domain to real before <code>simplify_rational()</code> than you would by calling the two in succession.
</p>
TicketslutherThu, 30 May 2013 19:38:24 GMT
https://trac.sagemath.org/ticket/14630#comment:6
https://trac.sagemath.org/ticket/14630#comment:6
<p>
Well I'd say this feels like mixing different concepts. The log, radical, etc. are about the form of the expression that's going to be transformed, whereas the domain is about the values the variables in the expression may take.
</p>
<p>
You're right that sometimes the application of simplifications in different order yields different results. But I find this rather annoying (not that I know how to fix it). By adding even more functions to the mix we make this situation even worse.
</p>
<p>
I usually use simplify_full(). So as I understand it I'd always need to call simplify_full() and simplify_real() in some order to benefit from the knowledge about the domain.
</p>
<p>
And then I'm still left wondering if there are simplifications in simplify_full() hat could benefit from this knowledge too, but didn't get it because there's only simplify_real() and not simplify_full_real().
</p>
<p>
Is there a list of which simplify_* function could use this domain parameter?
</p>
TicketburcinThu, 30 May 2013 19:57:04 GMT
https://trac.sagemath.org/ticket/14630#comment:7
https://trac.sagemath.org/ticket/14630#comment:7
<p>
Instead of adding a new function <code>simplify_real()</code> or a <code>domain</code> parameter to the existing functions, can we use a context manager instead?
</p>
<p>
Example use would be:
</p>
<pre class="wiki">sage: t = sqrt(x^2)
sage: t.simplify()
sqrt(x^2)
sage: with maxima_domain(RR):
....: u = t.simplify()
....:
sage: u
abs(x)
sage: t.simplify()
sqrt(x^2)
</pre>
TicketmjoTue, 04 Jun 2013 02:51:15 GMT
https://trac.sagemath.org/ticket/14630#comment:8
https://trac.sagemath.org/ticket/14630#comment:8
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/14630#comment:6" title="Comment 6">sluther</a>:
</p>
<p>
All of the <code>simplify_foo()</code> functions except <code>simplify_radical()</code> could benefit from it. There are only a small number of subexpressions that can be simplified by <code>simplify_real()</code>, and I think only <code>simplify_radical()</code> will "simplify" out those subexpressions making <code>simplify_real()</code> redundant.
</p>
<p>
The <code>simplify_radical()</code> method will change the expression <code>sqrt(x^2)</code> to either <code>x</code> or <code>-x</code> "consistently but arbitrarily.". This is not really a simplification, since it gives the wrong answer in the default case, so beware using <code>simplify_full()</code>. All of the rest could be combined with <code>simplify_real()</code> in some way.
</p>
TicketmjoTue, 04 Jun 2013 02:56:49 GMT
https://trac.sagemath.org/ticket/14630#comment:9
https://trac.sagemath.org/ticket/14630#comment:9
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/14630#comment:7" title="Comment 7">burcin</a>:
</p>
<blockquote class="citation">
<p>
Instead of adding a new function <code>simplify_real()</code> or a <code>domain</code> parameter to the existing functions, can we use a context manager instead?
</p>
<p>
Example use would be:
</p>
<pre class="wiki">sage: t = sqrt(x^2)
sage: t.simplify()
sqrt(x^2)
sage: with maxima_domain(RR):
....: u = t.simplify()
....:
sage: u
abs(x)
sage: t.simplify()
sqrt(x^2)
</pre></blockquote>
<p>
This is way better than what we currently have to do:
</p>
<pre class="wiki">sage: maxima_lib.eval('domain: real;')
'real'
sage: (sqrt(x^2)).simplify()
abs(x)
sage: maxima_lib.eval('domain: complex;')
'complex'
</pre><p>
but still does two things undesirably:
</p>
<ol><li>The user has to know about the maxima_domain() call, and there's no easy way to find out about it. This is in contrast with <code>x.<tab></code> "what can I do with this expression?"
</li></ol><ol start="2"><li>It ties the simplification to the maxima backend. If we ever want to use sympy or some other backend, we're going to have a mess.
</li></ol>
TicketjdemeyerTue, 13 Aug 2013 15:35:53 GMTmilestone changed
https://trac.sagemath.org/ticket/14630#comment:10
https://trac.sagemath.org/ticket/14630#comment:10
<ul>
<li><strong>milestone</strong>
changed from <em>sage-5.11</em> to <em>sage-5.12</em>
</li>
</ul>
TicketnbruinFri, 23 Aug 2013 16:23:25 GMT
https://trac.sagemath.org/ticket/14630#comment:11
https://trac.sagemath.org/ticket/14630#comment:11
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/14630#comment:7" title="Comment 7">burcin</a>:
</p>
<blockquote class="citation">
<p>
Instead of adding a new function <code>simplify_real()</code> or a <code>domain</code> parameter to the existing functions, can we use a context manager instead?
</p>
</blockquote>
<p>
You'd need to document that the user of the context manager should make sure to not relinquish control inside the context manager. Thanks to "yield" in python, lexical enclosure doesn't necessarily mean runtime enclosure.
</p>
Ticketvbraun_spamThu, 30 Jan 2014 21:20:52 GMTmilestone changed
https://trac.sagemath.org/ticket/14630#comment:12
https://trac.sagemath.org/ticket/14630#comment:12
<ul>
<li><strong>milestone</strong>
changed from <em>sage-6.1</em> to <em>sage-6.2</em>
</li>
</ul>
Ticketvbraun_spamTue, 06 May 2014 15:20:58 GMTmilestone changed
https://trac.sagemath.org/ticket/14630#comment:13
https://trac.sagemath.org/ticket/14630#comment:13
<ul>
<li><strong>milestone</strong>
changed from <em>sage-6.2</em> to <em>sage-6.3</em>
</li>
</ul>
Ticketvbraun_spamSun, 10 Aug 2014 16:51:03 GMTmilestone changed
https://trac.sagemath.org/ticket/14630#comment:14
https://trac.sagemath.org/ticket/14630#comment:14
<ul>
<li><strong>milestone</strong>
changed from <em>sage-6.3</em> to <em>sage-6.4</em>
</li>
</ul>
TicketrwsSun, 02 Nov 2014 09:05:57 GMTstatus changed
https://trac.sagemath.org/ticket/14630#comment:15
https://trac.sagemath.org/ticket/14630#comment:15
<ul>
<li><strong>status</strong>
changed from <em>needs_review</em> to <em>needs_info</em>
</li>
</ul>
<p>
I think the form/domain-simplify design issue has not been resolved and should be discussed/decided first: the/an author may benefit from presenting a solution to sage-devel, and if the crowd has no opinion then it should be implemented. Thus, I'm setting to needs_info.
</p>
TicketegourgoulhonWed, 05 Nov 2014 07:17:47 GMTcc set
https://trac.sagemath.org/ticket/14630#comment:16
https://trac.sagemath.org/ticket/14630#comment:16
<ul>
<li><strong>cc</strong>
<em>egourgoulhon</em> added
</li>
</ul>
TicketmjoWed, 05 Nov 2014 19:04:58 GMTcommit, branch set
https://trac.sagemath.org/ticket/14630#comment:17
https://trac.sagemath.org/ticket/14630#comment:17
<ul>
<li><strong>commit</strong>
set to <em>24cc55466abd2f02a9187186364fb4373d7900e9</em>
</li>
<li><strong>branch</strong>
set to <em>u/mjo/ticket/14630</em>
</li>
</ul>
<p>
New commits:
</p>
<table class="wiki">
<tr><td><a class="ext-link" href="http://git.sagemath.org/sage.git/commit/?id=24cc55466abd2f02a9187186364fb4373d7900e9"><span class="icon"></span>24cc554</a></td><td><code>Trac #14630: Add Expression.simplify_real() method.</code>
</td></tr></table>
TicketkcrismanTue, 18 Nov 2014 03:35:06 GMT
https://trac.sagemath.org/ticket/14630#comment:18
https://trac.sagemath.org/ticket/14630#comment:18
<p>
This seems fine, given that it is extremely unlikely a context manager will appear and that having many options seems undesirable. However, if someone gets a sage-devel discussion on this going I'm not going to stop them.
</p>
<pre class="wiki">sage: A = e^(sqrt(x^2))
sage: A
e^(sqrt(x^2))
sage: A.simplify_real()
e^abs(x)
</pre><p>
I was pleased this worked, wasn't sure how much it would do. Maybe the following would be a useful test to show what it does and doesn't do.
</p>
<pre class="wiki">sage: var('y z')
(y, z)
sage: A = e^(sqrt(x^2)+sqrt(y^2)+sqrt(i*z^2))
sage: A.simplify_real()
e^((-1)^(1/4)*abs(z) + abs(x) + abs(y))
</pre><p>
Here's another one that, again, pleasantly works as one would think.
</p>
<pre class="wiki">sage: C = (x^2+y^2).imag()
sage: C
2*imag_part(x)*real_part(x) + 2*imag_part(y)*real_part(y)
sage: C.simplify_real()
0
</pre><p>
Now if only we <em>had</em> to use this for the following simplification!
</p>
<pre class="wiki">sage: B = conjugate(z)
sage: B.simplify_real()
z
sage: B.simplify() # wa-wa "you lose" noise - #6862
z
</pre>
TicketkcrismanTue, 18 Nov 2014 03:38:54 GMT
https://trac.sagemath.org/ticket/14630#comment:19
https://trac.sagemath.org/ticket/14630#comment:19
<p>
Also note this probably conflicts slightly with <a class="closed ticket" href="https://trac.sagemath.org/ticket/11912" title="enhancement: Clarify simplify_radical and Maxima's radcan (closed: fixed)">#11912</a>.
</p>
TicketmjoTue, 18 Nov 2014 16:57:45 GMT
https://trac.sagemath.org/ticket/14630#comment:20
https://trac.sagemath.org/ticket/14630#comment:20
<p>
Just making a note to myself here to update all of the "see also" references in the other <code>simplify_*</code> methods. We should mention <code>simplify_real()</code>, <code>simplify_rectform()</code>, and any other new similar methods.
</p>
TicketgitSat, 22 Nov 2014 14:57:49 GMTcommit changed
https://trac.sagemath.org/ticket/14630#comment:21
https://trac.sagemath.org/ticket/14630#comment:21
<ul>
<li><strong>commit</strong>
changed from <em>24cc55466abd2f02a9187186364fb4373d7900e9</em> to <em>612f8ede28c281e6e5f4bb0e3864ca35ff3906c3</em>
</li>
</ul>
<p>
Branch pushed to git repo; I updated commit sha1. This was a forced push. New commits:
</p>
<table class="wiki">
<tr><td><a class="ext-link" href="http://git.sagemath.org/sage.git/commit/?id=f34ddfc2e47508ebc2323e347739f18000c15717"><span class="icon"></span>f34ddfc</a></td><td><code>Trac #11912: Rename and deprecate Expression.simplify_radical().</code>
</td></tr><tr><td><a class="ext-link" href="http://git.sagemath.org/sage.git/commit/?id=2d50b886561b9cc98585749b6292eaba269da73c"><span class="icon"></span>2d50b88</a></td><td><code>Trac #11912, Trac #3520: Add numerical integral example.</code>
</td></tr><tr><td><a class="ext-link" href="http://git.sagemath.org/sage.git/commit/?id=e5ab33994355520f0f27914f73f1680292eadc3d"><span class="icon"></span>e5ab339</a></td><td><code>Trac #11912 (review): Remove superfluous documentation paragraph.</code>
</td></tr><tr><td><a class="ext-link" href="http://git.sagemath.org/sage.git/commit/?id=5d24f4c71b07beef87cc6b27df7f7cc37c29071e"><span class="icon"></span>5d24f4c</a></td><td><code>Trac #11912 (review): Add canonicalize_radical() to the "see also" list for Expression.simplify().</code>
</td></tr><tr><td><a class="ext-link" href="http://git.sagemath.org/sage.git/commit/?id=612f8ede28c281e6e5f4bb0e3864ca35ff3906c3"><span class="icon"></span>612f8ed</a></td><td><code>Trac #14630: Add Expression.simplify_real() method.</code>
</td></tr></table>
TicketmjoSat, 22 Nov 2014 15:00:28 GMTstatus changed; dependencies set
https://trac.sagemath.org/ticket/14630#comment:22
https://trac.sagemath.org/ticket/14630#comment:22
<ul>
<li><strong>status</strong>
changed from <em>needs_info</em> to <em>needs_review</em>
</li>
<li><strong>dependencies</strong>
set to <em>#11912</em>
</li>
</ul>
<p>
I just force-pushed a branch that's rebased on top of <a class="closed ticket" href="https://trac.sagemath.org/ticket/11912" title="enhancement: Clarify simplify_radical and Maxima's radcan (closed: fixed)">#11912</a> because of a conflict. That one has a positive review, so I guess when it's merged I could rebase this on top of the develop branch? Not sure what's easiest for the release manager.
</p>
TicketgitSat, 22 Nov 2014 15:09:16 GMTcommit changed
https://trac.sagemath.org/ticket/14630#comment:23
https://trac.sagemath.org/ticket/14630#comment:23
<ul>
<li><strong>commit</strong>
changed from <em>612f8ede28c281e6e5f4bb0e3864ca35ff3906c3</em> to <em>649e3b3eece6daea3d3c043d2034f3416a85fb09</em>
</li>
</ul>
<p>
Branch pushed to git repo; I updated commit sha1. New commits:
</p>
<table class="wiki">
<tr><td><a class="ext-link" href="http://git.sagemath.org/sage.git/commit/?id=649e3b3eece6daea3d3c043d2034f3416a85fb09"><span class="icon"></span>649e3b3</a></td><td><code>Trac #14630: Add Expression.simplify_hypergeometric() to the "see also" list for Expression.simplify().</code>
</td></tr></table>
TicketmjoSat, 22 Nov 2014 15:10:11 GMT
https://trac.sagemath.org/ticket/14630#comment:24
https://trac.sagemath.org/ticket/14630#comment:24
<p>
And per my note, I've included another left-out function in the <code>simplify()</code> "see also" list.
</p>
TicketrwsFri, 12 Dec 2014 16:38:37 GMTstatus changed; reviewer set
https://trac.sagemath.org/ticket/14630#comment:25
https://trac.sagemath.org/ticket/14630#comment:25
<ul>
<li><strong>status</strong>
changed from <em>needs_review</em> to <em>positive_review</em>
</li>
<li><strong>reviewer</strong>
set to <em>Karl-Dieter Crisman, Ralf Stephan</em>
</li>
</ul>
<p>
I think it is fine now and certainly should be included, test pass in <code>expression.pyx</code>.
</p>
TicketvbraunMon, 15 Dec 2014 17:50:53 GMTstatus, branch changed; resolution set
https://trac.sagemath.org/ticket/14630#comment:26
https://trac.sagemath.org/ticket/14630#comment:26
<ul>
<li><strong>status</strong>
changed from <em>positive_review</em> to <em>closed</em>
</li>
<li><strong>resolution</strong>
set to <em>fixed</em>
</li>
<li><strong>branch</strong>
changed from <em>u/mjo/ticket/14630</em> to <em>649e3b3eece6daea3d3c043d2034f3416a85fb09</em>
</li>
</ul>
Ticket