Skip to content

Conversation

@heltonmc
Copy link
Member

@heltonmc heltonmc commented Sep 24, 2022

This PR gives dedicated routines for the airy functions instead of relying on the relations to Bessel functions. The first thing this allows is significantly more accuracy than we had before in whole domain (for airybi these are roughly 4 more digits accurate). I've updated the tests to reflect that.

The second thing is they are much faster now.

julia> @benchmark SpecialFunctions.airybi(z) setup=(z = 4.0)
BenchmarkTools.Trial: 10000 samples with 10 evaluations.
 Range (min  max):  1.257 μs   2.107 μs  ┊ GC (min  max): 0.00%  0.00%
 Time  (median):     1.267 μs              ┊ GC (median):    0.00%
 Time  (mean ± σ):   1.271 μs ± 27.456 ns  ┊ GC (mean ± σ):  0.00% ± 0.00%

       ▂▄▄█▇▇▅▃▁                                              
  ▁▂▄▅██████████▆▅▄▃▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▂▂▂▂▂▂▂▂▂▂▂▂▁▁▁▁▁ ▂
  1.26 μs        Histogram: frequency by time        1.31 μs <

 Memory estimate: 16 bytes, allocs estimate: 1.

julia> @benchmark airybi(z) setup=(z = 4.0)
BenchmarkTools.Trial: 10000 samples with 988 evaluations.
 Range (min  max):  46.224 ns  79.481 ns  ┊ GC (min  max): 0.00%  0.00%
 Time  (median):     47.749 ns              ┊ GC (median):    0.00%
 Time  (mean ± σ):   48.534 ns ±  3.767 ns  ┊ GC (mean ± σ):  0.00% ± 0.00%

  ▃  █▄                                                     ▁ ▁
  █▁▄██▄▄▅▇▇▇▆▅▆▅▆▆▆▇██▆▆▇▅▅▅▄▆▅▄▄▃▄▄▄▃▄▃▃▄▃▄▄▁▃▄▃▁▁▃▄▃▃▁▄▆▇█ █
  46.2 ns      Histogram: log(frequency) by time      69.3 ns <

 Memory estimate: 0 bytes, allocs estimate: 0.

So having dedicated routines allows for much better accuracy and speed. Of course, I have also added support for the entire complex plane. The motivation for this is some of the uniform asymptotic expansions for bessel functions require evalulation of the airy functions (https://dlmf.nist.gov/10.20) so this may come in handy as we look at those for complex plane.

Of course there are still some domains I'm not too happy with in the complex plane. I will add notes in the file on this. I chatted with @cgeoga and a potential use here is to use the hypergeometric functions or the exponentially improved functions to try and bridge domains. We can piece that together better in the future.

I still have a couple of things to finish up on this. Mainly tidying up and adding docs to this but also getting rid of some of those constant gamma calls. There is a lot of code overlap that could be simplified especially in the asymptotic expansions. However, what we want to overlap with will depend if we want to compute both airyai and airyaiprime or airyai and airybi. Just depends. It might be something we revisit in the future. Looking at the asymptotic expansions we will want airyai and airyprime so it might best to combine those....

Need to also go through and think more carefully about type promotions. I don't think we need to actually promote to float64 in a lot of the algorithms this is just left over from things I was trying.

@codecov
Copy link

codecov bot commented Sep 24, 2022

Codecov Report

Base: 94.08% // Head: 94.17% // Increases project coverage by +0.08% 🎉

Coverage data is based on head (9cd17e1) compared to base (8e349fd).
Patch coverage: 95.29% of modified lines in pull request are covered.

Additional details and impacted files
@@            Coverage Diff             @@
##           master      #51      +/-   ##
==========================================
+ Coverage   94.08%   94.17%   +0.08%     
==========================================
  Files          18       18              
  Lines        1539     1820     +281     
==========================================
+ Hits         1448     1714     +266     
- Misses         91      106      +15     
Impacted Files Coverage Δ
src/recurrence.jl 100.00% <ø> (ø)
src/math_constants.jl 66.66% <50.00%> (-6.07%) ⬇️
src/gamma.jl 83.33% <83.33%> (+0.40%) ⬆️
src/besselk.jl 97.46% <84.21%> (-1.48%) ⬇️
src/airy.jl 97.43% <97.36%> (-2.57%) ⬇️
src/besseli.jl 98.51% <100.00%> (+0.01%) ⬆️

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report at Codecov.
📢 Do you have feedback about the report comment? Let us know in this issue.

@heltonmc
Copy link
Member Author

Ok I've updated the docs and added the appropriate limits for infinite arguments therefore no error is return they will simply return the branches defined by the exponential or 1 / z.

There's one thing I'm still thinking about is how do we want to appropriately promote types in some of the series. For example the besseli series can always be computed without loss of precision but only for real arguments. For complex argument we will need to promote ComplexF32 to ComplexF64 and same happens here for the airy functions (airybi) which can be computed stably for real arguments but not so for imaginary arguments. Need to come up with a good structure to promote Float32 for these use cases.

@heltonmc
Copy link
Member Author

heltonmc commented Sep 27, 2022

Ok I think this is ready to go. I've added tests for Float32 arguments. This function oscillates around the zero axis for negative arguments so it is just easy to promote these to Float64. I'm open to other ideas the best way to do this but went with a structure like.

function airyai_power_series(x::ComplexOrReal{T}; tol=eps(T)) where T
    S = eltype(x)
    ...
   ...
    for i in 0:MaxIter
        ...
        abs(t) < tol * abs(ai1) && break
       ...
    end
    return ...
end
airyai_power_series(x::Float32) = Float32(airyai_power_series(Float64(x), tol=eps(Float32)))
airyai_power_series(x::ComplexF32) = ComplexF32(airyai_power_series(ComplexF64(x), tol=eps(Float32)))

Here is a plot of the relative errors in the entire complex plane compared to the special functions implementation which is only accurate to like 1e-12-1e-13 in some domains anyway.
airyai_error

@heltonmc
Copy link
Member Author

@oscardssmith Ok with merging?

@heltonmc heltonmc merged commit 32d9bbe into master Oct 11, 2022
@heltonmc heltonmc deleted the complex_besseli branch October 11, 2022 04:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants