# Evaluating symbolic expression, when some variables are finally fixed

Hello

I'm looking for solution when bigger number of variables is in the picture.

Simple example: There is relationship I = V/R then we know that R = 3, with that knowledge let's plot I(V)
in sage it should look something like:

V = var('V')
R = var('R')
I = V/R
R = 3
plot(I)


but above is not working, because in plot(I) I is still V/R not V/3 (knowledge of R=3 is not used), so I'm looking for some operation that turns V/R into V/3, something like

I = evaluate(I)


but such evaluate() apparently does not exist

there are however two different ways
(1) repeat I=V/R after R=3 and in such situation I becomes V/3 as needed
(2) I = I(R=R) and with earlier R=3, I also becomes V/3
both however seems for me be solution(s) for simple expression with just few variables, and not good (not as straightforward as hypothetical I = evaluate(I) for more complex expression with several variables.

Is such evaluate() or so, available already, and I failed to find it?
Is there a (easy) way to implement that proposed evaluate() ?

edit retag close merge delete

Sort by » oldest newest most voted

When you write R = SR.var('R'), the left-hand R is a Python name pointing to the right-hand SR.var('R'), which is a symbolic expression. Then when you write R = 3, the Python name R points to the integer 3, so there is no relationship anymore between R and SR.var('R'):

sage: R = SR.var('R')
sage: type(R)
<type 'sage.symbolic.expression.Expression'>
sage: R = 3
sage: type(R)
<type 'sage.rings.integer.Integer'>


If you want to substitute R with 3 in I, you should do:

sage: I.substitute({R:3})
1/3*V

more

Needs a minor edit of V to R...

Either that or you can (partially) evaluate expressions using call syntax:

sage: var(R,V)
(R,V)
sage: I=V/R
sage: I
V/R
sage: I(R=3)
1/3*V


It has the slight advantage that the binding of R is irrelevant

sage: R="not a valid value"
sage: I(R=3)
1/3*V


The "R=" is a python construct and, for calling symbolic expressions, gets interpreted in terms of the symbolic ring This post is a wiki. Anyone with karma >750 is welcome to improve it.

Thanks to other answers, which concentrated on particular example, I wanted to explain better what I'm after (i.e. the general solution), and in that process I've got the answer:

I = eval(preparse(str(I)))

where

1. str(I) converts the 'I' expression to string
2. preparse(...) preparses the code of expression in the sage style ('^' as power, and so on)
3. eval(...) finally evaluates expression (in particular example: taking into account that R is already set to 3)

The code thus would be:

V = var('V')
R = var('R')
I = V/R
R = 3  # this is one line representation of possible several lines of code
# to compute value in general case. Let's also note that the value can
# even be provided externally (read from file, or so)
I = eval(preparse(str(I)))
plot(I)


and having in mind even more general solution with evaluate() definition:

def evaluate(expression):
return eval(preparse(str(expression)))

V = var('V')
R = var('R')
I = V/R
R = 3  # this is one line representation of possible several lines of code
# to compute value in general case. Let's also note that the value can
# even be provided externally (read from file, or so)
I = evaluate(I)
plot(I)


Few days later:
There is a small improvement possible - by adding simplify(), and so making the whole thing
I = simplify(eval(preparse(str(I))))

Please let know if the code could be more elegant (pythonic or sageonic) and if there are some disadvantages or threads in such solution

more

if it makes sense also in the more complicated case, you may simply define $I=V/R$ after the numerical value of $R$ has been computed. if it's not what you're after, you may create a function which computes the numerical values returning a dictionary, say numerical_values, and evaluate the current as in I = I.subs(numerical_values).

Moreover, notice that the "intuitive evaluation" is also ok, since both:

var('V R')
I = V/R
plot(I(R=3), (V, 0, 2))


and

var('V R')
I(R) = V/R
plot(I(3), (V, 0, 2))


work.

more

Although the first one has the advantage that it is clear which variable is evaluated ($R$).