【问题标题】:How do I make this substitution in Mathematica?如何在 Mathematica 中进行这种替换?
【发布时间】:2011-11-26 23:55:31
【问题描述】:

我刚刚开始使用 Mathematica,我有一个关于进行替换的非常基本的问题,但我无法让它工作。

我想找到函数 phi[x,y] 的泛函的欧拉-拉格朗日方程,然后替换函数 phi[x,y]

如果我输入以下内容:

VariationalD[tau*phi[x, y]^2 - 2*phi[x, y]^4 + phi[x, y]^6 + Dot[D[phi[x, y], {{x, y}}], D[phi[x, y, {{x, y}}]]], phi[x, y], {x, y}]

我明白了

Plus[Times[2,tau,phi[x,y]],Times[-8,Power[phi[x,y],3]],Times[6,Power[phi[x,y],5]],Times[-2,Plus[Derivative[0,2][phi][x,y],Derivative[2,0][phi][x,y]]]]

现在,如果我尝试% /. phi[x,y] -> phi0[x,y] + psi[x,y],它会替换所有多项式项,但不会替换导数项。

如何强制替换到这些函数中?

【问题讨论】:

  • +1,让我努力想出一个简单、通用的方法来完成这个。
  • 这对物理学家来说可能是显而易见的,但你想为Derivative[0, 2][phi][x, y] term 做什么替换?
  • @Yaro phi[x,y]->phi0[x,y]+psi[x,y] ...可能他正在做一些扰动分析。之后,您只保留最重要的术语是 psi。这就是 ODE 始终为您提供谐波振荡器的方式……或混沌。那是物理学:)

标签: wolfram-mathematica


【解决方案1】:

我同意rcollyer 所说的所有内容,但我认为他的最终解决方案可能有点不透明。

我能想出的最简单的规则(与 rcollyer 的基本相同)是

{phi[x__] :> phi0[x] + psi[x], f_[phi][x__] :> f[phi0][x] + f[psi][x]}

或者副作用较小的东西是

{phi[x__] :> phi0[x] + psi[x], Derivative[n__][phi][x__] :> Derivative[n][phi0][x] + Derivative[n][psi][x]}

如果DerivativeDefault 属性(比较Default[Times]Default[Derivative])会容易得多。它应该是 Default[Derivative] := Sequence[] 之类的东西,但不幸的是,它与模式匹配不匹配。

回到您的问题,您可能想要定义类似

VariationalD[expr_, sym_, var_] := Module[{
  vRule = {sym[x__] :> sym[x] + var[x], 
    Derivative[n__][sym][x__] :> Derivative[n][sym][x] + Derivative[n][var][x]}}, 
  (expr /. vRule) - expr]

假设符号sym 的变化var 很小。当然,您需要做的是围绕var=0 展开系列,并且只保留线性部分。然后在任何具有var 派生词的术语上使用按部分集成。所有这些都应该包含在上述模块中。

【讨论】:

  • +1,有趣的答案。我的回答是不透明的,但是我反对每次需要替换函数的总和时都需要创建一个特殊规则。我宁愿有一个我可以不加修改地使用的规则,但每个人都有自己的规则。你的规则会更容易在我脑海中浮现。
  • 至于您对我的回答可能产生的副作用的看法,a_[b__][c__] 模式只会匹配那些有两组或更多组方括号的头部。此外,Distribute[a[b]] 只有在b 包含Plus 时才会实际重新排列事物,并且它不能超过一层,即f[a,x+y,b] 变为f[a,x,b]+f[a,y,b]f[a,g[x+y],b] 不受影响。 Through 是唯一的潜在问题子代,因为 Through[a b[x]] 未被评估,因此可以稍微改进模式。
【解决方案2】:

首先,您在二阶导数项中放错了],它应该是D[phi[x, y], {{x, y}}]] 而不是D[phi[x, y, {{x, y}}]]]

也就是说,Mathematica 中的替换可能很棘手,正如其他 questions 中所指出的那样。这并不是说不可能,只是需要一些工作。在这种情况下,问题在于phi[x,y]Derivative[2, 0][phi][x, y] 不同。因此,您的模式将与衍生项不匹配。最简单的做法是添加规则

Derivative[a__][phi][x__]:> Derivative[a][phi0][x] + Derivative[a][psi][x]

到您的替换规则列表。需要注意的三件事:1)我使用ReplaceDelayed,这样两种类型的派生词都可以匹配而无需编写多个规则,2)因为我可以使用模式,所以我命名它们以便我可以在规则的 RHS 上引用它们, 3) 我在定义ax 时使用了double underscore,这将匹配序列中的一个或多个项目。

当然,这不是解决问题的最令人满意的方法,因为每次您希望进行这种替换时,您都需要编写两条规则。事实证明,一个更通用的方法非常难以完成,我将不得不回复您。

编辑:这需要双重替换,如下

<result> /. phi -> phi0 + psi /. a_[b__][c__] :> Through[Distribute[a[b]][c]]

Distribute 确保导数与Plus 一起正常工作,Through 与函数 args c 相同。关键是Derivative[2, 0][phi][x, y]HeadDerivative[2, 0][phi],因此规则中的方括号有几级。

【讨论】:

  • 感谢您的回答。它有效,但我在解析它时仍然遇到了一些麻烦。模式 a_[b__][c__] 到底匹配什么?我猜例如 a_ 可以匹配 Derivative,b__ 可以匹配 [2,0],c__ 可以匹配 [phi0+psi]。那么 RuleDelayed 的 rhs 将是 Through[Distribute[Derivative[2,0]][phi0+psi]]。我一定是错误地解释了括号或操作顺序错误,但在我看来,Distribute 函数没有任何东西可以分发 Derivative。除非先评估 Through 函数?
  • @Ranjit,那是最难的。这种模式,a_[b__][c__] 更容易从右到左阅读:[c__] 匹配末尾带有方括号的任何内容,[b__] 然后匹配倒数第二个方括号,因此 a_ 匹配其他所有内容。所以,a_ :&gt; Derivative[2,0]b__ :&gt; phi0 + psic__ :&gt; Sequence[x,y]。那么Distribute的目的就是把Derivative[2,0]Plus互换,Through给每个导数附加[x,y]
猜你喜欢
  • 1970-01-01
  • 2020-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-23
  • 2016-09-29
  • 1970-01-01
  • 2011-09-08
相关资源
最近更新 更多