-
Notifications
You must be signed in to change notification settings - Fork 97
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Exponential integral function #236
Conversation
(@augustt198 has been working on this with me as part of UROP project at MIT.) |
You did a bunch of benchmarks against external codes — it would be good to post a few of those here. |
Can we now provide complex support for |
src/expint.jl
Outdated
x < 4.0 && return @E₁_cf64(x, 16, [5.114292670961982, -1.2789140459431323, 0.22066200334871455, -0.015067049382830766]) | ||
x < 6.1 && return @E₁_cf64(x, 14, [4.194988480897909, -0.7263593325667503, 0.08956574399359891, -0.00434973529065973]) | ||
x < 8.15 && return @E₁_cf64(x, 9, [3.0362016309948228, -0.33793806630590445, 0.029410409377178114, -0.0010060498260648586]) | ||
x < 25.0 && return @E₁_cf64(x, 8, [2.5382065303376895, -0.18352177433259526, 0.011141562002742184, -0.0002634921890930066]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe just use ratfn_minimax from https://github.com/simonbyrne/Remez.jl/blob/master/src/Remez.jl?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ApproxFun claims that a degree-16 polynomial gives machine precision over the 2.15..3.0 interval, for example, and presumably a minimax function could do even better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that you will want to pass a weighting function of 1/E₁ to ratfn_minimax
so that it minimizes the maximum relative error.
Tests are currently failing, for example:
for example
|
test failure:
The relative error in the real part is |
@test_throws ArgumentError expint(-50+100im, 5+5im) ⩭ 0.00004495913300988524775299480665674170202100859018442234 - 0.00003791061255142431660134050245626121520797056806394134im | ||
@test_throws ArgumentError expint(0.0001-100im, 5+5im) ⩭ -0.0000670979311229384710017493655410977414867979779532195 + 0.0000229212453762433221017163627753752485911057259666081im | ||
@test_throws ArgumentError expint(-100-100im, 5+5im) ⩭ -6.08640887739723453551143736571517308449904372104665e86 - 1.89339595225376542869023397967131390592967463726985e87im | ||
@test_throws ArgumentError expint(-67.7427839203913 - 53.20793098548715im, -18.33277989291684 + 5.734337337627761im) ⩭ -8.98320096334454197835241406421715692910936300308912e64 + 5.24063785033491832811625264321940307636652348236306e64im |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
real ν > 50 are supported, so we should test some of those cases.
Regarding the failing test, since it seems to just be slightly worse roundoff error in the real part on one machine (and the overall error in z is quite small), I don't think it's worth getting to the bottom of what is probably a compiler quirk — just test it with the lower 5e-12 tolerance from the other tests. |
Note: you can implement the incomplete gamma function in terms of this. To get the equivalent of gamma_inc2(a,x) = let q = expint(1-a,x) * x^a / gamma(a); 1-q, q; end (However, this might give an inaccurate first value, the lower incomplete gamma function ratio, if It actually seems to be significantly faster than our current |
Do you want to make a new minor release for |
Once #263 is fixed, which should happen next week. |
Tagged. Since the api has been stable for a while, and Julia’s package system strongly favors >= 1.0 versions for compatibility tracking, I tagged it as 1.0 |
Should there be documentation for this? |
It's in the "dev" docs; I'm not sure why it hasn't appeared in the "stable" docs yet? |
For some reasons I don't currently understand, documentation is built only on pushes to |
Should be fixed by JuliaRegistries/General#30169 |
Yes, https://juliamath.github.io/SpecialFunctions.jl/stable/ now points to v1.3.0 |
This PR adds the exponential integral
En(ν, z)
for both complex ν and z. The special case ν = 1 is optimized in functionE₁(z)
, which is based on Steven Johnson's code in #19.Not all test cases are passing yet, so this is still a draft.
TODO:
E₁(z)
Polynomials.jl
dependencyevalpoly
En(ν, z)
Inf
En(41 - 23im, 30 + 404im)
fails