Ask Your Question

On mutating a variable to a function

asked 2023-02-24 10:24:27 +0200

Cyrille gravatar image

updated 2023-02-24 10:25:31 +0200

In looking to the page by accident, I have discovered an incredible feature of Sagemath : the fact that a variable can be transformed in a function and vis-versa. It is very nice for an economist (not only but it is what I am) in the following code

var('x y p_x p_y R λ')
U(x,y)= x*y
L(x,y,λ)= U(x,y)+λ*(R-p_x*x-p_y*y)
sol = solve([L(x,y,λ).diff(x)==0,L(x,y,λ).diff(y)==0,L(x,y,λ).diff(λ)==0], (x,y,λ))
x = function('x')
x = sol[0][0].rhs()
show(LatexExpr(r'\frac{dx}{dR} = '),x.diff(R).simplify())

My question : is there a shorten way to have access to x than writting x = sol[0][0].rhs() since show(sol[0][0]) display the relation correctly (but without x = sol[0][0].rhs(), I can't obtain the desired result).

Incidently, I think that this incredible feature is not enough publicized.

edit retag flag offensive close merge delete

2 Answers

Sort by » oldest newest most voted

answered 2023-02-24 13:40:56 +0200

Emmanuel Charpentier gravatar image

updated 2023-02-24 13:46:50 +0200


No, no, no, no, no.

And no.

You didn't "change a variable to a function". You redefined (twice !) the Python variable x.

Initially, you didn't define x, which means that by default, the Python variable x is bound to a Python object representing the symbolic variable $x$. This definition is active for lines 1-5 of your code.

Line 6, you redefine the Python variable x, binding it to a Python object representing an (undefined) symbolic function $x$.

Line 7, you redefine the Python variable x again, which binds it to the symbolic expression sol[0][0].rhs(), which turns out to be 1/2*R/p_x.

This symbolic expression has a .diff method :

Let e such a sumbolic expression ; e.diff(u) will return e.fiunction(u).diff(u), meaning *" take e as the body of a function of u and differentiate it with respect to u".

Therefore, x.diff(R).simplify()) is 1/2*R/p_x.function(R).diff(R).simplify() which evaluates to $\frac{p_x}{2}$.

See a Python tutorial (or the Python documentation) to understand the meaning of = in Python : a variable is just a label attached to a Python object ; this is quite different of a Sage symbolic variable, which is a Python object representing such a (mathematical) variable in the sage.symbolic.expression.Expression class.

The problem is compounded by the (hopefully convenient) shortcut of defining var("a") as a shortcut meaning a = SR.var("a"), meaning :

  • Create a sage.symbolic.expression.Expression representing the mathematical variable $a$, then

  • bind this object to the Python variable a.

This convenient shortcut is confusing to beginners...


edit flag offensive delete link more


Emmanuel you are the expert not me. But in the documentation I have read and cited in the beginning of my question it is written explicitely "Restoring variables after they have been turned into functions". I have modestly tried to apply what I have read.

Cyrille gravatar imageCyrille ( 2023-02-24 18:02:06 +0200 )edit

The example you quoted means that the Python variable x has been bound to the (undefined) symbolic function $x$. The restore? documentation is pretty clear. Extract :

   Restore predefined global variables to their default values.


   * "vars" - string or list (default: None), if not None, restores
     just the given variables to the default value.


sage: var("a")
sage: a
sage: restore("a")
sage: a
NameError                                 Traceback (most recent call last)
Cell In [12], line 1
----> 1 a

NameError: name 'a' is not defined

`restore works only for the predefined global variables.

Emmanuel Charpentier gravatar imageEmmanuel Charpentier ( 2023-02-24 21:56:39 +0200 )edit

I think that this wording in the documentation is a bit misleading: "Restoring variables after they have been turned into functions". This suggests that after executing x = function('x'), Sage still remembers that x used to be a variable, when in fact it doesn't. As Emmanuel says, any assignment of the form x = ... completely replaces the old value of x with the new one. There is nothing magical about the letter x: deleting the line x = function('x') and then using z = sol[0][0].rhs() and z.diff(R) works just as well.

John Palmieri gravatar imageJohn Palmieri ( 2023-02-26 00:44:52 +0200 )edit

answered 2023-02-24 12:19:19 +0200

achrzesz gravatar image

updated 2023-02-24 14:10:49 +0200

This is not a short way but without rhs:

var('x y p_x p_y R λ')
U(x,y)= x*y
L(x,y,λ)= U(x,y)+λ*(R-p_x*x-p_y*y)
sol = solve([L(x,y,λ).diff(x)==0,L(x,y,λ).diff(y)==0,L(x,y,λ).diff(λ)==0],
show(LatexExpr(r'\frac{dx}{dR} = '),sol[x].diff(R))
edit flag offensive delete link more


Nice but you are obliged to change the name of the variable.

Cyrille gravatar imageCyrille ( 2023-02-24 12:27:07 +0200 )edit

I reedited my answer

achrzesz gravatar imageachrzesz ( 2023-02-24 14:11:54 +0200 )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


Asked: 2023-02-24 10:24:27 +0200

Seen: 126 times

Last updated: Feb 24 '23