1 | initial version |
To better focus on the actual question, in this answer we
w
for w0
, V
for EU
Define U
(as a symbolic function U
, not as the expression U(x)
):
sage: U = function('U')
Define a function V
of three variables based on U
:
sage: V(x, y, p) = p*U(x) + (1 - p)*U(y)
Note that all names on the left hand side of the assignment operator =
get
defined by that line: V
as a function, and x
, y
, p
as symbolic variables.
No need to declare them beforehand.
Define three symbolic variables:
sage: w, g, c = SR.var('w, g, c')
Define an expression f
based on V
and these variables:
sage: f = V(w, g*w - c, p)
Differentiate with respect to w
:
sage: h = diff(f, w)
View the result:
sage: view(h)
$$ -g {\left(p - 1\right)} \mathrm{D}_{0}\left(U\right)\left(g w - c\right) + p frac{partial}{partial w}U\left(w\right) $$
That has two occurrences of $U'$, represented in two ways:
The goal is to make them appear as $U'(g w - c)$ and $U'(w)$.
There are two approaches:
The answer by @dsejas covers string replacements in the latex form.
Here we discuss substitutions in the expression tree.
First we give a ready-made solution. Then we explain how one could explore to get to that solution.
Here is a function for operator substitution in an expression:
def subs_op(expr, op1, op2):
r"""
Return the expression `expr` with operator `op1` replaced by `op2`.
"""
op = expr.operator()
if op:
opp = (op2 if str(op) == str(op1) else op)
args = expr.operands()
aargs = (subs_op(a, op1, op2) for a in args)
return opp(*aargs)
else:
return expr
To address the question with this, define the to-be-replaced
and the replacement operators, then use subs_op
:
sage: DU = U(x).diff().operator()
sage: Uprime = function("U'")
sage: fff = subs_op(ff, DU, Uprime)
sage: fff
-g*(p - 1)*U'(g*w - c) + p*U'(w)
sage: view(fff)
$$ -g {\left(p - 1\right)} {\rm U'}\left(g w - c\right) + p {\rm U'}\left(w\right) $$
Problem solved, at least in an ad-hoc way.
Here is a use_prime
function that walks through an expression
and replaces any derivatives of functions of a single variable
by "prime" versions (or "double-prime", etc. depending on the
order of differentiation).
def use_prime(expr):
r"""
Return the expression with one-variable function derivatives "primed".
"""
op = expr.operator()
if op:
args = expr.operands()
aargs = (use_prime(a) for a in args)
opp = op
if (isinstance(op, sage.symbolic.operators.FDerivativeOperator)
and len(args) == 1):
name = op.function().name()
primes = "'" * len(op.parameter_set())
opp = function(f"{name}{primes}")
return opp(*aargs)
else:
return expr
Example with various types of derivatives:
sage: a, b = (function(f) for f in 'ab')
sage: x, z = SR.var('x, z')
sage: f(x, z) = z * a(x * z) + x * z * diff(b(z), z)
sage: g(x, z) = diff(f(x, z), x) + diff(f(x, z), z)
sage: h = diff(g(x, z), x)
sage: h
x*z^2*D[0, 0](a)(x*z) + z^3*D[0, 0](a)(x*z) + 2*z*D[0](a)(x*z) + z*diff(c(z), z, z) + diff(c(z), z)
sage: view(h)
$$ x z^{2} \mathrm{D}_{0, 0}\left(a\right)\left(x z\right) + z^{3} \mathrm{D}_{0, 0}\left(a\right)\left(x z\right) + 2 \, z \mathrm{D}_{0}\left(a\right)\left(x z\right) + z frac{partial^{2}}{(partial z)^{2}}c\left(z\right) + frac{partial}{partial z}c\left(z\right) $$
sage: hh = use_prime(h)
sage: hh
x*z^2*a''(x*z) + z^3*a''(x*z) + 2*z*a'(x*z) + z*c''(z) + c'(z)
sage: view(hh)
$$ x z^{2} {\rm a''}\left(x z\right) + z^{3} {\rm a''}\left(x z\right) + 2 \, z {\rm a'}\left(x z\right) + z {\rm c''}\left(z\right) + {\rm c'}\left(z\right) $$
Example with the original question:
U = function('U')
EU(x, y, p) = p*U(x) + (1 - p)*U(y)
w0, g, c = SR.var('w0, g, c')
f = EU(w0, g*w0 - c, p)
h = diff(f, w0)
show(h)
hh = use_prime(h)
show(hh)
$$ -g {\left(p - 1\right)} \mathrm{D}_{0}\left(U\right)\left(g w_{0} - c\right) + p frac{partial}{partial w_{0}}U\left(w_{0}\right) $$
$$ -g {\left(p - 1\right)} {\rm U'}\left(g w_{0} - c\right) + p {\rm U'}\left(w_{0}\right) $$
2 | No.2 Revision |
To better focus on the actual question, in this answer we
w
for w0
, V
for EU
Define U
(as a symbolic function U
, not as the expression U(x)
):
sage: U = function('U')
Define a function V
of three variables based on U
:
sage: V(x, y, p) = p*U(x) + (1 - p)*U(y)
Note that all names on the left hand side of the assignment operator =
get
defined by that line: V
as a function, and x
, y
, p
as symbolic variables.
No need to declare them beforehand.
Define three symbolic variables:
sage: w, g, c = SR.var('w, g, c')
Define an expression f
based on V
and these variables:
sage: f = V(w, g*w - c, p)
Differentiate with respect to w
:
sage: h = diff(f, w)
View the result:
sage: view(h)
$$
-g $$-g {\left(p - 1\right)}
\mathrm{D}_{0}\left(U\right)\left(g 1\right)} {\rm D}_{0}\left(U\right)\left(g w - c\right)
c\right) + p frac{partial}{partial w}U\left(w\right)
$$w}U\left(w\right)$$
That has two occurrences of $U'$, represented in two ways:
The goal is to make them appear as $U'(g w - c)$ and $U'(w)$.
There are two approaches:
The answer by @dsejas covers string replacements in the latex form.
Here we discuss substitutions in the expression tree.
First we give a ready-made solution. Then we explain how one could explore to get to that solution.
Here is a function for operator substitution in an expression:
def subs_op(expr, op1, op2):
r"""
Return the expression `expr` with operator `op1` replaced by `op2`.
"""
op = expr.operator()
if op:
opp = (op2 if str(op) == str(op1) else op)
args = expr.operands()
aargs = (subs_op(a, op1, op2) for a in args)
return opp(*aargs)
else:
return expr
To address the question with this, define the to-be-replaced
and the replacement operators, then use subs_op
:
sage: DU = U(x).diff().operator()
sage: Uprime = function("U'")
sage: fff = subs_op(ff, DU, Uprime)
sage: fff
-g*(p - 1)*U'(g*w - c) + p*U'(w)
sage: view(fff)
$$
-g $$-g {\left(p - 1\right)} {\rm U'}\left(g w - c\right) + p {\rm U'}\left(w\right)
$$U'}\left(w\right)$$
Problem solved, at least in an ad-hoc way.
Here is a use_prime
function that walks through an expression
and replaces any derivatives of functions of a single variable
by "prime" versions (or "double-prime", etc. depending on the
order of differentiation).
def use_prime(expr):
r"""
Return the expression with one-variable function derivatives "primed".
"""
op = expr.operator()
if op:
args = expr.operands()
aargs = (use_prime(a) for a in args)
opp = op
if (isinstance(op, sage.symbolic.operators.FDerivativeOperator)
and len(args) == 1):
name = op.function().name()
primes = "'" * len(op.parameter_set())
opp = function(f"{name}{primes}")
return opp(*aargs)
else:
return expr
Example with various types of derivatives:
sage: a, b = (function(f) for f in 'ab')
sage: x, z = SR.var('x, z')
sage: f(x, z) = z * a(x * z) + x * z * diff(b(z), z)
sage: g(x, z) h = diff(f(x, z), x) + diff(f(x, z), z)
sage: h = diff(g(x, z), z, x)
sage: h
x*z^2*D[0, 0](a)(x*z) + z^3*D[0, 0](a)(x*z) + 2*z*D[0](a)(x*z) + z*diff(c(z), z*diff(b(z), z, z) + diff(c(z), diff(b(z), z)
sage: view(h)
$$
x $$x z^{2} \mathrm{D}_{0, 0}\left(a\right)\left(x z\right) + z^{3} \mathrm{D}_{0, 0}\left(a\right)\left(x z\right) {\rm D}_{0, 0}(a)(x z) + 2 \, z \mathrm{D}_{0}\left(a\right)\left(x z\right) {\rm D}_0 (a)(x z) + z frac{partial^{2}}{(partial z)^{2}}c\left(z\right) frac{partial^2}{(partial z)^2}b(z) + frac{partial}{partial z}c\left(z\right)
$$z}b(z)$$
sage: hh = use_prime(h)
sage: hh
x*z^2*a''(x*z) + z^3*a''(x*z) + 2*z*a'(x*z) + z*c''(z) + c'(z)
z*b''(z) + b'(z)
sage: view(hh)
$$
x $$x z^{2} {\rm a''}\left(x z\right) + z^{3} {\rm a''}\left(x z\right) + 2 \, z {\rm a'}\left(x z\right) + z {\rm c''}\left(z\right) b''}\left(z\right) + {\rm c'}\left(z\right)
$$b'}\left(z\right)$$
Example with the original question:
U = function('U')
EU(x, V(x, y, p) = p*U(x) + (1 - p)*U(y)
w0, w, g, c = SR.var('w0, SR.var('w, g, c')
f = EU(w0, g*w0 V(w, g*w - c, p)
h = diff(f, w0)
w)
show(h)
hh = use_prime(h)
show(hh)
$$
-g {\left(p - 1\right)} \mathrm{D}_{0}\left(U\right)\left(g w_{0} - c\right) $$-g {(p - 1)} \mathrm{D}_0(U)(g w - c) + p frac{partial}{partial w_{0}}U\left(w_{0}\right)
$$
$$ -g {\left(p - 1\right)} w}U(w)$$
$$-g {(p - 1)} {\rm U'}\left(g w_{0} - c\right) U'}(g w - c) + p {\rm U'}\left(w_{0}\right)
$$
Having provided an approach above, we now explain the exploration that can lead to such an approach.
Define again
sage: U = function('U')
sage: V(x, y, p) = p*U(x) + (1 - p)*U(y)
sage: w, g, c = SR.var('w, g, c')
sage: f = V(w, g*w - c, p)
sage: h = diff(f, w)
Explore the available methods for expression h
with h.<TAB>
(ie type h.
then hit the TAB key).
Find among the available methods operator
and operands
:
sage: h.operator(), h.operands()
(<function add_vararg at 0x2007603a0>,
[-g*(p - 1)*D[0](U)(g*w - c), p*diff(U(w), w)])
Give names to the operands and get one level deeper:
sage: a, b = h.operands()
sage: a.operator(), a.operands()
(<function mul_vararg at 0x2007601f0>, [g, p - 1, D[0](U)(g*w - c), -1])
sage: b.operator(), b.operands()
(<function mul_vararg at 0x2007601f0>, [p, diff(U(w), w)])
Name the operands we care about and explore one level further:
sage: _, _, aa, _ = a.operands()
sage: _, bb = b.operands()
sage: aa
D[0](U)(g*w - c)
sage: bb
diff(U(w), w)
sage: aa.operator(), aa.operands()
(D[0](U), [g*w - c])
sage: bb.operator(), bb.operands()
(D[0](U), [w])
Unfortunately aa.operator()
and bb.operator()
do not compare equal:
sage: a.operator() == b.operator()
False
So we have to resort to string comparison:
sage: str(a.operator()) == str(b.operator())
Now we try to build this operator in a simpler way:
sage: DUx = U(x).diff()
sage: DUx
diff(U(x), x)
sage: DU = DUx.operator()
sage: DU
D[0](U)
Good, now for the replacement we use a symbolic function
whose string representation is U'
.
sage: function("U'")
sage: function("U'")
U'
All that is left is to recursively replace one operator
by the other by walking the expression tree.
See subs_op
above.
Now for the more general function, we analyse a little further:
sage: type(DU)
<class 'sage.symbolic.operators.FDerivativeOperator'>
sage: isinstance(DU, sage.symbolic.operators.FDerivativeOperator)
True
and exploring DU.
+ TAB
we find function
and parameter_set
.
The cases when we want to replace are those where the operator
is an FDerivativeOperator
and has a single variable.
See use_prime
above.
Besides exploring using TAB
and ?
, searching existing
questions and tickets can also prove useful, see below.
This answer was inspired by answers to similar questions.
Some queries
In particular see @tmonteil's answer to
and some answers to
Making the D
operator more accessible is the object of
3 | No.3 Revision |
To better focus on the actual question, in this answer we
w
V
instead of w0
and EU
, V
for EU
Define U
(as a symbolic function U
, not as the expression U(x)
):
sage: U = function('U')
Define a function V
of three variables based on U
:
sage: V(x, y, p) = p*U(x) + (1 - p)*U(y)
Note that all names on the left hand side of the assignment operator =
get
defined by that line: V
as a function, and x
, y
, p
as symbolic variables.
No need to declare them beforehand.
Define three symbolic variables:variables, an expression f
based on V
and these variables,
and another one, differentiating with respect to w
:
sage: w, g, c = SR.var('w, g, c')
Define an expression f
based on V
and these variables:
sage: f = V(w, g*w - c, p)
Differentiate with respect to w
:
sage: h = diff(f, w)
sage: view(h)
View the result:
sage: view(h)
$$-g {\left(p - 1\right)} {(p - 1)} {\rm D}_{0}\left(U\right)\left(g D}_0(U)(g w - c\right) c) + p frac{partial}{partial w}U\left(w\right)$$w}U(w)$$
That has two occurrences of $U'$, represented in two ways:
The goal is to make them appear which we would like to
show as $U'(g w - c)$ and $U'(w)$.
There are two approaches:
The answer by @dsejas covers an approach using
string replacements in the latex form.representation.
Here we discuss an alternative approach performing
substitutions in the expression tree.tree before displaying.
First we give provide two versions of this appraoch,
one ad-hoc for a ready-made solution. single derivative replacement,
one more general. Then we explain
explain how one could could
explore to get to that solution.these solutions.
Here is a function for operator substitution in an expression:
def subs_op(expr, op1, op2):
r"""
Return the expression `expr` with operator `op1` replaced by `op2`.
"""
op = expr.operator()
if op:
opp = (op2 if str(op) == str(op1) else op)
args = expr.operands()
aargs = (subs_op(a, op1, op2) for a in args)
return opp(*aargs)
else:
return expr
To address the question with this, define the to-be-replaced
and the replacement operators, then use subs_op
:
sage: DU = U(x).diff().operator()
sage: Uprime = function("U'")
sage: DU, Uprime
(D[0](U), U')
sage: fff = subs_op(ff, DU, Uprime)
sage: fff
-g*(p - 1)*U'(g*w - c) + p*U'(w)
sage: view(fff)
$$-g {\left(p - 1\right)} {\rm U'}\left(g w - c\right) + p {\rm U'}\left(w\right)$$
Problem solved, at least in an ad-hoc way.
Here is a use_prime
function that walks through an expression
and replaces any derivatives of functions of a single variable
by "prime" versions (or "double-prime", etc. depending on the
order of differentiation).
def use_prime(expr):
r"""
Return the expression with one-variable function derivatives "primed".
"""
op = expr.operator()
if op:
args = expr.operands()
aargs = (use_prime(a) for a in args)
opp = op
if (isinstance(op, sage.symbolic.operators.FDerivativeOperator)
and len(args) == 1):
name = op.function().name()
primes = "'" * len(op.parameter_set())
opp = function(f"{name}{primes}")
return opp(*aargs)
else:
return expr
Example with various types of derivatives:
sage: a, b = (function(f) for f in 'ab')
sage: x, z = SR.var('x, z')
sage: f(x, z) = z * a(x * z) + x * z * diff(b(z), z)
sage: h = diff(f(x, z), z, x)
sage: h
x*z^2*D[0, 0](a)(x*z) + 2*z*D[0](a)(x*z) + z*diff(b(z), z, z) + diff(b(z), z)
sage: view(h)
$$x z^{2} {\rm D}_{0, 0}(a)(x z) + 2 z {\rm D}_0 (a)(x z) + z frac{partial^2}{(partial z)^2}b(z) + frac{partial}{partial z}b(z)$$
sage: hh = use_prime(h)
sage: hh
x*z^2*a''(x*z) + 2*z*a'(x*z) + z*b''(z) + b'(z)
sage: view(hh)
$$x z^{2} {\rm a''}\left(x z\right) + 2 z {\rm a'}\left(x z\right) + z {\rm b''}\left(z\right) + {\rm b'}\left(z\right)$$
Example with the original question:
U = function('U')
V(x, y, p) = p*U(x) + (1 - p)*U(y)
w, g, c = SR.var('w, g, c')
f = V(w, g*w - c, p)
h = diff(f, w)
show(h)
hh = use_prime(h)
show(hh)
$$-g {(p - 1)} \mathrm{D}_0(U)(g w - c) + p frac{partial}{partial w}U(w)$$
$$-g {(p - 1)} {\rm U'}(g w - c) + p {\rm U'}(w)$$
Having provided an approach above, we now explain the exploration that can lead to such an approach.
Define again
sage: U = function('U')
sage: V(x, y, p) = p*U(x) + (1 - p)*U(y)
sage: w, g, c = SR.var('w, g, c')
sage: f = V(w, g*w - c, p)
sage: h = diff(f, w)
Explore the available methods for expression h
with h.<TAB>
(ie type h.
then hit the TAB key).
Find among the available methods operator
and operands
:
sage: h.operator(), h.operands()
(<function add_vararg at 0x2007603a0>,
[-g*(p - 1)*D[0](U)(g*w - c), p*diff(U(w), w)])
Give names to the operands and get one level deeper:
sage: a, b = h.operands()
sage: a.operator(), a.operands()
(<function mul_vararg at 0x2007601f0>, [g, p - 1, D[0](U)(g*w - c), -1])
sage: b.operator(), b.operands()
(<function mul_vararg at 0x2007601f0>, [p, diff(U(w), w)])
Name the operands we care about and explore one level further:
sage: _, _, aa, _ = a.operands()
sage: _, bb = b.operands()
sage: aa
D[0](U)(g*w - c)
sage: bb
diff(U(w), w)
sage: aa.operator(), aa.operands()
(D[0](U), [g*w - c])
sage: bb.operator(), bb.operands()
(D[0](U), [w])
Unfortunately aa.operator()
and bb.operator()
do not compare equal:
sage: a.operator() == b.operator()
False
So we have to resort to string comparison:
sage: str(a.operator()) == str(b.operator())
Now we try to build this operator in a simpler way:
sage: DUx = U(x).diff()
sage: DUx
diff(U(x), x)
sage: DU = DUx.operator()
sage: DU
D[0](U)
Good, now for the replacement we use a symbolic function
whose string representation is U'
.
sage: function("U'")
sage: function("U'")
U'
All that is left is to recursively replace one operator
by the other by walking the expression tree.
See subs_op
above.
Now for the more general function, we analyse a little further:
sage: type(DU)
<class 'sage.symbolic.operators.FDerivativeOperator'>
sage: isinstance(DU, sage.symbolic.operators.FDerivativeOperator)
True
and exploring DU.
+ TAB
we find function
and parameter_set
.
The cases when we want to replace are those where the operator
is an FDerivativeOperator
and has a single variable.
See use_prime
above.
Besides exploring using TAB
and ?
, searching existing
questions and tickets can also prove useful, see below.
This answer was inspired by answers to similar questions.
Some queries
In particular see @tmonteil's answer to
and some answers to
Making the D
operator more accessible is the object of
4 | No.4 Revision |
To better focus on the actual question, in this answer we use
simpler names w
and V
instead of w0
and EU
, and skip
the assumptions on $p$.
Define U
(as a symbolic function U
, not as the expression U(x)
):
sage: U = function('U')
Define a function V
of three variables based on U
:
sage: V(x, y, p) = p*U(x) + (1 - p)*U(y)
Note that all names on the left hand side of the assignment operator =
get
defined by that line: V
as a function, and x
, y
, p
as symbolic variables.
No need to declare them beforehand.
Define three symbolic variables, an expression f
based on V
and these variables,
and another one, differentiating with respect to w
:
sage: w, g, c = SR.var('w, g, c')
sage: f = V(w, g*w - c, p)
sage: h = diff(f, w)
sage: view(h)
$$-g {(p - 1)} {\rm D}_0(U)(g w - c) + p frac{partial}{partial w}U(w)$$frac{∂}{∂ w} U(w)$$
That has two occurrences of $U'$, which we would like to show as $U'(g w - c)$ and $U'(w)$ instead of ${\rm D}_0(U)(g w - c)$ and $frac{partial}{partial w} U(w)$.
The answer by @dsejas covers an approach using string replacements in the latex representation.
Here we discuss an alternative approach performing substitutions in the expression tree before displaying.
First we provide two versions of this appraoch, one ad-hoc for a single derivative replacement, one more general. Then we explain how one could explore to get to these solutions.
Here is a function for operator substitution in an expression:
def subs_op(expr, op1, op2):
r"""
Return the expression `expr` with operator `op1` replaced by `op2`.
"""
op = expr.operator()
if op:
opp = (op2 if str(op) == str(op1) else op)
args = expr.operands()
aargs = (subs_op(a, op1, op2) for a in args)
return opp(*aargs)
else:
return expr
To address the question with this, define the to-be-replaced
and the replacement operators, then use subs_op
:
sage: DU = U(x).diff().operator()
sage: Uprime = function("U'")
sage: DU, Uprime
(D[0](U), U')
sage: fff = subs_op(ff, DU, Uprime)
sage: fff
-g*(p - 1)*U'(g*w - c) + p*U'(w)
sage: view(fff)
$$-g {\left(p - 1\right)} {(p - 1)} {\rm U'}\left(g U'}(g w - c\right) c) + p {\rm U'}\left(w\right)$$U'}(w)$$
Problem solved, at least in an ad-hoc way.
Here is a use_prime
function that walks through an expression
and replaces any derivatives of functions of a single variable
by "prime" versions (or "double-prime", etc. depending on the
order of differentiation).
def use_prime(expr):
r"""
Return the expression with one-variable function derivatives "primed".
"""
op = expr.operator()
if op:
args = expr.operands()
aargs = (use_prime(a) for a in args)
opp = op
if (isinstance(op, sage.symbolic.operators.FDerivativeOperator)
and len(args) == 1):
name = op.function().name()
primes = "'" * len(op.parameter_set())
opp = function(f"{name}{primes}")
return opp(*aargs)
else:
return expr
Example with various types of derivatives:
sage: a, b = (function(f) for f in 'ab')
sage: x, z = SR.var('x, z')
sage: f(x, z) = z * a(x * z) + x * z * diff(b(z), z)
sage: h = diff(f(x, z), z, x)
sage: h
x*z^2*D[0, 0](a)(x*z) + 2*z*D[0](a)(x*z) + z*diff(b(z), z, z) + diff(b(z), z)
sage: view(h)
$$x z^{2} z^2 {\rm D}_{0, 0}(a)(x D}_{0,0}(a)(x z) + 2 z {\rm D}_0 (a)(x z) + z frac{partial^2}{(partial frac{∂^2}{(∂ z)^2}b(z) + frac{partial}{partial frac{∂}{∂ z}b(z)$$
sage: hh = use_prime(h)
sage: hh
x*z^2*a''(x*z) + 2*z*a'(x*z) + z*b''(z) + b'(z)
sage: view(hh)
$$x z^{2} z^2 {\rm a''}\left(x z\right) a''}(x z) + 2 z {\rm a'}\left(x z\right) a'}(x z) + z {\rm b''}\left(z\right) b''}(z) + {\rm b'}\left(z\right)$$b'}(z)$$
Example with the original question:
U = function('U')
V(x, y, p) = p*U(x) + (1 - p)*U(y)
w, g, c = SR.var('w, g, c')
f = V(w, g*w - c, p)
h = diff(f, w)
show(h)
hh = use_prime(h)
show(hh)
$$-g {(p - 1)} \mathrm{D}_0(U)(g {\rm D}_0(U)(g w - c) + p frac{partial}{partial frac{∂}{∂ w}U(w)$$
$$-g {(p - 1)} {\rm U'}(g w - c) + p {\rm U'}(w)$$
Having provided an approach above, we now explain the exploration that can lead to such an approach.
Define again
sage: U = function('U')
sage: V(x, y, p) = p*U(x) + (1 - p)*U(y)
sage: w, g, c = SR.var('w, g, c')
sage: f = V(w, g*w - c, p)
sage: h = diff(f, w)
Explore the available methods for expression h
with h.<TAB>
(ie type h.
then hit the TAB key).
Find among the available methods operator
and operands
:
sage: h.operator(), h.operands()
(<function add_vararg at 0x2007603a0>,
[-g*(p - 1)*D[0](U)(g*w - c), p*diff(U(w), w)])
Give names to the operands and get one level deeper:
sage: a, b = h.operands()
sage: a.operator(), a.operands()
(<function mul_vararg at 0x2007601f0>, [g, p - 1, D[0](U)(g*w - c), -1])
sage: b.operator(), b.operands()
(<function mul_vararg at 0x2007601f0>, [p, diff(U(w), w)])
Name the operands we care about and explore one level further:
sage: _, _, aa, _ = a.operands()
sage: _, bb = b.operands()
sage: aa
D[0](U)(g*w - c)
sage: bb
diff(U(w), w)
sage: aa.operator(), aa.operands()
(D[0](U), [g*w - c])
sage: bb.operator(), bb.operands()
(D[0](U), [w])
Unfortunately aa.operator()
and bb.operator()
do not compare equal:
sage: a.operator() == b.operator()
False
So we have to resort to string comparison:
sage: str(a.operator()) == str(b.operator())
Now we try to build this operator in a simpler way:
sage: DUx = U(x).diff()
sage: DUx
diff(U(x), x)
sage: DU = DUx.operator()
sage: DU
D[0](U)
Good, now for the replacement we use a symbolic function
whose string representation is U'
.
sage: function("U'")
sage: function("U'")
U'
All that is left is to recursively replace one operator
by the other by walking the expression tree.
See subs_op
above.
Now for the more general function, we analyse a little further:
sage: type(DU)
<class 'sage.symbolic.operators.FDerivativeOperator'>
sage: isinstance(DU, sage.symbolic.operators.FDerivativeOperator)
True
and exploring DU.
+ TAB
we find function
and parameter_set
.
The cases when we want to replace are those where the operator
is an FDerivativeOperator
and has a single variable.
See use_prime
above.
Besides exploring using TAB
and ?
, searching existing
questions and tickets can also prove useful, see below.
This answer was inspired by answers to similar questions.
Some queries
In particular see @tmonteil's answer to
and some answers to
Making the D
operator more accessible is the object of
5 | No.5 Revision |
To better focus on the actual question, in this answer we use
simpler names w
and V
instead of w0
and EU
, and skip
the assumptions on $p$.
Define U
(as a symbolic function U
, not as the expression U(x)
):
sage: U = function('U')
Define a function V
of three variables based on U
:
sage: V(x, y, p) = p*U(x) + (1 - p)*U(y)
Note that all names on the left hand side of the assignment operator =
get
defined by that line: V
as a function, and x
, y
, p
as symbolic variables.
No need to declare them beforehand.
Define three symbolic variables, an expression f
based on V
and these variables,
and another one, differentiating with respect to w
:
sage: w, g, c = SR.var('w, g, c')
sage: f = V(w, g*w - c, p)
sage: h = diff(f, w)
sage: view(h)
$$-g {(p - 1)} {\rm D}_0(U)(g w - c) + p frac{∂}{∂ w} ({∂}/{∂ w}) U(w)$$
That has two occurrences of $U'$, which we would like to
show as $U'(g w - c)$ and $U'(w)$ instead of
${\rm D}_0(U)(g w - c)$ and $frac{partial}{partial w} $({∂}/{∂ w}) U(w)$.
The answer by @dsejas covers an approach using string replacements in the latex representation.
Here we discuss an alternative approach performing substitutions in the expression tree before displaying.
First we provide two versions of this appraoch,
approach,
one ad-hoc for a single derivative replacement,
one more general. Then we explain how one could
explore to get to these solutions.
Here is a function for operator substitution in an expression:
def subs_op(expr, op1, op2):
r"""
Return the expression `expr` with operator `op1` replaced by `op2`.
"""
op = expr.operator()
if op:
opp = (op2 if str(op) == str(op1) else op)
args = expr.operands()
aargs = (subs_op(a, op1, op2) for a in args)
return opp(*aargs)
else:
return expr
To address the question with this, define the to-be-replaced
and the replacement operators, then use subs_op
:
sage: DU = U(x).diff().operator()
sage: Uprime = function("U'")
sage: DU, Uprime
(D[0](U), U')
sage: fff = subs_op(ff, DU, Uprime)
sage: fff
-g*(p - 1)*U'(g*w - c) + p*U'(w)
sage: view(fff)
$$-g {(p - 1)} {\rm U'}(g w - c) + p {\rm U'}(w)$$
Problem solved, at least in an ad-hoc way.
Here is a use_prime
function that walks through an expression
and replaces any derivatives of functions of a single variable
by "prime" versions (or "double-prime", etc. depending on the
order of differentiation).
def use_prime(expr):
r"""
Return the expression with one-variable function derivatives "primed".
"""
op = expr.operator()
if op:
args = expr.operands()
aargs = (use_prime(a) for a in args)
opp = op
if (isinstance(op, sage.symbolic.operators.FDerivativeOperator)
and len(args) == 1):
name = op.function().name()
primes = "'" * len(op.parameter_set())
opp = function(f"{name}{primes}")
return opp(*aargs)
else:
return expr
Example with various types of derivatives:
sage: a, b = (function(f) for f in 'ab')
sage: x, z = SR.var('x, z')
sage: f(x, z) = z * a(x * z) + x * z * diff(b(z), z)
sage: h = diff(f(x, z), z, x)
sage: h
x*z^2*D[0, 0](a)(x*z) + 2*z*D[0](a)(x*z) + z*diff(b(z), z, z) + diff(b(z), z)
sage: view(h)
$$x z^2 {\rm D}_{0,0}(a)(x z) + 2 z {\rm D}_0 (a)(x z) + z frac{∂^2}{(∂ z)^2}b(z) + frac{∂}{∂ z}b(z)$$({∂^2}/{(∂ z)^2})b(z) + ({∂}/{∂ z})b(z)$$
sage: hh = use_prime(h)
sage: hh
x*z^2*a''(x*z) + 2*z*a'(x*z) + z*b''(z) + b'(z)
sage: view(hh)
$$x z^2 {\rm a''}(x z) + 2 z {\rm a'}(x z) + z {\rm b''}(z) + {\rm b'}(z)$$
Example with the original question:
U = function('U')
V(x, y, p) = p*U(x) + (1 - p)*U(y)
w, g, c = SR.var('w, g, c')
f = V(w, g*w - c, p)
h = diff(f, w)
show(h)
hh = use_prime(h)
show(hh)
$$-g {(p - 1)} {\rm D}_0(U)(g w - c) + p frac{∂}{∂ w}U(w)$$({∂}/{∂ z})U(w)$$
$$-g {(p - 1)} {\rm U'}(g w - c) + p {\rm U'}(w)$$
Having provided an approach above, we now explain the exploration that can lead to such an approach.
Define again
sage: U = function('U')
sage: V(x, y, p) = p*U(x) + (1 - p)*U(y)
sage: w, g, c = SR.var('w, g, c')
sage: f = V(w, g*w - c, p)
sage: h = diff(f, w)
Explore the available methods for expression h
with h.<TAB>
(ie type h.
then hit the TAB key).
Find among the available methods operator
and operands
:
sage: h.operator(), h.operands()
(<function add_vararg at 0x2007603a0>,
[-g*(p - 1)*D[0](U)(g*w - c), p*diff(U(w), w)])
Give names to the operands and get one level deeper:
sage: a, b = h.operands()
sage: a.operator(), a.operands()
(<function mul_vararg at 0x2007601f0>, [g, p - 1, D[0](U)(g*w - c), -1])
sage: b.operator(), b.operands()
(<function mul_vararg at 0x2007601f0>, [p, diff(U(w), w)])
Name the operands we care about and explore one level further:
sage: _, _, aa, _ = a.operands()
sage: _, bb = b.operands()
sage: aa
D[0](U)(g*w - c)
sage: bb
diff(U(w), w)
sage: aa.operator(), aa.operands()
(D[0](U), [g*w - c])
sage: bb.operator(), bb.operands()
(D[0](U), [w])
Unfortunately aa.operator()
and bb.operator()
do not compare equal:
sage: a.operator() == b.operator()
False
So we have to resort to string comparison:
sage: str(a.operator()) == str(b.operator())
Now we try to build this operator in a simpler way:
sage: DUx = U(x).diff()
sage: DUx
diff(U(x), x)
sage: DU = DUx.operator()
sage: DU
D[0](U)
Good, now for the replacement we use a symbolic function
whose string representation is U'
.
sage: function("U'")
sage: function("U'")
U'
All that is left is to recursively replace one operator
by the other by walking the expression tree.
See subs_op
above.
Now for the more general function, we analyse a little further:
sage: type(DU)
<class 'sage.symbolic.operators.FDerivativeOperator'>
sage: isinstance(DU, sage.symbolic.operators.FDerivativeOperator)
True
and exploring DU.
+ TAB
we find function
and parameter_set
.
The cases when we want to replace are those where the operator
is an FDerivativeOperator
and has a single variable.
See use_prime
above.
Besides exploring using TAB
and ?
, searching existing
questions and tickets can also prove useful, see below.
This answer was inspired by answers to similar questions.
Some queries
In particular see @tmonteil's answer to
and some answers to
Making the D
operator more accessible is the object of