形状为(n,)的Sympy lambdify数组

时间:2018-07-03 13:39:11

标签: sympy

此刻我有以下与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一起使用。 (符号变量无法识别)

1 个答案:

答案 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.squeezenp.reshape)还快:大约6 µs vs 9 µs。似乎可以消除一个函数调用。