Ask Your Question
0

Why is basic arithmetic disallowed on symbolic functions?

asked 2015-03-09 23:36:16 +0100

stan gravatar image

updated 2015-03-11 11:58:41 +0100

slelievre gravatar image

The documentation at http://www.sagemath.org/doc/reference... states:

In Sage 4.0, basic arithmetic with unevaluated functions is no longer supported

Why? What is the intended way of manipulating equations and then, at some point, taking derivatives with respect to some dependent variable? The following approach has an undesired side-effect:

sage: var('B E H T_s')
(B, E, H, T_s)
sage: eq_B_TS = B == H/E
sage: diff(eq_B_TS.subs(B = function('B')(T_s), E = function('E')(T_s), H = function('H')(T_s)), T_s)
D[0](B)(T_s) == -H(T_s)*D[0](E)(T_s)/E(T_s)^2 + D[0](H)(T_s)/E(T_s)

Fine, but now my B, E and H are symbolic functions and I cannot do any basic arithmetic with them any more:

sage: B*E
Traceback (click to the left of this block for traceback)
...
TypeError: unsupported operand type(s) for *: 'NewSymbolicFunction' and 'NewSymbolicFunction'

There must be a better way. Thanks for your help already.

edit retag flag offensive close merge delete

3 Answers

Sort by ยป oldest newest most voted
0

answered 2015-03-11 16:48:32 +0100

nbruin gravatar image

A part of your question seems to amount to "can I have both a function and a variable with the same print name" and indeed you can. The only slightly tricky bit is that, of course, you cannot have both bound to the same python identifier at the same time. So one solution is:

sage: A_as_a_var=var('A')
sage: A_as_a_function=function('A')
sage: A_as_a_function(A_as_a_var)
A(A)

The fact that the python identifier A is now bound to one of the two as a side-effect is perhaps confusing. If you use other "var" and "function" then you can avoid this problem.

sage: from sage.symbolic.function_factory import function as lib_function
sage: lib_var=SR.var
sage: A_as_a_var=lib_var('A')
sage: A_as_a_function=lib_function('A')
sage: A_as_a_function(A_as_a_var)
A(A)
sage: A
NameError: name 'A' is not defined

i.e., A is bound to neither, so no confusion about what it is bound to.

edit flag offensive delete link more

Comments

Wow, this is confusing, but actually solves my question, as long as the assignment of A_as_a_function = function('A') comes before var('A'). The example in my question then becomes:

sage: B_f = function('B')
sage: E_f = function('E')
sage: H_f = function('H')
sage: var('B E H T_s')
sage: eq_B = B == H/E
sage: eq1 = diff(eq_B.subs(B = B_f(T_s), H = H_f(T_s), E = E_f(T_s)), T_s)

Now B, E and E are still expressions, while E(T_s) is obtained by typing E_f(T_s). I wonder what other problems this will cause...

stan gravatar imagestan ( 2015-03-11 23:40:21 +0100 )edit
0

answered 2015-03-10 09:15:36 +0100

stan gravatar image

updated 2015-03-10 09:20:24 +0100

I just found a way to deal with this, which would be to define a python function that creates a new symbolic function out of an already defined variable, while keeping the latex representation of the original variable for illustration purposes:

def f(var1, var2):
    '''
    Creates a symbolic function out of existing variable,
    where the name of the function is f-underscore followed
    by the name of the existing variable, while the latexname
    of the original variable, if defined, stays the same. 
    Returns the function evaluated at another defined variable
    given as var2.
    Example:
    sage: var('B E H T_s')
    sage: eq_B = B == H/E
    sage: eq1 = diff(eq_B.subs(B = f(B,T_s), H = f(H,T_s), E = f(E,T_s)), T_s)
    sage: latex(eq1)
    D[0]\left(B\right)\left(T_{s}\right) = -\frac{H\left(T_{s}\right)
    D[0]\left(E\right)\left(T_{s}\right)}{E\left(T_{s}\right)^{2}} +
    \frac{D[0]\left(H\right)\left(T_{s}\right)}{E\left(T_{s}\right)}
    '''
    name = 'f_'+str(var1)
    z = function(name,latex_name = latex(var1)) 
    return z(var2)
edit flag offensive delete link more
0

answered 2015-03-10 00:23:11 +0100

tmonteil gravatar image

updated 2015-03-10 00:24:46 +0100

Note that, as with the ugly var, the function() function injects its returned value in the namespace, even if it is used during a .subs() call:

sage: function('aze')
aze
sage: aze
aze

sage: b = function('qsd')(x)
sage: b
qsd(x)
sage: qsd
qsd

Why don't you just define B, E and H directly as symbolic functions ?

sage: var('T_s')
T_s
sage: B = function('B')(T_s)
sage: E = function('E')(T_s)
sage: H = function('H')(T_s)
sage: eq_B_TS = B == H/E
sage: diff(eq_B_TS, T_s)
D[0](B)(T_s) == -H(T_s)*D[0](E)(T_s)/E(T_s)^2 + D[0](H)(T_s)/E(T_s)
sage: B*E
B(T_s)*E(T_s)
edit flag offensive delete link more

Comments

B = function('B')(T_s)

is very odd, as it creates a symbolic function called 'B' and then overwrites it immediately by a symbolic expression relating to function 'B' evaluated at 'T_s', if I understand http://trac.sagemath.org/ticket/17447 correctly. It also prints 'B(T_s)' every time, which is not desired, as it clutters equations and suggests that B is only a function of T_s. However in other contexts, B can also be a function of time or whatever.

B = function('B')(T_s)
H = function('H')(T_s)
E = function('E')(T_s)
eq_B = B == H/E
eq_B

B(T_s) == H(T_s)/E(T_s)

stan gravatar imagestan ( 2015-03-10 08:57:40 +0100 )edit
1

In ticket #17477 there is discussion about splitting var and function into var/declare_var and function/declare_function which would prevent such misunderstandings better.

rws gravatar imagerws ( 2015-03-11 10:32:45 +0100 )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

1 follower

Stats

Asked: 2015-03-09 23:36:16 +0100

Seen: 579 times

Last updated: Mar 11 '15