我想计算Fadeeva
函数special.wofz
的二阶导数。Fadeeva
函数与error函数密切相关。因此,如果有人更熟悉erf的答案是赞赏的。
下面是查找wofz
的二阶导数的代码:
import numpy as np
import matplotlib.pyplot as plt
from scipy.special import wofz
def Z(x):
return wofz(x)
## first derivative of wofz (analytically)
def Zp(x):
return -2/1j/np.pi**0.5 - 2*x*Z(x)
##second derivative (analytically)
def Zpp(x):
return (Z(x)+x*Zp(x))*x
x = np.float64(np.linspace(1e4,14e4,1000))
plt.plot(x, Zpp(x).imag,"-")
Zpp_num=np.diff(Zp(x))/np.diff(x) ##calc numerically the second derivative
plt.plot(x[:-1],Zpp_num.imag)
代码生成下一个图:
显然,分析计算有严重的错误。我用的公式是正确的。一定是数字问题。在
问:有人能告诉我是什么导致了这种行为吗?是因为wofz函数的精确性吗?有人知道计算wofz
的算法吗?要得出一个可靠的结果,争论有多大?我找不到任何关于它的信息。另外,我知道我可以对wofz
使用渐近近似来求二阶导数,但是如果可能的话,我想用scipy
。在
正如你所怀疑的,在计算导数时,问题是由数值引起的。正确的二阶导数,正如@clwainwright已经在注释中指出的那样,是
这两个项的虚部表现如下:
证明有两个很小的量,几乎相等,然后计算它们的差。在
更多细节
^{pr2}$想象的部分是
并且
Im(Z)
与Dawson函数D
(scipy.special.dawsn
)成正比问题是你有
为什么这是一个问题是因为the asymptotic expansion of the Dawson function开头是
它的前导项被
Im(Zpp(x))
的第一项吃掉,小的修正给了函数它的值(实际上,前导项是Im(Zpp(x))
最后一项中的1/(2x)
。在所以这个问题是
Zpp
的解析表达式所固有的。您可以尝试重塑分析表达式以解决此数值问题(特别是精度损失),但这并不容易。您也可以尝试使用sympy
。我已经尝试了一段时间了,但没有成功。可能还是有可能的。在按照@Andras Deak的回答,可以解析地计算出high-x展开式,然后使用一些简单的平滑方法在它和scipy函数之间进行插值。实际上在高x展开中有两个项会被取消,所以你得小心一点。在
我得到的答案是:
从而产生以下曲线图:
蓝线是数值导数,绿线是使用展开式的导数。后者实际上在大x下有更好的行为
相关问题 更多 >
编程相关推荐