此刻我有以下与sympy有关的“问题”:
我有一个像M = matrix([pi*a, sin(1)*b])
这样的符号表达式,我想lambdify
并将其传递给数值优化器。问题在于,优化器需要函数来输入/输出形状为(n,)
的numpy数组,特别是不是(n,1)
的形状。
现在我已经可以通过以下代码(MWE)实现此目标:
import numpy as np
import sympy as sp
a, b = sp.symbols('a, b')
M = sp.Matrix([2*a, b])
f_tmp = sp.lambdify([[a,b]], M, 'numpy')
fun = lambda x: np.reshape( f_tmp(x), (2,))
现在,这当然是非常丑陋的,因为每次fun
被评估时都需要进行重塑(可能很多次)。有办法避免这个问题吗?根据定义,Matrix
类始终是二维的。我尝试使用sympy
的{{1}}类,但是它们不能与lambdify一起使用。 (符号变量无法识别)
答案 0 :(得分:1)
一种方法是将矩阵转换为嵌套列表并采用第一行:
fun = sp.lambdify([[a, b]], M.T.tolist()[0], 'numpy')
现在fun([2, 3])
是[4, 3]
。这是一个Python列表,而不是NumPy数组,但是优化器(至少是SciPy中的优化器)应该可以。
一个人也可以做
fun = sp.lambdify([[a, b]], np.squeeze(M), 'numpy')
也返回一个列表。
在我的测试中,上述速度同样快,并且比具有包装功能的版本(np.squeeze
或np.reshape
)还快:大约6 µs vs 9 µs。似乎可以消除一个函数调用。