[英]SymPy - Kronecker Delta Function Evaluation
我正在使用 SymPy 对大型方程组进行数值分析。 我的等式的一部分包含一个 Kronecker Delta function 作为脉冲,这样当 q = 0 -> dirac_delta = 1 时,否则 dirac_delta = 0。我需要在 integer 步中对 q = - 10 -> +10 的值执行此操作1.
我的代码的一个简化示例是:
import sympy as sp
import numpy as np
modules = ["numpy", "sympy"]
# Create symbols
q = sp.symbols('q', integer=True)
# Create P_q symbol as a function of q
P_q = sp.symbols('P_q', cls=sp.Function)
P_q = P_q(q)
# Define Equation
# Simplified example KroneckerDelta - when q = 0, P_q = 1, otherwise P_q = 0
P_q_eq = sp.Eq(P_q, sp.KroneckerDelta(0,q))
P_q = sp.KroneckerDelta(0,q)
display(P_q_eq)
# Create a lambda function for fast numerical calculation
lam_P_q = sp.lambdify(q, P_q, modules)
# Define the values of q
num_points = 21
data = np.linspace(-10, 10, num_points, dtype=int)
#print(data)
ans = lam_P_q(data)
print(ans)
在运行时我收到一个错误:
36 #print(data) 37 ---> 38 ans = lam_P_q(data) 39 print(ans) 中的 ValueError Traceback(最近调用最后一次)
在 _lambdifygenerated(q) 1 def _lambdifygenerated(q): ----> 2 return ((1 if 0 == q else 0))
ValueError:具有多个元素的数组的真值不明确。 使用 a.any() 或 a.all()
我的理解是我需要添加 the.any() or.all() 因为 lambdify 正在将数组 q 与单个值 0 进行比较。所以当我使用 .any() or.all() 修改输入数据时然后它返回一个值。
但是,我要求每个 q 值的响应为 0 或 1 - 这样它就是一个取决于 q 值的脉冲响应。
打印(q)
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
我试图将“0”比较值作为长度与 q 相等的零数组提供,但这没有用。
我知道这可以用 scipy 信号 function "signal.unit_impulse(21, 'mid')" 生成,但我不确定如何在 SymPy 格式中将其实现为 lambdify 到 output q,如上所述。 我试图创建一个自定义模块来替换 sp.KroneckerDelta function 来执行此操作,但无法获得有效的解决方案(可能是由于实施不当):
def impulse(num, p):
val = signal.unit_impulse(num, 'mid')
j = p + (num-1)/2
kron_p = int(val[j])
return kron_p
kronecker = {'KroneckerDelta': impulse(21,q)}
modules = [kronecker, "numpy", "sympy"]
我是否需要将 q 的值替换为 lambdify function - 如果是这样,我如何指定要替换的值范围?
我觉得我在我的方法中做了一些根本错误的事情,并且很感激帮助让我认为在 SymPy 中做一件相对简单的事情来工作。 (我对 SymPy 还很陌生,而且肯定还在努力了解它)。 谢谢。
您创建的变量data
是一个列表类型,如下所示:
data = [-10 -9 -8 -7 -6 ... 8 9 10]
lam_P_q(data)
并不意味着采用类型为list
的变量。 它的意思是取一个数字。 例如,在您的情况下: data = -10
要将data
变量中的所有单个数字提供给lam_P_q(data)
,可以使用 for 循环。 以下是您修改后的示例:
import sympy as sp
import numpy as np
from IPython.display import display
modules = ["numpy", "sympy"]
# Create symbols
q = sp.symbols('q', integer=True)
# Create P_q symbol as a function of q
P_q = sp.symbols('P_q', cls=sp.Function)
P_q = P_q(q)
print(P_q)
# Define Equation
# Simplified example KroneckerDelta - when q = 0, P_q = 1, otherwise P_q = 0
P_q_eq = sp.Eq(P_q, sp.KroneckerDelta(0,q))
P_q = sp.KroneckerDelta(0,q)
display(P_q_eq)
# Create a lambda function for fast numerical calculation
lam_P_q = sp.lambdify(q, P_q, modules)
# Define the values of q
num_points = 21
data = np.linspace(-10, 10, num_points, dtype=int)
print(data)
#feeding lam_P_q with numbers and saving answers into the list results
results=[]
for num in data:
ans = lam_P_q(num)
results.append(ans)
print(results)
这是 lambdify 中的错误。 请打开一个同情问题:
https://github.com/sympy/sympy/issues
您可以通过将 KroneckerDelta 重写为 Piecewise 来解决这个问题:
In [12]: P_q
Out[12]:
δ
0,q
In [13]: P_q.rewrite(Piecewise)
Out[13]:
⎧0 for q ≠ 0
⎨
⎩1 otherwise
In [14]: f = lambdify(q, P_q.rewrite(Piecewise), modules)
In [15]: f(data)
Out[15]:
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0.])
这是生成的代码:
In [16]: import inspect
In [18]: print(inspect.getsource(f))
def _lambdifygenerated(q):
return select([not_equal(q, 0),True], [0,1], default=nan)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.