complex error function w(z)定义为e^(-x^2) erfc(-ix)
。使用上面定义的w(z)的问题是erfc倾向于爆发出更大的x(由指数变为0补充所以一切都保持很小),因此Mathematica恢复到使生命非常缓慢的任意精度计算。该功能用于实现voigt轮廓 - 一种常用于光谱学和其他相关领域的线形。现在我正在回复计算一次线条形状并使用插值来加快速度,但这并不能让我轻易地改变线条形状的参数(或适合它们)。
scipy有一个很好的快速实现w(z)为scipy.special.wofz
,我想知道Mathematica中是否有一个等价物。
答案 0 :(得分:5)
复杂误差函数可以用Hermite“多项式”H_{-1}(x)
来编写:
In[1]:= FullSimplify[2 HermiteH[-1,I x] == Sqrt[Pi] Exp[-x^2] Erfc[I x]]
Out[1]= True
并且评估不会遭受许多下溢和溢出
In[68]:= 2 HermiteH[-1, I x] /. x -> 100000.
Out[68]= 6.12323*10^-22 - 0.00001 I
In[69]:= Sqrt[Pi] E^-x^2 Erfc[I x] /. x -> 100000.
During evaluation of In[69]:= General::unfl: Underflow occurred in computation. >>
During evaluation of In[69]:= General::ovfl: Overflow occurred in computation. >>
Out[69]= Indeterminate
也就是说,一些快速测试表明,Hermite函数的评估速度要慢于指数和误差函数的乘积...
答案 1 :(得分:4)
无穷远处的一系列展开表明,实部和虚部具有非常不同的尺度。我建议单独计算它们而不是添加它们。下面我使用系列扩展的前几个术语来获得想象的部分。
In[186]:=
w[x_?NumericQ] := {N[Exp[-SetPrecision[x, 25]^2], 20],
N[(3 /(4 Sqrt[\[Pi]] x^5) + 1/(2 Sqrt[\[Pi]] x^3) + 1/(
Sqrt[\[Pi]] x))]}
In[187]:= w[11]
Out[187]= {2.8207700884601354011*10^-53, 0.05150453151309212}
In[188]:= w[1000]
Out[188]= {3.296831478088558579*10^-434295, 0.0005641898656429712}
不确定你想要那么小的真实部分有多么糟糕。如果你可以放弃它,将数字保持在合理的范围内。在某些范围内(或者如果需要高于机器精度),您可能希望在该虚部上使用更多的扩展术语。
Daniel Lichtblau Wolfram Research
答案 2 :(得分:4)
可以使用Dawson integral在Mathematica中显式有效地计算实线上复杂误差函数的实部和虚部:
In[9]:= Sqrt[Pi] Exp[-x^2] Erfc[I x] ==
E^-x^2 Sqrt[\[Pi]] - 2 I DawsonF[x] // FullSimplify
Out[9]= True
这比使用HermiteH[-1,z]
快4倍。
In[10]:= w1[x_] := E^-x^2 Sqrt[\[Pi]] - 2 I DawsonF[x]
w2[x_] := 2 HermiteH[-1, I x]
In[15]:= AbsoluteTiming[w1 /@ Range[-5.0, 5.0, 0.001];]
Out[15]= {2.3272327, Null}
In[16]:= AbsoluteTiming[w2 /@ Range[-5.0, 5.0, 0.001];]
Out[16]= {10.2400239, Null}
答案 3 :(得分:1)
可以从Mathematica运行的复杂错误函数(也称为Faddeeva函数)的语言C程序也可以在RooFit中找到。请阅读Karbach et al. arXiv:1407.0748的文章了解详情。
答案 4 :(得分:0)
只需包装C库libcerf。