ASKSAGE: Sage Q&A Forum - RSS feedhttps://ask.sagemath.org/questions/Q&A Forum for SageenCopyright Sage, 2010. Some rights reserved under creative commons license.Wed, 19 Apr 2017 18:52:52 +0200Why does simplify break print_latex_func?https://ask.sagemath.org/question/37328/why-does-simplify-break-print_latex_func/Here's a minimal example of what I am talking about. Both print statements should return the same output in this scenario.
,var n x
def my_latex_print(self, *args):
return "a_{%s}" %(', '.join(map(latex, args)))
a=function('a',nargs=1,print_latex_func=my_latex_print)(n)
sexp=a(n=n+1)+a(n=n)
print latex(sexp)
sexp=simplify(expand(sexp))
print latex(sexp)
However, the outputs differ:
a_{n + 1} + a_{n}
a\left(n + 1\right) + a\left(n\right)
Of course simplify-expand may lead to a different expression, but that's not what I am concerned about. I am concerned about the representation of `a(n)` instead of `a_n` in the output.
My main question is: How can I recover `a_n` out of `sexp` at the end of my code?Wed, 19 Apr 2017 04:17:36 +0200https://ask.sagemath.org/question/37328/why-does-simplify-break-print_latex_func/Comment by Björn for <p>Here's a minimal example of what I am talking about. Both print statements should return the same output in this scenario.</p>
<pre><code>,var n x
def my_latex_print(self, *args):
return "a_{%s}" %(', '.join(map(latex, args)))
a=function('a',nargs=1,print_latex_func=my_latex_print)(n)
sexp=a(n=n+1)+a(n=n)
print latex(sexp)
sexp=simplify(expand(sexp))
print latex(sexp)
</code></pre>
<p>However, the outputs differ:</p>
<pre><code>a_{n + 1} + a_{n}
a\left(n + 1\right) + a\left(n\right)
</code></pre>
<p>Of course simplify-expand may lead to a different expression, but that's not what I am concerned about. I am concerned about the representation of <code>a(n)</code> instead of <code>a_n</code> in the output. </p>
<p>My main question is: How can I recover <code>a_n</code> out of <code>sexp</code> at the end of my code?</p>
https://ask.sagemath.org/question/37328/why-does-simplify-break-print_latex_func/?comment=37331#post-id-37331I know it is `simplify()` and not `expand()` that causes the problem. But why and how?Wed, 19 Apr 2017 13:50:49 +0200https://ask.sagemath.org/question/37328/why-does-simplify-break-print_latex_func/?comment=37331#post-id-37331Answer by kcrisman for <p>Here's a minimal example of what I am talking about. Both print statements should return the same output in this scenario.</p>
<pre><code>,var n x
def my_latex_print(self, *args):
return "a_{%s}" %(', '.join(map(latex, args)))
a=function('a',nargs=1,print_latex_func=my_latex_print)(n)
sexp=a(n=n+1)+a(n=n)
print latex(sexp)
sexp=simplify(expand(sexp))
print latex(sexp)
</code></pre>
<p>However, the outputs differ:</p>
<pre><code>a_{n + 1} + a_{n}
a\left(n + 1\right) + a\left(n\right)
</code></pre>
<p>Of course simplify-expand may lead to a different expression, but that's not what I am concerned about. I am concerned about the representation of <code>a(n)</code> instead of <code>a_n</code> in the output. </p>
<p>My main question is: How can I recover <code>a_n</code> out of <code>sexp</code> at the end of my code?</p>
https://ask.sagemath.org/question/37328/why-does-simplify-break-print_latex_func/?answer=37333#post-id-37333The issue is that `simplify` and `expand` send `sexp` to Maxima, which does not "know" about your custom print function. Then when it comes back to Sage it also doesn't know about it anymore. One way of slightly avoiding this is to call the new thing `sexp2`, though this doesn't solve the printing problem.
For that, you may have to somehow coerce the expression back to using your `a`, perhaps using `subs`.Wed, 19 Apr 2017 14:02:47 +0200https://ask.sagemath.org/question/37328/why-does-simplify-break-print_latex_func/?answer=37333#post-id-37333Comment by Björn for <p>The issue is that <code>simplify</code> and <code>expand</code> send <code>sexp</code> to Maxima, which does not "know" about your custom print function. Then when it comes back to Sage it also doesn't know about it anymore. One way of slightly avoiding this is to call the new thing <code>sexp2</code>, though this doesn't solve the printing problem.</p>
<p>For that, you may have to somehow coerce the expression back to using your <code>a</code>, perhaps using <code>subs</code>.</p>
https://ask.sagemath.org/question/37328/why-does-simplify-break-print_latex_func/?comment=37335#post-id-37335Aha, I see... At the end of the day I don't really mind Maxima, as long as I can coerce back, which I cannot seem to figure out how to achieve. Obvious (to me) candidates would seem to be `latex(sexp2.subs({a(n):a(n)}))` or even `latex(sexp2.subs({a: a}))`. But they do not work as expected or throw errors when I use keywords in combination with arguments to `a()`.
print sexp2.operands()[0].operator().__class__ # maxima a()
print a.__class__ # my a()
Reveals the functions `a()` are indeed different, the former `function_factory.NewSymbolicFunction`, the latter `expression.Expression`. Can't I just somehow retrospectively set the `print_latex_func` on the `function_factory.NewSymbolicFunction`?Wed, 19 Apr 2017 14:38:07 +0200https://ask.sagemath.org/question/37328/why-does-simplify-break-print_latex_func/?comment=37335#post-id-37335Comment by Björn for <p>The issue is that <code>simplify</code> and <code>expand</code> send <code>sexp</code> to Maxima, which does not "know" about your custom print function. Then when it comes back to Sage it also doesn't know about it anymore. One way of slightly avoiding this is to call the new thing <code>sexp2</code>, though this doesn't solve the printing problem.</p>
<p>For that, you may have to somehow coerce the expression back to using your <code>a</code>, perhaps using <code>subs</code>.</p>
https://ask.sagemath.org/question/37328/why-does-simplify-break-print_latex_func/?comment=37338#post-id-37338Not only that, to get the operator name, one somehow needs to find it by location in the sage expression, at least I am not aware of a better way to find a reference to the "maxima" a(). Maybe one could loop over all operators in the expression and somehow filter by a feature that identifies them as maxima operators... but that's messy.Wed, 19 Apr 2017 16:20:07 +0200https://ask.sagemath.org/question/37328/why-does-simplify-break-print_latex_func/?comment=37338#post-id-37338Comment by ndomes for <p>The issue is that <code>simplify</code> and <code>expand</code> send <code>sexp</code> to Maxima, which does not "know" about your custom print function. Then when it comes back to Sage it also doesn't know about it anymore. One way of slightly avoiding this is to call the new thing <code>sexp2</code>, though this doesn't solve the printing problem.</p>
<p>For that, you may have to somehow coerce the expression back to using your <code>a</code>, perhaps using <code>subs</code>.</p>
https://ask.sagemath.org/question/37328/why-does-simplify-break-print_latex_func/?comment=37337#post-id-37337Very tricky. But IMHO it is annoying that sending an expression through maxima results in two identically named but different functions, see:
print sexp2.operands()[0].operator().name()
print sexp2.operands()[0].operator() is aWed, 19 Apr 2017 16:07:36 +0200https://ask.sagemath.org/question/37328/why-does-simplify-break-print_latex_func/?comment=37337#post-id-37337Comment by ndomes for <p>The issue is that <code>simplify</code> and <code>expand</code> send <code>sexp</code> to Maxima, which does not "know" about your custom print function. Then when it comes back to Sage it also doesn't know about it anymore. One way of slightly avoiding this is to call the new thing <code>sexp2</code>, though this doesn't solve the printing problem.</p>
<p>For that, you may have to somehow coerce the expression back to using your <code>a</code>, perhaps using <code>subs</code>.</p>
https://ask.sagemath.org/question/37328/why-does-simplify-break-print_latex_func/?comment=37340#post-id-37340Looping over all operators:
f = copy(sexp2)
for x in f.operands():
f = f.substitute_function(x.operator(),sage_eval(x.operator().name(),locals=locals()))
sexp2 ; fWed, 19 Apr 2017 17:16:22 +0200https://ask.sagemath.org/question/37328/why-does-simplify-break-print_latex_func/?comment=37340#post-id-37340Comment by Björn for <p>The issue is that <code>simplify</code> and <code>expand</code> send <code>sexp</code> to Maxima, which does not "know" about your custom print function. Then when it comes back to Sage it also doesn't know about it anymore. One way of slightly avoiding this is to call the new thing <code>sexp2</code>, though this doesn't solve the printing problem.</p>
<p>For that, you may have to somehow coerce the expression back to using your <code>a</code>, perhaps using <code>subs</code>.</p>
https://ask.sagemath.org/question/37328/why-does-simplify-break-print_latex_func/?comment=37343#post-id-37343That's just perfect, thanks! `latex(sexp2), latex(f)` instead of `sexp2 ; f` really demonstrates the achievement of your recursive coercion. Very nice, I especially like that the code does not require a priori knowledge of the function to be substituted. This really should be built into sage's `simplify()` at the stage when it processes what comes back from maxima.Wed, 19 Apr 2017 18:52:52 +0200https://ask.sagemath.org/question/37328/why-does-simplify-break-print_latex_func/?comment=37343#post-id-37343Answer by Björn for <p>Here's a minimal example of what I am talking about. Both print statements should return the same output in this scenario.</p>
<pre><code>,var n x
def my_latex_print(self, *args):
return "a_{%s}" %(', '.join(map(latex, args)))
a=function('a',nargs=1,print_latex_func=my_latex_print)(n)
sexp=a(n=n+1)+a(n=n)
print latex(sexp)
sexp=simplify(expand(sexp))
print latex(sexp)
</code></pre>
<p>However, the outputs differ:</p>
<pre><code>a_{n + 1} + a_{n}
a\left(n + 1\right) + a\left(n\right)
</code></pre>
<p>Of course simplify-expand may lead to a different expression, but that's not what I am concerned about. I am concerned about the representation of <code>a(n)</code> instead of <code>a_n</code> in the output. </p>
<p>My main question is: How can I recover <code>a_n</code> out of <code>sexp</code> at the end of my code?</p>
https://ask.sagemath.org/question/37328/why-does-simplify-break-print_latex_func/?answer=37336#post-id-37336Thanks to kcrisman I figured the remaining bits out myself. Complete code as follows:
# [...]
print latex(sexp)
sexp2=simplify(sexp) # expand doesn't hurt it, so omit that
print latex(sexp2)
# observe they are different due to sexp2 being processed
# via Maxima, as explained by kcrisman
# maxima replaces a() by a new a() that doesn't have the
# print function:
print sexp2.operands()[0].operator().__class__ # maxima a()
print a.__class__ # the a() we have defined
# to coerce back, we need to replace the former by the latter:
print latex(sexp2.substitute_function(sexp2.operands()[0].operator(),a))
(And that does the intended.)Wed, 19 Apr 2017 15:15:37 +0200https://ask.sagemath.org/question/37328/why-does-simplify-break-print_latex_func/?answer=37336#post-id-37336Comment by kcrisman for <p>Thanks to kcrisman I figured the remaining bits out myself. Complete code as follows:</p>
<pre><code># [...]
print latex(sexp)
sexp2=simplify(sexp) # expand doesn't hurt it, so omit that
print latex(sexp2)
# observe they are different due to sexp2 being processed
# via Maxima, as explained by kcrisman
# maxima replaces a() by a new a() that doesn't have the
# print function:
print sexp2.operands()[0].operator().__class__ # maxima a()
print a.__class__ # the a() we have defined
# to coerce back, we need to replace the former by the latter:
print latex(sexp2.substitute_function(sexp2.operands()[0].operator(),a))
</code></pre>
<p>(And that does the intended.)</p>
https://ask.sagemath.org/question/37328/why-does-simplify-break-print_latex_func/?comment=37339#post-id-37339Very nice work - hope you don't mind I used my mighty powers to make this an answer and accept it for you, since you did the hard part!Wed, 19 Apr 2017 16:53:55 +0200https://ask.sagemath.org/question/37328/why-does-simplify-break-print_latex_func/?comment=37339#post-id-37339Comment by Björn for <p>Thanks to kcrisman I figured the remaining bits out myself. Complete code as follows:</p>
<pre><code># [...]
print latex(sexp)
sexp2=simplify(sexp) # expand doesn't hurt it, so omit that
print latex(sexp2)
# observe they are different due to sexp2 being processed
# via Maxima, as explained by kcrisman
# maxima replaces a() by a new a() that doesn't have the
# print function:
print sexp2.operands()[0].operator().__class__ # maxima a()
print a.__class__ # the a() we have defined
# to coerce back, we need to replace the former by the latter:
print latex(sexp2.substitute_function(sexp2.operands()[0].operator(),a))
</code></pre>
<p>(And that does the intended.)</p>
https://ask.sagemath.org/question/37328/why-does-simplify-break-print_latex_func/?comment=37342#post-id-37342I guess will have to live with that ;) Thanks again for giving me the starting point, there wasn't much left to do after that.Wed, 19 Apr 2017 18:46:17 +0200https://ask.sagemath.org/question/37328/why-does-simplify-break-print_latex_func/?comment=37342#post-id-37342