Ask Your Question

Why is basic arithmetic disallowed on symbolic functions?

asked 2015-03-09 17:36:16 -0500

stan gravatar image

updated 2015-03-11 05:58:41 -0500

The documentation at 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

answered 2015-03-11 10:48:32 -0500

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)

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


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 17:40:21 -0500 )edit

answered 2015-03-09 18:23:11 -0500

tmonteil gravatar image

updated 2015-03-09 18:24:46 -0500

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')
sage: aze

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

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

sage: var('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
edit flag offensive delete link more


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

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

stan gravatar imagestan ( 2015-03-10 02:57:40 -0500 )edit

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 04:32:45 -0500 )edit

answered 2015-03-10 03:15:36 -0500

stan gravatar image

updated 2015-03-10 03:20:24 -0500

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.
    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}} +
    name = 'f_'+str(var1)
    z = function(name,latex_name = latex(var1)) 
    return z(var2)
edit flag offensive delete link more

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


Asked: 2015-03-09 17:36:16 -0500

Seen: 158 times

Last updated: Mar 11 '15