SpecialFunctions.jl
SpecialFunctions.jl copied to clipboard
Added faddeeva_w function
"w", the mother of all Faddeva functions, can be useful. This function is named wofz in python/scipy (Cf. http://ab-initio.mit.edu/wiki/index.php/Faddeeva_Package). It is called faddeeva_w in this PR.
I would just call it faddeeva(z)
if we add this; faddeeva_w
seems unnecessarily verbose since there is no other "Faddeeva" function in common parlance.
I'm a little skeptical that we need to add it explicitly, however, since it is basically redundant with erfcx
: fadeeva(z) = erfcx(-im*z)
.
We can think to implement raw original C-functions with relerr argument as faddeeva.z(z, relerr), faddeeva.erf(z, relerr), etc. Hence the choice of faddeeva_w instead of faddeeva. But capitalized form Faddeeva.z(z, relerr), Faddeeva.erf(z, relerr) etc. can be choosen for raw functions and faddeeva(z) for high precision function.
About the redundancy, there is a modest gain with fadeeva_w(z) over erfcx(-im*z): between 5% and 7% on timing tests.
julia> w(z)=SpecialFunctions.erfcx(-im*z)
w (generic function with 1 method)
julia> @btime w(2.1)
30.296 ns (0 allocations: 0 bytes)
0.012155178329914935 + 0.3180730926015565im
julia> @btime SpecialFunctions.faddeeva_w(2.1)
28.904 ns (0 allocations: 0 bytes)
0.012155178329914935 + 0.3180730926015565im
julia> @btime w(0.1)
21.997 ns (0 allocations: 0 bytes)
0.9900498337491681 + 0.11208866436449542im
julia> @btime SpecialFunctions.faddeeva_w(0.1)
20.607 ns (0 allocations: 0 bytes)
0.9900498337491681 + 0.11208866436449542im
About the redundancy, there is a modest gain with fadeeva_w(z) over erfcx(-im*z): between 5% and 7% on timing tests.
I can believe that, except:
-
You can probably make it a bit faster by using
erfcx(Complex(imag(z), -real(z)))
if this 5% difference matters. -
In real applications, the fadeeva function is typically combined with other calculations, e.g. to compute Voigt profiles, and the
-im*z
calculation can often be combined with the other calculations at no cost.
Internally, the Faddeeva C code expresses things in terms of the Faddeeva function, but this is a bit of an implementation detail…
(The relationship to erfcx
is precisely why I didn't wrap this function in my initial work to connect this to Julia: JuliaLang/julia#1808. Actually, putting this in Julia was my very first pull request to Julia JuliaLang/julia#1799. That may not be an argument in favor of my design choices back then 😉.)
That being said, if someone googles a formula for e.g. Voigt profiles and finds something in terms of w(z), it is a bit friendlier if we provide a faddeeva(z)
function directly rather than requiring them to understand the relationship to erfcx
.
If we choose to withdraw this PR, maybe the documentation can be completed to say that w function (as python scilab.special.wofz) can be defined by the user as erfcx(Complex(imag(z), -real(z))). Just to educate faddeeva newbies. For them Julia is lacking something.
It's probably easier to just add a faddeeva(z)
function than to try and get users to use erfcx
for this.
There was a crosspost between us. As you are inclined to keep this PR, the function is renamed now.
Should also add it to the exports
list in SpecialFunctions.jl
.
This PR reminds me of another thing I don't like about the Faddeeva function: unlike erfcx
, it doesn't give real outputs for real inputs, which makes erfcx
a much nicer way to present essentially the same function. (faddeeva
gives real outputs for purely imaginary inputs.)
You are right, but you need to take into account the "marketing" aspect for non specialists of thoses functions. Reading without high concentration the page http://ab-initio.mit.edu/wiki/index.php/Faddeeva_Package, Julia seems less complete than other language libraries.
@stevengj Should we resolve conflicts and merge this?
Resolved the conflicts.
Merge?
I guess it's fine, though I'm not super enthusiastic as it's mostly just a "marketing" function. But at least the implementation is short and the name is unlikely to conflict with anything else.
needs another update.
It seems like this bitrotted away. Since we had got it close enough, it would be nice to get this in.
Codecov Report
Patch coverage: 100.00
% and project coverage change: +0.07
:tada:
Comparison is base (
07a890c
) 94.25% compared to head (c9c73ac
) 94.32%.
Additional details and impacted files
@@ Coverage Diff @@
## master #88 +/- ##
==========================================
+ Coverage 94.25% 94.32% +0.07%
==========================================
Files 14 14
Lines 2908 2909 +1
==========================================
+ Hits 2741 2744 +3
+ Misses 167 165 -2
Flag | Coverage Δ | |
---|---|---|
unittests | 94.32% <100.00%> (+0.07%) |
:arrow_up: |
Flags with carried forward coverage won't be shown. Click here to find out more.
Impacted Files | Coverage Δ | |
---|---|---|
src/SpecialFunctions.jl | 100.00% <ø> (ø) |
|
src/erf.jl | 100.00% <100.00%> (ø) |
|
src/beta_inc.jl | 92.51% <0.00%> (+0.29%) |
:arrow_up: |
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.
:umbrella: View full report at Codecov.
:loudspeaker: Do you have feedback about the report comment? Let us know in this issue.
This PR will be 5 years old next month! Steven and I have formally reviewed and approved and other commenters have suggested support, so let's merge it before we forget and have to rebase it again in a couple of years. Thanks for the contribution and for your patience, @fp4code!