Numerical precision - dawson(x) vs erfcw(real(x+iy))

I am fitting spectroscopy transmission data of molecular gas absorption data with voigt lineshapes; we measure both phase and magnitude of the absorption lines.

For the phase fit, I use the complex error function erfcw when both a doppler (pressure) and lorentzian (collision) component is present, and the Dawson integral when only a doppler component is expected.

I noticed that I don't get the same phase using erfcw or dawson for doppler-only lineshapes. Ideally (i.e. analytically),
dawson(x)*2/sqrt(pi) = imag(erfcw(cmplx(x,0))

I noticed that this relationship is only true for |x|<~5; this is shown in the attached graph created with the macro at the bottom. Can anyone tell me which calculation is more accurate for large x?

thanks,
Fabrizio

macro testIt()<br />
	make/d/o/n=1000 Wdaw, Werf, delta; setscale/I x -50,50, Wdaw, Werf, delta<br />
	Wdaw=2/sqrt(pi)*dawson(x)<br />
	werf=imag(erfcw(cmplx(x,0)))<br />
	delta=abs((wdaw-werf)/werf)<br />
	display delta; ModifyGraph log(left)=1<br />
endmacro


Igor
Hello Fabrizio,

Your macro uses the function erfcw() which is not in my version of IP (obviously my home copy needs an update).

The Dawson integral is computed from a series approximation. The erfc is usually computed from the Hyper-Geometric function which is, in general, a very messy series calculation. In other words both of these are not simple. IIRC the Dawson expression is going to be more accurate closer to zero. For large arguments I still expect the Dawson integral to be more accurate. There is a brief discussion of Dawson's accuracy in the reference provided in the IGOR help file.

If I had to guess (and if accuracy at large x really mattered to me) I'd use Dawson because it is a simpler and more straightforward calculation. If the built-in Dawson function does not provide sufficient accuracy one can look into using better expansions. Feel free to send details of your application and requirements to support@wavemetrics.com if you want us to help.

A.G.
WaveMetrics, Inc.
Igor
Hello Fabrizio,

After a bit more investigation here are some details:

The Dawson integral is evaluated from a series of 24 terms. When x is large (x>20) you are going to see some degradation in accuracy simply because the integrand becomes unstable numerically. Erfcw is said to have accuracy to about 14 digits. The primary expansion in this approach is relatively more stable for large x.

If accuracy is really important you can have a bit more control (at the cost of computation time) using the error function. Note that the Dawson integral can also be evaluated using

Function/c FF(zz)
Variable/C zz

return -cmplx(0,(sqrt(pi)/2))*exp(-zz*zz)*erf(cmplx(0,1)*zz)
End

The advantage here is that erf() in the last expression can take an accuracy parameter. A word of caution though is that for large arguments and decent accuracy the hypergeometric function 1F1() used to compute the erf() can take a long time to converge.

HTH,

A.G.
WaveMetrics, Inc.
fabrizio
Thanks for your answers.

I just had a chance to compare with matlab. In Matlab, I used the built-in Dawson function and implemented the complex error function (aka Faddeeva function) according to J. A. C Weideman, 'Computation of the Complex Error Function', SIAM Journal on Numerical Analysis, Vol. 31, No 5 (Oct. 1994), pp. 1497-1518, using 30 terms.

The Matlab dawson agrees very well with the Igor erfcw, and the Weideman complex error function in Matlab is still doing fairly well, however the Igor Dawson stands apart... (see attached figure). More specifically, the igor Dawson function converges faster (I assume too fast...) towards zero for |x|>5.

I use Igor 6.2.2.2 on windows XP; the erfcw function seems to be part of Igor and is also described in the online and pdf help ... ?
DawsonMatlabIgor.png (56.29 KB)
johnweeks
This is a pretty old thread, but, for what it's worth, Igor 8 will feature a Dawson integral implementation with greatly improved accuracy outside the -5,5 range of inputs, and Dawson will accept complex inputs as well.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
jjweimer

In honor of John's retirement, I shall resurrect this 10 yr old thread. (ha!) I have an option to choose between a Dawson integral form or an error function form of an expression in numerical calculations. My colleague prefers  the former from a first-principled derivation perspective, and I prefer the latter both for ease in making a larger expression dimensionless by removing common factors and for commonality in numerical analysis (i.e. error functions are more "colloquial" than Dawson's integrals).

Just for my own information, I referenced the link below. I am interested in the D+ case.

https://en.wikipedia.org/wiki/Dawson_function

As near as I can now determine, for exact translation between the Dawson integral and error function forms, I must input a complex number to the erf(...) function in Igor Pro and pull off the imaginary component. Hence, the two functions below give the same report for any input.

 

// @brief calculate Dawson integral form
Function cal_Dawson(variable kappa)

	variable vrtn
	vrtn = Dawson(kappa)
	return vrtn
end

// @brief calculate erfi form
Function cal_erfi(variable kappa)

	variable vrtn
	vrtn = (sqrt(Pi)/2)*exp(-kappa^2)*imag(erf(cmplx(0,kappa)))
	return vrtn
end

 

My question is whether the second function can be written directly to "keep it all real"?? By example, just guessing, I tried the function below.

// @brief calculate erfr form
Function cal_erfr(variable kappa)

	variable vrtn
	vrtn = (sqrt(Pi)/2)*exp(kappa^2)*real(erfcw(kappa))
	return vrtn
end

 

For additional background, I am interested in capturing the equivalence only in the range of positive, real kappa. And I am satisfied with a relative accuracy at the ppm level.

 

Igor

Hello JJ,

I wrote the original Dawson function using code that I wrote in the 1980's.  It used quadrature to compute the integral over the range that was good enough for my PhD work.  Some 20 years later JW replaced the code with a function from the Faddeeva package that boasts higher accuracy.  You can read more about the package here:  http://ab-initio.mit.edu/Faddeeva.

Igor's various error functions are calculated using different algorithms with varying levels of accuracy:

Function   Argument   Algorithm
erf              real                 Incomplete gamma: P(1/2, x^2)
erfc             real                  Incomplete gamma: Q(1/2, x^2), or 1+P(1/2, x^2) for x<0
erf              complex          (2z/sqrt(pi)) * 1F1(1/2; 3/2; -z^2)
erfc            complex          1 - erf(z) via the hypergeometric series
erfcw          complex          Poppe & Wijers, ACM TOMS 16(1), 38-46 (1990)
erfcx            real                  Polynomial approximation (fma-based)

For accuracy reasons I'd stay with Dawson based in the Faddeeva package especially in view of the fact that some of the hypergeometric functions are sometimes difficult to push to high accuracy.

HTH,

AG

jjweimer

Thanks AG. Just curious though. As near as I see, if I input a complex number to the error function, I am tapping into the Faddeeva routine just as in the Dawson function. So, the two functions that I report are equivalent ways in Igor Pro to calculate the same value and should exhibit nearly the same accuracy and speed??

Just for further background, my colleague arrived at the Dawson integral form using derivations by hand. The input was Z = sqrt(X) whereby X is constrained to be positive even though foundations require X to be negative. It seems perhaps that Dawson(Z(positive real)) = Dawson(-i*|Z|(negative complex)) (symmetry). My derivations with symbolic math (Maple in this case) resulted in the error function form, whereby Maple's error function input allowed X to be negative, resulting in a complex Z, resulting in a final agreement. I attach a report from within Maple showing three equivalent ways to obtain the same value in the function we are investigating.

Finally, had you asked me about three weeks ago whether I knew anything about Dawson's integral, I would have said ... Isn't there a TV show with that name? But, everyone in college calculus has been introduced to the error function. Hence my desire to provide future readers of our collaborative publication something that is familiar (error function) even as I now better respect the equivalence (and potential benefits) of using the Dawson's integral.

--
JJW

Igor

Hello JJ,

I think you misunderstood the table in my last comment.  If you execute, e.g., 

•print/c erf(cmplx(1,1))

Igor computes the erf() via the HyperGeometric function.

 

AG