Mathematica 中的部分评估
我有一个作用于两个函数的微分运算符。为了简化问题,假设我的运算符是
A[F_,G_] := D[F,x] D[G,y]
,如果我知道 F,我希望能够定义微分运算符 AF,使得 AF[G] 等于 A[F,G]。最明显的方法是
AF[G_] := A[F,G]
没有任何问题的工作。但我真正想要的是安排事情,以便当我使用不同的参数 G1、G2...调用 AF 时,导数 D[F,x] 不会每次都重新计算,而只会重新计算一次。此外,我希望 AF 的定义不依赖于 A 的特定形式,因为 A 作为参数传递给我的函数。
我已经阅读了有关 Hold、HoldAll、Evaluate 等的帮助,但我无法将这些内容放在一起来获得我想要的东西。我什至不知道我想要的在 Mathematica 中是否可行。
I have a differential operator that acts on two functions. To simplify the problem let's say that my operator is
A[F_,G_] := D[F,x] D[G,y]
I want to be able, if I know F, to define a differential operator AF such that AF[G] is equal to A[F,G]. The obvious way is
AF[G_] := A[F,G]
which works without any problem. But what I would really like is to arrange things so that when I call AF with different arguments G1, G2, ... the derivative D[F,x] is not re-computed every time but only once. Moreover, I would like the definition of AF to not depend on the particular form of A, since A is passed as an argument to my function.
I have read the help on Hold, HoldAll, Evaluate etc. but I cannot put these things together to get what I want. I don't even know if what I want is possible in Mathematica.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
对于您描述的问题,我没有看到直接的方法。您可以做的一件事是重新定义它以使其变得更加容易,那就是重新定义
A
,使其成为F
和G
的导数的函数。如果您有,您将能够很好地计算所需的
F
的导数,然后以相对于通用的方式定义
,如下所示:AF
A您可以使用
With
将已求值的片段替换为 SetDelayed 表单(使用“:=”的定义)的未求值右侧,如图所示。然而,如果您不能做出这样的改变,事情就会变得棘手,您将不得不对A
是什么进行一些假设。如果
A
是为其定义了 DownValues 的符号,并且定义简单,那么您可以通过使用Hold
、执行规则替换和然后执行ReleaseHold
,如下所示:第二条规则中的
With[...]
位是一个技巧,用于强制评估与内的模式匹配的内容>Hold
调用“Trott-Strzebonski 方法” ,这很晦涩,但对于这样的任务非常有用。然而,这种方式确实限制了你的接口,这意味着你不能为A
传递一个纯函数,并且对于更复杂的定义,这个技巧可能也不起作用。如果您能够设法指定您的微分形式将是实际导数的函数,我强烈建议您这样做。编辑:我想到了一种更通用、更强大的方法来做到这一点。
技巧是使用
Block
暂时抑制D
(导数运算符)的定义,因此A
定义中的导数保持未计算状态,然后使用规则替换来替换F
的导数的值,同时将所有内容包装在纯函数中以获得正确的名称替换,如下所示:With the problem you describe, I don't see a straightforward way of doing it. One thing you could do to recast it to make it dramatically easier would be to redefine
A
so its a function of the derivatives ofF
andG
. If you haveyou'll be in a very good position to calculate the derivatives of
F
that you need and then defineAF
in a way that's generic with respect toA
, like so:You can use
With
to substitute evaluated pieces into the unevaluated right-hand side of a SetDelayed form (a definition using ":=") as shown. However, if you can't make that change, things are going to get hairy, and you'll have to make some assumptions about whatA
is.If
A
is a symbol with DownValues defined for it, and has a simple definition, then you can do the partial evaluation you want by using aHold
, doing rule substitutions, and then doing aReleaseHold
, like so:The
With[...]
bit in the second rule is a trick for forcing the evaluation of something matching a pattern inside aHold
called the "Trott-Strzebonski method", which is obscure but extremely useful for tasks like this. However, going this way really limits your interface, meaning that you can't, say, pass in a pure function forA
, and with a more complicated definition this trick probably won't work either. If you can possibly manage to specify that your differential form will be a function of the actual derivatives, I strongly recommend doing so.EDIT: I thought of a more general and robust way of doing this.
The trick then is to temporarily suppress the definition of
D
(the derivative operator) usingBlock
, so the derivatives in the definition ofA
remain unevaluated, and then use rule-replacement to substitute in the values for the derivatives ofF
while wrapping everything up in a pure function to get the name substitution right, like so:你能不能仅仅这样做:
这类似于在 F# 等真正的函数式编程语言中进行柯里化,你可以在其中编写:
Can you not just do:
That is similar to currying in a real functional programming language like F#, where you would write: