繁体   English   中英

SymPy - Kronecker Delta Function 评估

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM