Sympy - Rename part of an expressionSymPy: Custom print format for a custom Function expressionHow to merge two dictionaries in a single expression?Rename multiple files in a directory in PythonRenaming columns in pandasSecond derivative of the Hankel function unsing sympyExtract affine part of SymPy expressionSympy gives numerical numpy output in dtype object formatsympy autowrap (cython): limit of # of arguments, arguments in array form?sympy - symbolic sum over symbolic number of elementsReplacing part of the sympy expressionExtract the constant part of a SymPy expression
If a centaur druid Wild Shapes into a Giant Elk, do their Charge features stack?
Patience, young "Padovan"
Domain expired, GoDaddy holds it and is asking more money
Email Account under attack (really) - anything I can do?
Is domain driven design an anti-SQL pattern?
What are the advantages and disadvantages of running one shots compared to campaigns?
Doomsday-clock for my fantasy planet
Need help identifying/translating a plaque in Tangier, Morocco
"My colleague's body is amazing"
Why is the design of haulage companies so “special”?
Are cabin dividers used to "hide" the flex of the airplane?
Prime joint compound before latex paint?
Re-submission of rejected manuscript without informing co-authors
Is Social Media Science Fiction?
aging parents with no investments
I’m planning on buying a laser printer but concerned about the life cycle of toner in the machine
How would photo IDs work for shapeshifters?
Are white and non-white police officers equally likely to kill black suspects?
Is a vector space a subspace of itself?
Where else does the Shulchan Aruch quote an authority by name?
Is it wise to hold on to stock that has plummeted and then stabilized?
How to make payment on the internet without leaving a money trail?
Why do we use polarized capacitors?
Does the average primeness of natural numbers tend to zero?
Sympy - Rename part of an expression
SymPy: Custom print format for a custom Function expressionHow to merge two dictionaries in a single expression?Rename multiple files in a directory in PythonRenaming columns in pandasSecond derivative of the Hankel function unsing sympyExtract affine part of SymPy expressionSympy gives numerical numpy output in dtype object formatsympy autowrap (cython): limit of # of arguments, arguments in array form?sympy - symbolic sum over symbolic number of elementsReplacing part of the sympy expressionExtract the constant part of a SymPy expression
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
Say I have defined the following expression:
from sympy import *
N, D, i, j, d = symbols("N D i j d", integer=True)
beta, gamma = symbols(r'beta gamma')
X = IndexedBase("X", shape=(N, D))
# r(i, j) = euclidian distance between X[i] and X[j]
r = lambda i, j: sqrt(Sum((X[i, d] - X[j, d])**2, (d, 1, D)))
expr = r(i, j)**2 + r(i, j)
The expr
variable now displays like this:
While this is fine for this minimal example, it gets quite messy in larger expressions. This really hinders my ability to see what happens later on when I compute sums over all r(i,j)
, derivatives etc.
My question: Is there a way to tell SymPy about r(i, j)
, such that it can be displayed as something like this:
while still behaving as before in subsequent expressions?
I know I could make r
a Function
, which would display as wanted, but then it would not work properly in a subsequent calculation (e.g. derivatives would be abstract and not evaluated).
Any help would be much appreciated!
python sympy
|
show 1 more comment
Say I have defined the following expression:
from sympy import *
N, D, i, j, d = symbols("N D i j d", integer=True)
beta, gamma = symbols(r'beta gamma')
X = IndexedBase("X", shape=(N, D))
# r(i, j) = euclidian distance between X[i] and X[j]
r = lambda i, j: sqrt(Sum((X[i, d] - X[j, d])**2, (d, 1, D)))
expr = r(i, j)**2 + r(i, j)
The expr
variable now displays like this:
While this is fine for this minimal example, it gets quite messy in larger expressions. This really hinders my ability to see what happens later on when I compute sums over all r(i,j)
, derivatives etc.
My question: Is there a way to tell SymPy about r(i, j)
, such that it can be displayed as something like this:
while still behaving as before in subsequent expressions?
I know I could make r
a Function
, which would display as wanted, but then it would not work properly in a subsequent calculation (e.g. derivatives would be abstract and not evaluated).
Any help would be much appreciated!
python sympy
I'm not too familiar with Sympy, is this helpful at all: (docs.sympy.org/latest/modules/rewriting.html)?
– Sarcoma
Mar 8 at 7:22
@Sarcoma Didn't know about that, nice! Withcse
it's able to auto-replace the common subexpressions, which is nice. But it's still not a full solution, as the resulting expressions "forget" their origin, and e.g. derivatives don't work as they should. I tried taking the derivative first, thencse
, but then it tends to find other patterns than what I would expect it to.
– Bendik
Mar 8 at 7:47
What do you mean derivatives would be abstract and not evaluated?
– ALFA
Mar 8 at 11:44
@ALFA I mean thatdiff(r(i,j), X[k,l])
evaluates to zero because there is no known dependency onX
within the functionr
(if I definer
as aFunction
symbol). The only derivatives that make sense for SymPy isdiff(r(i,j), i, 1)
(or same withj
), which would not be able to evaluate to anything (it's just the derivative of some function), plus not being very relevant in this case.
– Bendik
Mar 8 at 11:51
I did manage to get something working following the examples in docs.sympy.org/latest/modules/… on some built in functions. It didn't seem to work nicely with my custom class. I'll play around with it a bit more.
– Sarcoma
Mar 8 at 12:36
|
show 1 more comment
Say I have defined the following expression:
from sympy import *
N, D, i, j, d = symbols("N D i j d", integer=True)
beta, gamma = symbols(r'beta gamma')
X = IndexedBase("X", shape=(N, D))
# r(i, j) = euclidian distance between X[i] and X[j]
r = lambda i, j: sqrt(Sum((X[i, d] - X[j, d])**2, (d, 1, D)))
expr = r(i, j)**2 + r(i, j)
The expr
variable now displays like this:
While this is fine for this minimal example, it gets quite messy in larger expressions. This really hinders my ability to see what happens later on when I compute sums over all r(i,j)
, derivatives etc.
My question: Is there a way to tell SymPy about r(i, j)
, such that it can be displayed as something like this:
while still behaving as before in subsequent expressions?
I know I could make r
a Function
, which would display as wanted, but then it would not work properly in a subsequent calculation (e.g. derivatives would be abstract and not evaluated).
Any help would be much appreciated!
python sympy
Say I have defined the following expression:
from sympy import *
N, D, i, j, d = symbols("N D i j d", integer=True)
beta, gamma = symbols(r'beta gamma')
X = IndexedBase("X", shape=(N, D))
# r(i, j) = euclidian distance between X[i] and X[j]
r = lambda i, j: sqrt(Sum((X[i, d] - X[j, d])**2, (d, 1, D)))
expr = r(i, j)**2 + r(i, j)
The expr
variable now displays like this:
While this is fine for this minimal example, it gets quite messy in larger expressions. This really hinders my ability to see what happens later on when I compute sums over all r(i,j)
, derivatives etc.
My question: Is there a way to tell SymPy about r(i, j)
, such that it can be displayed as something like this:
while still behaving as before in subsequent expressions?
I know I could make r
a Function
, which would display as wanted, but then it would not work properly in a subsequent calculation (e.g. derivatives would be abstract and not evaluated).
Any help would be much appreciated!
python sympy
python sympy
edited Feb 28 at 11:29
Bendik
asked Feb 28 at 9:21
BendikBendik
3811315
3811315
I'm not too familiar with Sympy, is this helpful at all: (docs.sympy.org/latest/modules/rewriting.html)?
– Sarcoma
Mar 8 at 7:22
@Sarcoma Didn't know about that, nice! Withcse
it's able to auto-replace the common subexpressions, which is nice. But it's still not a full solution, as the resulting expressions "forget" their origin, and e.g. derivatives don't work as they should. I tried taking the derivative first, thencse
, but then it tends to find other patterns than what I would expect it to.
– Bendik
Mar 8 at 7:47
What do you mean derivatives would be abstract and not evaluated?
– ALFA
Mar 8 at 11:44
@ALFA I mean thatdiff(r(i,j), X[k,l])
evaluates to zero because there is no known dependency onX
within the functionr
(if I definer
as aFunction
symbol). The only derivatives that make sense for SymPy isdiff(r(i,j), i, 1)
(or same withj
), which would not be able to evaluate to anything (it's just the derivative of some function), plus not being very relevant in this case.
– Bendik
Mar 8 at 11:51
I did manage to get something working following the examples in docs.sympy.org/latest/modules/… on some built in functions. It didn't seem to work nicely with my custom class. I'll play around with it a bit more.
– Sarcoma
Mar 8 at 12:36
|
show 1 more comment
I'm not too familiar with Sympy, is this helpful at all: (docs.sympy.org/latest/modules/rewriting.html)?
– Sarcoma
Mar 8 at 7:22
@Sarcoma Didn't know about that, nice! Withcse
it's able to auto-replace the common subexpressions, which is nice. But it's still not a full solution, as the resulting expressions "forget" their origin, and e.g. derivatives don't work as they should. I tried taking the derivative first, thencse
, but then it tends to find other patterns than what I would expect it to.
– Bendik
Mar 8 at 7:47
What do you mean derivatives would be abstract and not evaluated?
– ALFA
Mar 8 at 11:44
@ALFA I mean thatdiff(r(i,j), X[k,l])
evaluates to zero because there is no known dependency onX
within the functionr
(if I definer
as aFunction
symbol). The only derivatives that make sense for SymPy isdiff(r(i,j), i, 1)
(or same withj
), which would not be able to evaluate to anything (it's just the derivative of some function), plus not being very relevant in this case.
– Bendik
Mar 8 at 11:51
I did manage to get something working following the examples in docs.sympy.org/latest/modules/… on some built in functions. It didn't seem to work nicely with my custom class. I'll play around with it a bit more.
– Sarcoma
Mar 8 at 12:36
I'm not too familiar with Sympy, is this helpful at all: (docs.sympy.org/latest/modules/rewriting.html)?
– Sarcoma
Mar 8 at 7:22
I'm not too familiar with Sympy, is this helpful at all: (docs.sympy.org/latest/modules/rewriting.html)?
– Sarcoma
Mar 8 at 7:22
@Sarcoma Didn't know about that, nice! With
cse
it's able to auto-replace the common subexpressions, which is nice. But it's still not a full solution, as the resulting expressions "forget" their origin, and e.g. derivatives don't work as they should. I tried taking the derivative first, then cse
, but then it tends to find other patterns than what I would expect it to.– Bendik
Mar 8 at 7:47
@Sarcoma Didn't know about that, nice! With
cse
it's able to auto-replace the common subexpressions, which is nice. But it's still not a full solution, as the resulting expressions "forget" their origin, and e.g. derivatives don't work as they should. I tried taking the derivative first, then cse
, but then it tends to find other patterns than what I would expect it to.– Bendik
Mar 8 at 7:47
What do you mean derivatives would be abstract and not evaluated?
– ALFA
Mar 8 at 11:44
What do you mean derivatives would be abstract and not evaluated?
– ALFA
Mar 8 at 11:44
@ALFA I mean that
diff(r(i,j), X[k,l])
evaluates to zero because there is no known dependency on X
within the function r
(if I define r
as a Function
symbol). The only derivatives that make sense for SymPy is diff(r(i,j), i, 1)
(or same with j
), which would not be able to evaluate to anything (it's just the derivative of some function), plus not being very relevant in this case.– Bendik
Mar 8 at 11:51
@ALFA I mean that
diff(r(i,j), X[k,l])
evaluates to zero because there is no known dependency on X
within the function r
(if I define r
as a Function
symbol). The only derivatives that make sense for SymPy is diff(r(i,j), i, 1)
(or same with j
), which would not be able to evaluate to anything (it's just the derivative of some function), plus not being very relevant in this case.– Bendik
Mar 8 at 11:51
I did manage to get something working following the examples in docs.sympy.org/latest/modules/… on some built in functions. It didn't seem to work nicely with my custom class. I'll play around with it a bit more.
– Sarcoma
Mar 8 at 12:36
I did manage to get something working following the examples in docs.sympy.org/latest/modules/… on some built in functions. It didn't seem to work nicely with my custom class. I'll play around with it a bit more.
– Sarcoma
Mar 8 at 12:36
|
show 1 more comment
2 Answers
2
active
oldest
votes
You can make a custom Function subclass that doesn't evaluate by default:
class r(Function):
@classmethod
def eval(cls, i, j):
return
def doit(self, **kwargs):
i, j = self.args
return sqrt(Sum((X[i, d] - X[j, d])**2, (d, 1, D)))
eval
tells it when to evaluate. Since it always returns None, it never evaluates. It also tells SymPy the function has two arguments. You can also have it return explicit values in some cases, if you like. For instance, you might want it to evaluate if i
and j
are explicit numbers.
@classmethod
def eval(cls, i, j):
if i.is_Number and j.is_Number:
return sqrt(Sum((X[i, d] - X[j, d])**2, (d, 1, D)))
With this you can use it as desired, and call expr.doit()
when you want it to evaluate. You can also specifically define evaluation for certain functions to avoid doit
. For example, derivatives:
def _eval_derivative(self, x):
return self.doit()._eval_derivative(x)
This will make r(i, j).diff(i)
evaluate immediately without having to call doit
.
Other functions have similar methods you can define. See the SymPy documentation.
add a comment |
I don't really know if it may helps you but what about this:
from sympy import *
from sympy.utilities.lambdify import lambdify, implemented_function
N, D, i, j, d = symbols("N D i j d", integer=True)
beta, gamma = symbols(r'beta gamma')
X = IndexedBase("X", shape=(N, D))
r = implemented_function('r', lambda i, j: sqrt(Sum((X[i, d] - X[j, d])**2, (d, 1, D))));
expr = r(i, j)**2 + r(i, j)
print(expr)
r = lambdify((i,j), r(i,j))
print(diff(r(i,j), X[i,j]))
You can display your expression as you wish, then use lambdify()
and makes it behave as it should. Just guessing, maybe it's useless for you as you probably prefer a way to maintain the same expression all along the code.
I'd come across this, looked like it ought to do the trick. Couldn't get it working though. I saw this in the docs for lambdify: "Be aware that this is a quick workaround, not a general method to create special symbolic functions. If you want to create a symbolic function to be used by all the machinery of SymPy you should subclass the Function class." which led me to think that the more verboseclass r(Function):
might also work.
– Sarcoma
Mar 8 at 12:21
That's pretty close actually. It's slightly awkward to have to change between the two all the time, but still. Withr_func = lambdify((i,j), r(i,j))
defined and doingdiff(expr.subs(r(i,j), r_func(i,j)), X[k,l]).subs(r_func(i,j), r(i,j))
it works the way I want it to. Wrapping this whole thing incse
makes it even simpler.
– Bendik
Mar 8 at 12:24
1
@Sarcoma But perhaps theFunction
subclass is the way to go to make this "smoother", although more work upfront... I'm gonna tinker with it a bit
– Bendik
Mar 8 at 12:26
1
Yes I would implement this with Function subclass. I think this is the closest option to your request, doing further researches on the web l could’t find a better way
– ALFA
Mar 8 at 13:59
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54922165%2fsympy-rename-part-of-an-expression%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
You can make a custom Function subclass that doesn't evaluate by default:
class r(Function):
@classmethod
def eval(cls, i, j):
return
def doit(self, **kwargs):
i, j = self.args
return sqrt(Sum((X[i, d] - X[j, d])**2, (d, 1, D)))
eval
tells it when to evaluate. Since it always returns None, it never evaluates. It also tells SymPy the function has two arguments. You can also have it return explicit values in some cases, if you like. For instance, you might want it to evaluate if i
and j
are explicit numbers.
@classmethod
def eval(cls, i, j):
if i.is_Number and j.is_Number:
return sqrt(Sum((X[i, d] - X[j, d])**2, (d, 1, D)))
With this you can use it as desired, and call expr.doit()
when you want it to evaluate. You can also specifically define evaluation for certain functions to avoid doit
. For example, derivatives:
def _eval_derivative(self, x):
return self.doit()._eval_derivative(x)
This will make r(i, j).diff(i)
evaluate immediately without having to call doit
.
Other functions have similar methods you can define. See the SymPy documentation.
add a comment |
You can make a custom Function subclass that doesn't evaluate by default:
class r(Function):
@classmethod
def eval(cls, i, j):
return
def doit(self, **kwargs):
i, j = self.args
return sqrt(Sum((X[i, d] - X[j, d])**2, (d, 1, D)))
eval
tells it when to evaluate. Since it always returns None, it never evaluates. It also tells SymPy the function has two arguments. You can also have it return explicit values in some cases, if you like. For instance, you might want it to evaluate if i
and j
are explicit numbers.
@classmethod
def eval(cls, i, j):
if i.is_Number and j.is_Number:
return sqrt(Sum((X[i, d] - X[j, d])**2, (d, 1, D)))
With this you can use it as desired, and call expr.doit()
when you want it to evaluate. You can also specifically define evaluation for certain functions to avoid doit
. For example, derivatives:
def _eval_derivative(self, x):
return self.doit()._eval_derivative(x)
This will make r(i, j).diff(i)
evaluate immediately without having to call doit
.
Other functions have similar methods you can define. See the SymPy documentation.
add a comment |
You can make a custom Function subclass that doesn't evaluate by default:
class r(Function):
@classmethod
def eval(cls, i, j):
return
def doit(self, **kwargs):
i, j = self.args
return sqrt(Sum((X[i, d] - X[j, d])**2, (d, 1, D)))
eval
tells it when to evaluate. Since it always returns None, it never evaluates. It also tells SymPy the function has two arguments. You can also have it return explicit values in some cases, if you like. For instance, you might want it to evaluate if i
and j
are explicit numbers.
@classmethod
def eval(cls, i, j):
if i.is_Number and j.is_Number:
return sqrt(Sum((X[i, d] - X[j, d])**2, (d, 1, D)))
With this you can use it as desired, and call expr.doit()
when you want it to evaluate. You can also specifically define evaluation for certain functions to avoid doit
. For example, derivatives:
def _eval_derivative(self, x):
return self.doit()._eval_derivative(x)
This will make r(i, j).diff(i)
evaluate immediately without having to call doit
.
Other functions have similar methods you can define. See the SymPy documentation.
You can make a custom Function subclass that doesn't evaluate by default:
class r(Function):
@classmethod
def eval(cls, i, j):
return
def doit(self, **kwargs):
i, j = self.args
return sqrt(Sum((X[i, d] - X[j, d])**2, (d, 1, D)))
eval
tells it when to evaluate. Since it always returns None, it never evaluates. It also tells SymPy the function has two arguments. You can also have it return explicit values in some cases, if you like. For instance, you might want it to evaluate if i
and j
are explicit numbers.
@classmethod
def eval(cls, i, j):
if i.is_Number and j.is_Number:
return sqrt(Sum((X[i, d] - X[j, d])**2, (d, 1, D)))
With this you can use it as desired, and call expr.doit()
when you want it to evaluate. You can also specifically define evaluation for certain functions to avoid doit
. For example, derivatives:
def _eval_derivative(self, x):
return self.doit()._eval_derivative(x)
This will make r(i, j).diff(i)
evaluate immediately without having to call doit
.
Other functions have similar methods you can define. See the SymPy documentation.
answered Mar 8 at 22:44
asmeurerasmeurer
59.2k17114188
59.2k17114188
add a comment |
add a comment |
I don't really know if it may helps you but what about this:
from sympy import *
from sympy.utilities.lambdify import lambdify, implemented_function
N, D, i, j, d = symbols("N D i j d", integer=True)
beta, gamma = symbols(r'beta gamma')
X = IndexedBase("X", shape=(N, D))
r = implemented_function('r', lambda i, j: sqrt(Sum((X[i, d] - X[j, d])**2, (d, 1, D))));
expr = r(i, j)**2 + r(i, j)
print(expr)
r = lambdify((i,j), r(i,j))
print(diff(r(i,j), X[i,j]))
You can display your expression as you wish, then use lambdify()
and makes it behave as it should. Just guessing, maybe it's useless for you as you probably prefer a way to maintain the same expression all along the code.
I'd come across this, looked like it ought to do the trick. Couldn't get it working though. I saw this in the docs for lambdify: "Be aware that this is a quick workaround, not a general method to create special symbolic functions. If you want to create a symbolic function to be used by all the machinery of SymPy you should subclass the Function class." which led me to think that the more verboseclass r(Function):
might also work.
– Sarcoma
Mar 8 at 12:21
That's pretty close actually. It's slightly awkward to have to change between the two all the time, but still. Withr_func = lambdify((i,j), r(i,j))
defined and doingdiff(expr.subs(r(i,j), r_func(i,j)), X[k,l]).subs(r_func(i,j), r(i,j))
it works the way I want it to. Wrapping this whole thing incse
makes it even simpler.
– Bendik
Mar 8 at 12:24
1
@Sarcoma But perhaps theFunction
subclass is the way to go to make this "smoother", although more work upfront... I'm gonna tinker with it a bit
– Bendik
Mar 8 at 12:26
1
Yes I would implement this with Function subclass. I think this is the closest option to your request, doing further researches on the web l could’t find a better way
– ALFA
Mar 8 at 13:59
add a comment |
I don't really know if it may helps you but what about this:
from sympy import *
from sympy.utilities.lambdify import lambdify, implemented_function
N, D, i, j, d = symbols("N D i j d", integer=True)
beta, gamma = symbols(r'beta gamma')
X = IndexedBase("X", shape=(N, D))
r = implemented_function('r', lambda i, j: sqrt(Sum((X[i, d] - X[j, d])**2, (d, 1, D))));
expr = r(i, j)**2 + r(i, j)
print(expr)
r = lambdify((i,j), r(i,j))
print(diff(r(i,j), X[i,j]))
You can display your expression as you wish, then use lambdify()
and makes it behave as it should. Just guessing, maybe it's useless for you as you probably prefer a way to maintain the same expression all along the code.
I'd come across this, looked like it ought to do the trick. Couldn't get it working though. I saw this in the docs for lambdify: "Be aware that this is a quick workaround, not a general method to create special symbolic functions. If you want to create a symbolic function to be used by all the machinery of SymPy you should subclass the Function class." which led me to think that the more verboseclass r(Function):
might also work.
– Sarcoma
Mar 8 at 12:21
That's pretty close actually. It's slightly awkward to have to change between the two all the time, but still. Withr_func = lambdify((i,j), r(i,j))
defined and doingdiff(expr.subs(r(i,j), r_func(i,j)), X[k,l]).subs(r_func(i,j), r(i,j))
it works the way I want it to. Wrapping this whole thing incse
makes it even simpler.
– Bendik
Mar 8 at 12:24
1
@Sarcoma But perhaps theFunction
subclass is the way to go to make this "smoother", although more work upfront... I'm gonna tinker with it a bit
– Bendik
Mar 8 at 12:26
1
Yes I would implement this with Function subclass. I think this is the closest option to your request, doing further researches on the web l could’t find a better way
– ALFA
Mar 8 at 13:59
add a comment |
I don't really know if it may helps you but what about this:
from sympy import *
from sympy.utilities.lambdify import lambdify, implemented_function
N, D, i, j, d = symbols("N D i j d", integer=True)
beta, gamma = symbols(r'beta gamma')
X = IndexedBase("X", shape=(N, D))
r = implemented_function('r', lambda i, j: sqrt(Sum((X[i, d] - X[j, d])**2, (d, 1, D))));
expr = r(i, j)**2 + r(i, j)
print(expr)
r = lambdify((i,j), r(i,j))
print(diff(r(i,j), X[i,j]))
You can display your expression as you wish, then use lambdify()
and makes it behave as it should. Just guessing, maybe it's useless for you as you probably prefer a way to maintain the same expression all along the code.
I don't really know if it may helps you but what about this:
from sympy import *
from sympy.utilities.lambdify import lambdify, implemented_function
N, D, i, j, d = symbols("N D i j d", integer=True)
beta, gamma = symbols(r'beta gamma')
X = IndexedBase("X", shape=(N, D))
r = implemented_function('r', lambda i, j: sqrt(Sum((X[i, d] - X[j, d])**2, (d, 1, D))));
expr = r(i, j)**2 + r(i, j)
print(expr)
r = lambdify((i,j), r(i,j))
print(diff(r(i,j), X[i,j]))
You can display your expression as you wish, then use lambdify()
and makes it behave as it should. Just guessing, maybe it's useless for you as you probably prefer a way to maintain the same expression all along the code.
answered Mar 8 at 12:06
ALFAALFA
1,058516
1,058516
I'd come across this, looked like it ought to do the trick. Couldn't get it working though. I saw this in the docs for lambdify: "Be aware that this is a quick workaround, not a general method to create special symbolic functions. If you want to create a symbolic function to be used by all the machinery of SymPy you should subclass the Function class." which led me to think that the more verboseclass r(Function):
might also work.
– Sarcoma
Mar 8 at 12:21
That's pretty close actually. It's slightly awkward to have to change between the two all the time, but still. Withr_func = lambdify((i,j), r(i,j))
defined and doingdiff(expr.subs(r(i,j), r_func(i,j)), X[k,l]).subs(r_func(i,j), r(i,j))
it works the way I want it to. Wrapping this whole thing incse
makes it even simpler.
– Bendik
Mar 8 at 12:24
1
@Sarcoma But perhaps theFunction
subclass is the way to go to make this "smoother", although more work upfront... I'm gonna tinker with it a bit
– Bendik
Mar 8 at 12:26
1
Yes I would implement this with Function subclass. I think this is the closest option to your request, doing further researches on the web l could’t find a better way
– ALFA
Mar 8 at 13:59
add a comment |
I'd come across this, looked like it ought to do the trick. Couldn't get it working though. I saw this in the docs for lambdify: "Be aware that this is a quick workaround, not a general method to create special symbolic functions. If you want to create a symbolic function to be used by all the machinery of SymPy you should subclass the Function class." which led me to think that the more verboseclass r(Function):
might also work.
– Sarcoma
Mar 8 at 12:21
That's pretty close actually. It's slightly awkward to have to change between the two all the time, but still. Withr_func = lambdify((i,j), r(i,j))
defined and doingdiff(expr.subs(r(i,j), r_func(i,j)), X[k,l]).subs(r_func(i,j), r(i,j))
it works the way I want it to. Wrapping this whole thing incse
makes it even simpler.
– Bendik
Mar 8 at 12:24
1
@Sarcoma But perhaps theFunction
subclass is the way to go to make this "smoother", although more work upfront... I'm gonna tinker with it a bit
– Bendik
Mar 8 at 12:26
1
Yes I would implement this with Function subclass. I think this is the closest option to your request, doing further researches on the web l could’t find a better way
– ALFA
Mar 8 at 13:59
I'd come across this, looked like it ought to do the trick. Couldn't get it working though. I saw this in the docs for lambdify: "Be aware that this is a quick workaround, not a general method to create special symbolic functions. If you want to create a symbolic function to be used by all the machinery of SymPy you should subclass the Function class." which led me to think that the more verbose
class r(Function):
might also work.– Sarcoma
Mar 8 at 12:21
I'd come across this, looked like it ought to do the trick. Couldn't get it working though. I saw this in the docs for lambdify: "Be aware that this is a quick workaround, not a general method to create special symbolic functions. If you want to create a symbolic function to be used by all the machinery of SymPy you should subclass the Function class." which led me to think that the more verbose
class r(Function):
might also work.– Sarcoma
Mar 8 at 12:21
That's pretty close actually. It's slightly awkward to have to change between the two all the time, but still. With
r_func = lambdify((i,j), r(i,j))
defined and doing diff(expr.subs(r(i,j), r_func(i,j)), X[k,l]).subs(r_func(i,j), r(i,j))
it works the way I want it to. Wrapping this whole thing in cse
makes it even simpler.– Bendik
Mar 8 at 12:24
That's pretty close actually. It's slightly awkward to have to change between the two all the time, but still. With
r_func = lambdify((i,j), r(i,j))
defined and doing diff(expr.subs(r(i,j), r_func(i,j)), X[k,l]).subs(r_func(i,j), r(i,j))
it works the way I want it to. Wrapping this whole thing in cse
makes it even simpler.– Bendik
Mar 8 at 12:24
1
1
@Sarcoma But perhaps the
Function
subclass is the way to go to make this "smoother", although more work upfront... I'm gonna tinker with it a bit– Bendik
Mar 8 at 12:26
@Sarcoma But perhaps the
Function
subclass is the way to go to make this "smoother", although more work upfront... I'm gonna tinker with it a bit– Bendik
Mar 8 at 12:26
1
1
Yes I would implement this with Function subclass. I think this is the closest option to your request, doing further researches on the web l could’t find a better way
– ALFA
Mar 8 at 13:59
Yes I would implement this with Function subclass. I think this is the closest option to your request, doing further researches on the web l could’t find a better way
– ALFA
Mar 8 at 13:59
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54922165%2fsympy-rename-part-of-an-expression%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
I'm not too familiar with Sympy, is this helpful at all: (docs.sympy.org/latest/modules/rewriting.html)?
– Sarcoma
Mar 8 at 7:22
@Sarcoma Didn't know about that, nice! With
cse
it's able to auto-replace the common subexpressions, which is nice. But it's still not a full solution, as the resulting expressions "forget" their origin, and e.g. derivatives don't work as they should. I tried taking the derivative first, thencse
, but then it tends to find other patterns than what I would expect it to.– Bendik
Mar 8 at 7:47
What do you mean derivatives would be abstract and not evaluated?
– ALFA
Mar 8 at 11:44
@ALFA I mean that
diff(r(i,j), X[k,l])
evaluates to zero because there is no known dependency onX
within the functionr
(if I definer
as aFunction
symbol). The only derivatives that make sense for SymPy isdiff(r(i,j), i, 1)
(or same withj
), which would not be able to evaluate to anything (it's just the derivative of some function), plus not being very relevant in this case.– Bendik
Mar 8 at 11:51
I did manage to get something working following the examples in docs.sympy.org/latest/modules/… on some built in functions. It didn't seem to work nicely with my custom class. I'll play around with it a bit more.
– Sarcoma
Mar 8 at 12:36