【发布时间】:2021-11-26 15:07:36
【问题描述】:
我有一个通用表达式E,它依赖于X(t)(变量数组)和dX(t)。
有没有从E 获取linear 和quadratic 术语的简单方法?
我的实际代码只有在E 很简单时才有效。
我的目标是得到矩阵M、V、K、A、B和C这样E = dX @ M @ dX + dX @ V @ X + X @ K @ X + A @ dX + B @ X + C
例如
import sympy as sp
t = sp.symbols("t")
x = sp.Function("x")(t)
y = sp.Function("y")(t)
dx = sp.diff(x, t)
dy = sp.diff(y, t)
X = sp.Array([x, y])
dX = sp.Array([dx, dy])
E = 7*(dx**2) + 2*dx*dy + 6*(dy**2) # M = [[7, 1],
# [1, 6]]
E += 4*dx*x + 6*dx*y + 3*dy*x + 5*dy*y # V = [[4, 6],
# [3, 5]]
E += (-3)*x**2 + (-4)*x*y + (-5)*y**2 # K = [[-3, -2],
# [-2, -5]]
E += 1*dx + (-7)*dy # A = [1, -7]
E += (-5)*x + 9*y # B = [-5, 9]
E += 80 # C = 80
到目前为止,我所做的只是取导数并手动减去项。 当我有常量值时,以下代码可以正常工作:
diff = sp.derive_by_array
def dot(A, B):
# Matrix multiplication of A and B
ndimA = len(sp.shape(A))
C = sp.tensorproduct(A, B)
D = sp.tensorcontraction(C, (ndimA-1, ndimA))
return D
M = diff( diff(E, dX), dX)/2
E -= dot(dX, dot(M, dX))
V = diff( diff(E, X), dX)
E -= dot(dX, dot(V, X))
K = diff( diff(E, X), X)/2
E -= dot(X, dot(K, X))
A = diff(E, dX)
E -= dot(A, dX)
B = diff(E, X)
E -= dot(B, X)
C = sp.expand(E)
但是当我输入非常数项时,结果是错误的。例如E = cos(x):
# expected
M = [[0, 0],
[0, 0]]
V = [[0, 0],
[0, 0]]
K = [[0, 0],
[0, 0]]
A = [0, 0]
B = [0, 0]
C = cos(x)
# gotten
M = [[0, 0],
[0, 0]]
V = [[0, 0],
[0, 0]]
K = [[-cos(x)/2, 0],
[0, 0]]
A = [0, 0]
B = [-x(t)**2*sin(x(t))/2 + x(t)*cos(x(t)) - sin(x(t)), 0]
C = x(t)**3*sin(x(t))/2 - x(t)**2*cos(x(t))/2 + x(t)*sin(x(t)) + cos(x(t))
我寻找使用Advanced Expression Manipulation 和函数srepr 分解E 的解决方案,但我认为它应该存在一种更简单的方法来做到这一点。
【问题讨论】: