Mathematica中的复杂误差函数

时间:2011-07-24 05:47:15

标签: wolfram-mathematica

complex error function w(z)定义为e^(-x^2) erfc(-ix)。使用上面定义的w(z)的问题是erfc倾向于爆发出更大的x(由指数变为0补充所以一切都保持很小),因此Mathematica恢复到使生命非常缓慢的任意精度计算。该功能用于实现voigt轮廓 - 一种常用于光谱学和其他相关领域的线形。现在我正在回复计算一次线条形状并使用插值来加快速度,但这并不能让我轻易地改变线条形状的参数(或适合它们)。

scipy有一个很好的快速实现w(z)为scipy.special.wofz,我想知道Mathematica中是否有一个等价物。

5 个答案:

答案 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

相关问题