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.Mon, 28 Feb 2011 19:49:16 +0100substituting expressions for numbershttps://ask.sagemath.org/question/7975/substituting-expressions-for-numbers/Say you have some formula in the form of an expression:
sage: x,y,a,b = var("x y a b")
sage: f = 10*x+2*y
sage: type(f)
<type 'sage.symbolic.expression.Expression'>
Now I want to replace the 10 by the variable a. What's the easiest
way to do this? It's the opposite of the typical substitution, so the functions
I'd usually throw at it all fail.
So far I can only up with (1) string techniques, which are bugs
waiting to happen, or (2) walking the entire expression tree and
constructing a new expression from each operator/operand triplet.
Mon, 28 Feb 2011 02:30:23 +0100https://ask.sagemath.org/question/7975/substituting-expressions-for-numbers/Answer by DSM for <p>Say you have some formula in the form of an expression:</p>
<pre><code>sage: x,y,a,b = var("x y a b")
sage: f = 10*x+2*y
sage: type(f)
<type 'sage.symbolic.expression.Expression'>
</code></pre>
<p>Now I want to replace the 10 by the variable a. What's the easiest
way to do this? It's the opposite of the typical substitution, so the functions
I'd usually throw at it all fail. </p>
<p>So far I can only up with (1) string techniques, which are bugs
waiting to happen, or (2) walking the entire expression tree and
constructing a new expression from each operator/operand triplet.</p>
https://ask.sagemath.org/question/7975/substituting-expressions-for-numbers/?answer=12155#post-id-12155So that this is recorded somewhere, here's the simplest way I found (thanks @kcrisman-- I always forget that we can access maxima functionality). It turns out maxima's subst is pretty powerful:
<pre><code>sage: var("x a")
(x, a)
sage: f = 10*x+3
sage: f
10*x + 3
sage: maxima.subst(a, 10, f).sage()
a*x + 3
</code></pre>
but then you have to live with any changes induced on the trip, whereas with Mike's solution you don't have to worry about that, and you can replace the "==" comparison by something which is as finely-tuned as you want.
I'd like f.subs({10:a}) to work, but I get lost in the code as soon as _gobjs start showing up..Mon, 28 Feb 2011 19:35:01 +0100https://ask.sagemath.org/question/7975/substituting-expressions-for-numbers/?answer=12155#post-id-12155Answer by kcrisman for <p>Say you have some formula in the form of an expression:</p>
<pre><code>sage: x,y,a,b = var("x y a b")
sage: f = 10*x+2*y
sage: type(f)
<type 'sage.symbolic.expression.Expression'>
</code></pre>
<p>Now I want to replace the 10 by the variable a. What's the easiest
way to do this? It's the opposite of the typical substitution, so the functions
I'd usually throw at it all fail. </p>
<p>So far I can only up with (1) string techniques, which are bugs
waiting to happen, or (2) walking the entire expression tree and
constructing a new expression from each operator/operand triplet.</p>
https://ask.sagemath.org/question/7975/substituting-expressions-for-numbers/?answer=12150#post-id-12150Yikes! I assume you are doing an explicit example and now want to generalize.
Sorry, I think you will have to walk the expression tree. Hopefully I am wrong, but Sage just doesn't have methods for this built in yet. I don't even know that Maxima does. Axiom/Fricas might be more along those lines, I don't know. Honestly, I'd probably even do a string thing, as long as I could watch it step by step - like in a text editor - to make sure I wasn't making any erroneous replacements.Mon, 28 Feb 2011 10:44:56 +0100https://ask.sagemath.org/question/7975/substituting-expressions-for-numbers/?answer=12150#post-id-12150Comment by DSM for <p>Yikes! I assume you are doing an explicit example and now want to generalize. </p>
<p>Sorry, I think you will have to walk the expression tree. Hopefully I am wrong, but Sage just doesn't have methods for this built in yet. I don't even know that Maxima does. Axiom/Fricas might be more along those lines, I don't know. Honestly, I'd probably even do a string thing, as long as I could watch it step by step - like in a text editor - to make sure I wasn't making any erroneous replacements.</p>
https://ask.sagemath.org/question/7975/substituting-expressions-for-numbers/?comment=22042#post-id-22042That was exactly the cause: there was a specific troublesome function and I wanted to see if I could find a smaller example when I realized I didn't know how..Mon, 28 Feb 2011 19:37:55 +0100https://ask.sagemath.org/question/7975/substituting-expressions-for-numbers/?comment=22042#post-id-22042Answer by Mike Hansen for <p>Say you have some formula in the form of an expression:</p>
<pre><code>sage: x,y,a,b = var("x y a b")
sage: f = 10*x+2*y
sage: type(f)
<type 'sage.symbolic.expression.Expression'>
</code></pre>
<p>Now I want to replace the 10 by the variable a. What's the easiest
way to do this? It's the opposite of the typical substitution, so the functions
I'd usually throw at it all fail. </p>
<p>So far I can only up with (1) string techniques, which are bugs
waiting to happen, or (2) walking the entire expression tree and
constructing a new expression from each operator/operand triplet.</p>
https://ask.sagemath.org/question/7975/substituting-expressions-for-numbers/?answer=12152#post-id-12152If you don't want to use strings, then I think you do have to walk the expression tree at the moment. Sage does come with some tools to help with this in `sage.symbolic.expression_conversions`, but they could be improved. For example, something like the following should be added to the Sage library:
from sage.symbolic.expression_conversions import Converter
class DoNothing(Converter):
def arithmetic(self, ex, operator):
return reduce(operator, map(self, ex.operands()))
def pyobject(self, ex, obj):
return ex
def symbol(self, ex):
return ex
def relation(self, ex, operator):
return operator(*map(self, ex.operands()))
def derivative(self, ex, operator):
#We'll just ignore this for now
return ex
def composition(self, ex, operator):
return operator(*map(self, ex.operands()))
Then,
sage: f = 10*x + 3
sage: d = DoNothing()
sage: d(f)
10*x + 3
With this little utility class in place, you can write:
class TenReplacer(DoNothing):
def pyobject(self, ex, obj):
return 99 if obj == 10 else obj
and have
sage: f = 10*x + 3
sage: t = TenReplacer()
sage: t(f)
99*x + 3
sage: t(f == 10)
99*x + 3 == 99
sage: t(f == 100)
99*x + 3 == 100Mon, 28 Feb 2011 11:26:39 +0100https://ask.sagemath.org/question/7975/substituting-expressions-for-numbers/?answer=12152#post-id-12152Comment by kcrisman for <p>If you don't want to use strings, then I think you do have to walk the expression tree at the moment. Sage does come with some tools to help with this in <code>sage.symbolic.expression_conversions</code>, but they could be improved. For example, something like the following should be added to the Sage library:</p>
<pre><code>from sage.symbolic.expression_conversions import Converter
class DoNothing(Converter):
def arithmetic(self, ex, operator):
return reduce(operator, map(self, ex.operands()))
def pyobject(self, ex, obj):
return ex
def symbol(self, ex):
return ex
def relation(self, ex, operator):
return operator(*map(self, ex.operands()))
def derivative(self, ex, operator):
#We'll just ignore this for now
return ex
def composition(self, ex, operator):
return operator(*map(self, ex.operands()))
</code></pre>
<p>Then,</p>
<pre><code>sage: f = 10*x + 3
sage: d = DoNothing()
sage: d(f)
10*x + 3
</code></pre>
<p>With this little utility class in place, you can write:</p>
<pre><code>class TenReplacer(DoNothing):
def pyobject(self, ex, obj):
return 99 if obj == 10 else obj
</code></pre>
<p>and have</p>
<pre><code>sage: f = 10*x + 3
sage: t = TenReplacer()
sage: t(f)
99*x + 3
sage: t(f == 10)
99*x + 3 == 99
sage: t(f == 100)
99*x + 3 == 100
</code></pre>
https://ask.sagemath.org/question/7975/substituting-expressions-for-numbers/?comment=22045#post-id-22045That is pretty cool. If you open a ticket for this, please copy me. I sadly don't understand quite enough about how this works yet to contribute to it, but could help review. Walking expression trees is a constant support request, so this would be great. If that's what this does?Mon, 28 Feb 2011 14:13:21 +0100https://ask.sagemath.org/question/7975/substituting-expressions-for-numbers/?comment=22045#post-id-22045Comment by DSM for <p>If you don't want to use strings, then I think you do have to walk the expression tree at the moment. Sage does come with some tools to help with this in <code>sage.symbolic.expression_conversions</code>, but they could be improved. For example, something like the following should be added to the Sage library:</p>
<pre><code>from sage.symbolic.expression_conversions import Converter
class DoNothing(Converter):
def arithmetic(self, ex, operator):
return reduce(operator, map(self, ex.operands()))
def pyobject(self, ex, obj):
return ex
def symbol(self, ex):
return ex
def relation(self, ex, operator):
return operator(*map(self, ex.operands()))
def derivative(self, ex, operator):
#We'll just ignore this for now
return ex
def composition(self, ex, operator):
return operator(*map(self, ex.operands()))
</code></pre>
<p>Then,</p>
<pre><code>sage: f = 10*x + 3
sage: d = DoNothing()
sage: d(f)
10*x + 3
</code></pre>
<p>With this little utility class in place, you can write:</p>
<pre><code>class TenReplacer(DoNothing):
def pyobject(self, ex, obj):
return 99 if obj == 10 else obj
</code></pre>
<p>and have</p>
<pre><code>sage: f = 10*x + 3
sage: t = TenReplacer()
sage: t(f)
99*x + 3
sage: t(f == 10)
99*x + 3 == 99
sage: t(f == 100)
99*x + 3 == 100
</code></pre>
https://ask.sagemath.org/question/7975/substituting-expressions-for-numbers/?comment=22041#post-id-22041Nice. Expression hacking is too handy not to have better support; maybe Expressions should grow some more methods to handle common cases? Even a convert-to/from-sequence representation method would have made a question a while back a two-liner. I still can't help feeling that .subs({10:a}) should Just Work, though.Mon, 28 Feb 2011 19:49:16 +0100https://ask.sagemath.org/question/7975/substituting-expressions-for-numbers/?comment=22041#post-id-22041