Ask Your Question

Is there a way to update an expression with new variable values?

asked 2013-05-03 13:02:11 -0500

Eviatar Bach gravatar image

updated 2014-11-10 09:28:44 -0500

tmonteil gravatar image

Is there a way to update an expression if the symbolic variables that it contains have been overwritten? For example,

sage: var('beta')
sage: eq = x == beta
sage: beta = 1
sage: eq
x == beta

Is there a way for it to change to x == 1? I wrote the following function to do this, but I wanted to know if something similar existed already.

def update(expr):
    return expr.subs(dict(zip(expr.variables(), map(lambda v:eval(str(v)), expr.variables()))))
edit retag flag offensive close merge delete

2 answers

Sort by ยป oldest newest most voted

answered 2013-05-09 04:29:07 -0500

niles gravatar image

The issue is that there is a difference between variables and "symbolic variables". A variable is a string of letters used to store some value. Every programming language has them. A "symbolic variable" is a Sage object that can be manipulated in certain ways. Just like other Sage objects, symbolic variables can be referenced by variable names. When you type var('beta'), Sage defines a new symbolic variable whose name is beta, and also defines a new standard variable, also named beta, and makes the standard variable reference the symbolic variable.

But here's the issue: You can later change this standard variable to refer to some other Sage object. And that's what you're doing when you write beta = 1.

When you defined eq, you were using the earlier object (that is, the symbolic variable) stored in the standard variable beta. Storing something new with the name beta doesn't change this.

Here's another example where I first use the variable B to store the value 1, then use it to define an equation, and then store a new value in that variable. Doing so doesn't change the equation.

sage: B = 1
sage: eq = x == B    
sage: eq
x == 1
sage: B = 2
sage: eq
x == 1

Incidentally, this is why the "dictionary approach" in the previous answer doesn't work: The dictionary being used in that case is equivalent to {1:1}, and it's key doesn't match any of the symbolic variables in the equation.

edit flag offensive delete link more


very insightful, thanks for the detailed explanation!

fidbc gravatar imagefidbc ( 2013-05-09 13:52:33 -0500 )edit

answered 2013-05-03 15:25:47 -0500

fidbc gravatar image

How about this:

sage: eq.subs(beta=beta)
x == 1

Something strange is that the "dictionary approach" does not work:

sage: eq.subs({beta:beta})
x == beta
edit flag offensive delete link more



Not so strange: the Python variable `beta` at that point does not contain the symbolic variable `beta` any more, but instead contains the value 1. Where key names in the first approach are interpreted as strings naming symbolic variables, in the second approach they are treated as Python expressions. You could have saved the old meaning of `beta` by writing `beta_var = beta` before the `beta = 1`. Then you could use `{beta_var: beta}` to update the expression.

MvG gravatar imageMvG ( 2013-05-15 07:06:46 -0500 )edit

the dictionary approach does work if you spell it sage: eq.subs({SR('beta'): beta}) Here `SR('beta')` creates the symbolic variable named `beta` independent of what the python name `beta` is bound to.

nbruin gravatar imagenbruin ( 2013-09-26 07:55:06 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools


Asked: 2013-05-03 13:02:11 -0500

Seen: 463 times

Last updated: May 09 '13