JuliaLang/julia — pull request #1799 by stevengj (2012-12-20 22:17:49+00:00)
Title: add complex error functions http://ab-initio.mit.edu/Faddeeva

This patch adds support for error functions erf and erfc of arbitrary complex arguments, as well as the related functions erfi, erfcx, and dawson. (It requires the most recent version of openlibm with the Faddeeva package merged.)

Note that the ugliness with the libFaddeeva_wrapper library can go away once ccall supports C99 complex numbers (issue #85).

The code works, but a little tweak from a Julia expert would be useful. In

for f in (:erf, :erfc, :erfcx, :erfi, :Dawson)
@eval begin
global $f
function ($f)(z::Complex128)
local w::Array{Float64,1} = Array(Float64,2)
ccall(($(string("wrapFaddeeva_",f)),:libFaddeeva_wrapper), Void, (Ptr{Complex128},Ptr{Complex128},Float64,), pointer(w), &z, zero(Float64))
return complex128(w[1],w[2])
end
...

I declared w as a local variable to hold the return value. I tried declaring

const w::Array{Float64,1} = Array(Float64,2)

in the surrounding let block instead, similar to how the Bessel and Airy functions are handled, but for some reason this lead to Julia complaining that w was not defined inside the function. I'm guessing that it is some kind of macro hygiene problem, but using $(esc(w)) did not seem to work.