用sympy缓慢替换符号矩阵

Azl*_*lof 5 python numpy sympy substitution differential-equations

我正在研究一个符号雅各J比大小的矩阵QxQ.该矩阵的每个系数包含Q符号,从f[0]f[Q-1].我想要做的是替代每个符号的每一个系数J与已知值g[0]g[Q-1](这是没有更多的符号).我发现最快的方法如下:

for k in range(Q):
    J = J.subs(f[k], g[k])
Run Code Online (Sandbox Code Playgroud)

但是,我觉得这个"基本"操作很长!例如,使用此MCVE:

import sympy
import numpy as np
import time

Q = 17
f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16 = \
    sympy.symbols("f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15 f16")
f = [f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16]
e = np.array([0., 1., 0., -1., 0., 1., -1., -1., 1.,
              2., -2., -2., 2., 3., 0., -3., 0.])
u = np.sum(f * e) / np.sum(f)
function = e * np.sum(f) * (1. + u * e + (u * e)**2 - u * u)
F = sympy.Matrix(function)
g = e * (1. + 0.2 * e + (0.2 * e)**2)

start_time = time.time()
J = F.jacobian(f)
print("--- %s seconds ---" % (time.time() - start_time))

start_time = time.time()
for k in range(Q):
    J = J.subs(f[k], g[k])
print("--- %s seconds ---" % (time.time() - start_time))
Run Code Online (Sandbox Code Playgroud)

我的计算机上的替换需要大约5秒,而雅可比矩阵的计算只需要0.6秒.在另一个(更长的)代码中,替换需要360s Q=37(而jacobian计算为20s)!

而且,当我查看我的运行进程时,我可以看到Python进程有时会在矩阵替换期间停止工作.

  1. 有谁知道这可能来自哪里?
  2. 有没有办法让这个操作更快?