SymPy:具有2D输入的lambdify

2024-04-28 07:42:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我在计算一个方阵V,它的每个元素都是我用sympy计算的积分。我只计算一个定积分V_nm,其结果是一个具有符号指数mn的数值表达式。说V_nm看起来像这样:

>>> V_nm
sin(3*n)*cos(m)

现在我想用mn作为数组的索引,从V_nm中生成一个二维数值(非符号!)矩阵。假设对于2x2矩阵,给定V_nm的结果将是:

[[sin(3)cos(1) sin(3)cos(2)]
 [sin(6)cos(1) sin(6)cos(2)]]

也就是说,n指定列,m指定行。(注意:我从1开始mn,而不是0,但这并不重要)

我如何做到这一点?
我知道我可以在列表理解中使用V_nm.subs([(n, ...), (m, ...)]),然后使用evalf(),但这是一条漫长的道路。我希望通过lambdify实现这一点。我知道如何对一维数组使用lambdify。你能告诉我如何在二维阵列上实现它吗


Tags: 元素列表表达式符号矩阵数组sincos
2条回答

你所问的看起来不像是一个标准的功能。但通过两个步骤,这是可能的。首先lambdify表达式,然后创建一个函数,通过numpy的broadcasting生成所需的2D数组:

from sympy import sin, cos, lambdify
from sympy.abc import m, n
import numpy as np

V_mn = sin(3 * n) * cos(m)

V_mn_np = lambdify((m, n), V_mn)
# using list comprehension:
# V_mn_np2D = lambda m, n: np.array([[V_mn_np(i, j) for j in range(n)] for i in range(m)])
# using numpy's broadcasting (faster for large arrays):
V_mn_np2D = lambda m, n: V_mn_np(np.arange(m)[:, None], np.arange(n))

V_mn_np2D(2, 2)

要使编号从1而不是0开始,请使用np.arange(1, m+1)np.arange(1, n+1)

作为测试,像100 * m + n这样的函数可以很容易地验证该方法是否按预期工作

W_mn = 100 * m + n

W_mn_np = lambdify((m, n), W_mn)
W_mn_np2D = lambda m, n: W_mn_np(np.arange(1, m+1)[:, None], np.arange(1, n+1))

W_mn_np2D(2, 3)

输出:

array([[101, 102, 103],
       [201, 202, 203]])

有一个Symphy的FunctionMatrix专门针对这种情况。请注意,它使用基于零的索引:

In [1]: m, n, i, j = symbols('m, n, i, j')                                                                                        

In [2]: V_nm = FunctionMatrix(m, n, Lambda((i, j), 100*(i+1) + (j+1)))                                                            

In [3]: V_nm                                                                                                                      
Out[3]: [100⋅i + j + 101]

In [4]: V_nm.subs({m:2, n:3}).as_explicit()                                                                                       
Out[4]: 
⎡101  102  103⎤
⎢             ⎥
⎣201  202  203⎦

In [5]: lambdify((m, n), V_nm)(2, 3)                                                                                              
Out[5]: 
array([[101., 102., 103.],
       [201., 202., 203.]])

相关问题 更多 >