[R] Bessel function with large index value
Martin Maechler
maechler at stat.math.ethz.ch
Fri Nov 20 16:52:22 CET 2009
>>>>> "DS" == David Scott <d.scott at auckland.ac.nz>
>>>>> on Sat, 21 Nov 2009 02:29:38 +1300 writes:
DS> This is a reply to my own question. I thought I had found an answer but
DS> it seems not so (some analysis follows below). Maybe Martin Maechler or
DS> Robin Hankin or Duncan Murdoch may have some ideas---I know the question
DS> is a bit specialized.
Indeed.
The good news is that last winter (when in the Swiss Alps, typically
after enjoying the sun and snow) I've written an experimental and
unpublished R package called 'Bessel'
where I've started to collect bessel implementations /
approximations that I had collected and partly tested in the
past, also looking at what other packages on CRAN had.
My 'Bessel' package depends on my new package 'Rmpfr'
(for arbitrary precision arithmetic), as I really want to
explore the quality of the different Bessel computations, and
for that have wanted access to "infinite" precision arithmetic.
Apropos 'Rmpfr': This has been on R-forge for about a year, and
now become a CRAN package a couple of weeks ago.
Thanks to Brian Ripley and Stefan Theussl, the package is
available for Windows from R-forge, but not yet from CRAN.
For MacOSX, it has not yet been made available in precompiled
form, but there you should be able to build it from the
sources, after installing the (GNU) GMP library, and the MPFR
library which builds on GMP.
Back to Bessel and my experimental code:
In there, I have a function, currently only for the Bessel
I_[\nu] that uses the Debye polynomial series needed for these
cases,
and indeed my function has a 'log' argument.
DS> David Scott wrote:
>> I am looking for a method of dealing with the modified Bessel function
>> K_\nu(x) for large \nu.
>>
>> The besselK function implementation of this allows for dealing with
>> large values of x by allowing for exponential scaling, but there is no
>> facility for dealing with large \nu.
>>
>> What would work for me would be an lbesselK function in the manner of
>> lgamma which returned the log of K_\nu(x) for large \nu. Does anybody
>> have any leads on this?
>>
>> Note that I have trawled through Abramowitz and Stegun and found 9.7.8
>> which doesn't work for me because of the complication in the definition
>> of the x argument. I have also seen a result of Ismail (1977) reported
>> by Barndorff-Nielsen and Blaesild which has the other problem, the
>> treatment of the x argument is too simple.
As my implementation uses A_&_S 9.3.7 for I_nu,
I wonder why you say that that the completely analogous 9.3.8
for K_nu is not appropriate.
>> To do the calculation I am attempting, I need to have the Bessel
>> function in a form that will allow a cancellation with a Gamma function
>> of high order in the denominator.
so, working on the log scale saves "all problems", right?
I think we should further correspond offline on the topic;
given your interest, I guess I should probably make my 'Bessel' available
from R-forge ....
Martin Maechler, ETH Zurich
>> David Scott
>>
>>
DS> After posting I checked the GNU Scientific Library
DS> (http://www.gnu.org/software/gsl/) and found:
DS> ********************
DS> — Function: double gsl_sf_bessel_lnKnu (double nu, double x)
DS> — Function: int gsl_sf_bessel_lnKnu_e (double nu, double x,
DS> gsl_sf_result * result)
DS> These routines compute the logarithm of the irregular modified
DS> Bessel function of fractional order \nu, \ln(K_\nu(x)) for x>0, \nu>0.
DS> ********************
DS> I then recalled that Robin Hankin and Duncan Murdoch had made the GSL
DS> available. I installed the package gsl and investigated the function
DS> bessel_lnKnu.
DS> Unfortunately, it appears that this function has *smaller* range than
DS> besselK when it comes to the index. The following shows it:
DS> library(plyr)
DS> library(gsl)
DS> ### Check calculations using both methods
DS> lnKnu <- maply(expand.grid(x = 100*(1:7), nu = 10*(1:100)), bessel_lnKnu)
DS> lnKnu
DS> Knu <- maply(expand.grid(x = 100*(1:7), nu = 10*(1:100)), besselK)
DS> Knu
DS> lnKnu/log(Knu)
DS> I was expecting what happens with gamma and lgamma
DS> ### Compare gamma function
DS> lgam <- lgamma(100*(1:7))
DS> lgam
DS> gam <- gamma(100*(1:7))
DS> gam
DS> lgam/log(gam)
DS> It seems that bessel_lnKnu is set up to protect against infinity when x
DS> becomes small:
DS> ### Does lnKnu protect against Inf when x goes to zero?
DS> lnnear0 <- maply(expand.grid(x = 0.00000001*(1:10), nu = 10*(0:5)),
DS> bessel_lnKnu)
DS> lnnear0
DS> near0 <- maply(expand.grid(x = 0.00000001*(1:10), nu = 10*(0:5)), besselK)
DS> near0
DS> lnnear0/log(near0)
DS> So, I am still in need of a solution: an implementation of log of Bessel
DS> K which protects against the index nu becoming large.
DS> David Scott
DS> --
DS> _________________________________________________________________
DS> David Scott Department of Statistics
DS> The University of Auckland, PB 92019
DS> Auckland 1142, NEW ZEALAND
DS> Phone: +64 9 923 5055, or +64 9 373 7599 ext 85055
DS> Email: d.scott at auckland.ac.nz, Fax: +64 9 373 7018
DS> Director of Consulting, Department of Statistics
DS> ______________________________________________
DS> R-help at r-project.org mailing list
DS> https://stat.ethz.ch/mailman/listinfo/r-help
DS> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
DS> and provide commented, minimal, self-contained, reproducible code.
More information about the R-help
mailing list