【问题标题】:Sympy trouble with simplifying partial derivatives简化偏导数的麻烦
【发布时间】:2020-11-25 22:11:48
【问题描述】:

我在 Sympy 中执行以下操作来生成表达式:

  1. 创建一些矩阵 Q_{ij},其中包含 x 和 y 的一些函数 \eta、\mu、\nu。
  2. 对索引求和并取一些偏导数。
  3. 用一些简单的表达式替换 \eta、\mu 和 \nu(比如 \sin(x)*\cos(y))。
  4. 尝试简化表达式,以便显式计算简单表达式的偏导数。

当我这样做时,它给了我以下错误: NotImplementedError: Improve MV Derivative support in collect

我使用的具体代码是:

from sympy import *

# Set up system and generate functions
x, y, z = symbols('x y z')
i, j, k, m, p = symbols('i j k m p')
xi = Matrix([x, y, z])
lims = range(0, 3)

eta = Function('eta', real=True)(x, y)
mu = Function('mu', real=True)(x, y)
nu = Function('nu', real=True)(x, y)

Q = Matrix([[2/sqrt(3)*eta, nu, 0],
            [nu, -1/sqrt(3)*eta + mu, 0],
            [0, 0, -1/sqrt(3)*eta - mu]])

# Create complicated expression of partial derivatives
Phi_L1 = -sum(Eijk(3, p + 1, i + 1)
              *diff(diff(diff(Q[k, l], xi[j]), xi[j]), xi[p])
              *diff(Q[k, l], xi[i])
              for i in lims
              for j in lims
              for k in lims
              for l in lims
              for p in lims
              )

Phi_L1 = simplify(Phi_L1)

# Choose example functions and try to evaluate expression explicitly
eta1 = sin(x)*cos(y)
mu1 = sinh(x)*cosh(y)
nu1 = x**2*y**2
expr1 = Phi_L1.subs(eta, eta1).subs(mu, mu1).subs(nu, nu1)
simplify(expr1)

我找不到给出相同错误的更简单示例。例如,以下内容按预期工作:

f = Function('f', real=True)(x, y)
expr = diff(diff(f, x), y)
simplify(expr.subs(f, sinh(x)*cosh(y)))

【问题讨论】:

标签: python sympy symbolic-math


【解决方案1】:

“收集”和“简化”在高阶偏导数方面存在已知问题https://github.com/sympy/sympy/issues/9068 概述了该问题

显示的例子是

import sympy as sp
x, y = sp.symbols("x y")
f, g = sp.symbols("f g", cls=sp.Function, args=(x,y))
f, g = f(), g()

expr1 = g.diff(x, 2) + f.diff(x, 2) + 5*f.diff(x, 2) + 2*f.diff(x) + 9*f.diff(x)
expr2 = g.diff(x, 2) + f.diff(x, 2) + 5*f.diff(x, 2) + 2*f.diff(x) + 9*f.diff(x) + g.diff(x).diff(y) + f.diff(x).diff(y) 

正常工作并显示 expr1 和 expo2 的预期输出

sp.collect(expr1, f) 工作得很好,但 sp.collect(expr2, f) 失败并出现已知错误,因为实现尚未完成...

【讨论】:

【解决方案2】:

这并没有解决错误(这显然是一个错误),但是对于显式获取简单函数的导数的情况,一种解决方法是仅使用 doit() 函数。在这种情况下,这看起来像(按照问题中发布的代码):

simplify(expr1.doit())

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-28
    • 2017-04-10
    • 1970-01-01
    • 2012-12-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多