根據維基百科的文章Voigt profile,在複雜的Faddeeva function瓦特方面Voigt functions U(X,T)和V(X,T)可以表示(Z):
U(x,t) + i*V(x,t) = sqrt(pi/(4*t))*w(i*z)
的Voigt函數H(A,U)可以在U(X,t)的條款
H(a,u) = U(u/a, 1/(4*a**2))/(a*sqrt(pi))
(另請參見DLMF section on Voigt functions。)
表示0
scipy
在scipy.special.wofz
中實現了Faddeeva函數。 利用這一點,這裏的沃伊特功能的實現:
from __future__ import division
import numpy as np
from scipy.special import wofz
_SQRTPI = np.sqrt(np.pi)
_SQRTPI2 = _SQRTPI/2
def voigtuv(x, t):
"""
Voigt functions U(x,t) and V(x,t).
The return value is U(x,t) + 1j*V(x,t).
"""
sqrtt = np.sqrt(t)
z = (1j + x)/(2*sqrtt)
w = wofz(z) * _SQRTPI2/sqrtt
return w
def voigth(a, u):
"""
Voigt function H(a, u).
"""
x = u/a
t = 1/(4*a**2)
voigtU = voigtuv(x, t).real
h = voigtU/(a*_SQRTPI)
return h
你說,你知道的即H值(A,U)是1.410526851411200e-007當a = 0.01和u = 200。我們可以檢查:
In [109]: voigth(0.01, 200)
Out[109]: 1.41052685142231e-07
上面並沒有回答爲什麼當u
大你的代碼不能正常工作的問題。要成功使用quad
,理解你的被積函數總是一個好主意。在你的情況下,當u
很大時,在x = u
附近只有非常小的間隔對積分作出重大貢獻。 quad
沒有檢測到這一點,所以它錯過了整數的很大一部分,並返回一個太小的值。
解決此問題的一種方法是使用quad
的points
參數,其中的點非常接近間隔的終點。例如,我改變了quad
的號召:
integ = inter.quad(lambda x: np.exp(-(np.square(u)-np.square(x))) * np.sin(2*a*(u-x)),
0, u, points=[0.999*u])
隨着這種變化,這裏就是爲voigt(0.01, 200)
你的函數返回:
In [191]: voigt(0.01, 200)
Out[191]: 1.4105268514252487e-07
我沒有爲價值0.999*u
嚴格的理由;這只是一個接近於時間間隔結束的點,以便爲大約200左右的u
提供合理的答案。對被積函數的進一步調查可以給你一個更好的選擇。 (例如,你能找到的最大積的位置的解析表達式?如果是的話,那會比0.999*u
好得多。)
您也可以嘗試調整的epsabs
和epsrel
值,但在我的幾個實驗中,加入了最大影響的論點。
使用'quad'或其他特定的scipy函數是它的一部分嗎?或者您是否需要Voigt功能的實施? –
它只是工作。謝謝 – handroski