簡體   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