Ask Your Question
1

Evaluating symbolic expression, when some variables are finally fixed

asked 2017-03-24 05:43:58 -0500

wjur gravatar image

updated 2017-05-07 11:04:14 -0500

tmonteil gravatar image

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 flag offensive close merge delete

3 answers

Sort by ยป oldest newest most voted
1

answered 2017-03-24 09:49:41 -0500

tmonteil gravatar image

updated 2017-03-25 16:13:17 -0500

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
edit flag offensive delete link more

Comments

Needs a minor edit of V to R...

paulmasson gravatar imagepaulmasson ( 2017-03-24 19:15:18 -0500 )edit

Edited, thanks.

tmonteil gravatar imagetmonteil ( 2017-03-25 16:13:30 -0500 )edit

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

nbruin gravatar imagenbruin ( 2017-03-26 18:56:33 -0500 )edit

BTW, more on substituting multiple values is on
Substituting multiple values question&answer

wjur gravatar imagewjur ( 2017-03-30 06:42:53 -0500 )edit
0

answered 2017-03-24 19:09:58 -0500

this post is marked as community wiki

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

edit flag offensive delete link more

Comments

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).

mforets gravatar imagemforets ( 2017-03-25 00:42:08 -0500 )edit

BTW, Solution I found thanks to other sage question&answer
problems with sage_eval and eval

wjur gravatar imagewjur ( 2017-03-30 06:31:47 -0500 )edit
0

answered 2017-03-24 11:08:22 -0500

mforets gravatar image

updated 2017-03-24 11:14:12 -0500

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.

edit flag offensive delete link more

Comments

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

mforets gravatar imagemforets ( 2017-03-24 11:15:23 -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

Stats

Asked: 2017-03-24 05:43:58 -0500

Seen: 128 times

Last updated: Mar 30