public inbox for gsl-discuss@sourceware.org
 help / color / mirror / Atom feed
From: Jason Detwiler <jasondet@gmail.com>
To: Brian Gough <bjg@network-theory.co.uk>
Cc: Heikki Orsila <shd@jolt.modeemi.cs.tut.fi>,
	gsl-discuss@sources.redhat.com
Subject: Re: request for Poisson CDF inverse
Date: Wed, 31 Aug 2011 10:51:00 -0000	[thread overview]
Message-ID: <CA+feh_ssYkhikX-p5ZesDMNSzw=VzR7Cg+fNztk5SM=XYB2ESA@mail.gmail.com> (raw)
In-Reply-To: <87hcoc9uvj.wl%bjg@network-theory.co.uk>

It's been a long time since this was discussed, but I came upon this
problem again in my research, and this time I was able to find a
reasonably fast implementation for this function. To be clear, what I
am after is the inverse of gsl_cdf_poisson_P(k, mu) with respect to
mu, i.e. the value of mu such that gsl_cdf_poisson_P(k, mu) = P for
some k, P.  Note that although the Poisson distribution is discrete,
this inverse of its CDF with respect to mu is a continuous function.

The best way I found to solve this is to root-solve f(mu) =
gsl_cdf_poisson_P(k,mu)-P using Newton's method (out to second order,
since the Poisson distribution has nice derivatives that are easy to
calculate). Here is some pseudocode for anyone interested in
implementing it in gsl (I'm still not confident I could do it up to
gsl standards):

// first guess based on variance = mu for Poisson dist:
erf((mu-k)/sqrt(2*mu))/2+0.5 ~= P
double nSigma = erfInverse(2.*P-1.)*sqrt(2.);
// nSigma*sqrt(mu) = k - mu: square both sides and solve quadratic
function for mu
// mu = [2k + nSigma^2 +/- sqrt([2k + nSigma^2]^2 - 4k^2)]/2: choose + for
double b = k + nSigma*nSigma/2.;
double mu = b + sqrt(b*b - k*k);

// Now root-solve f(mu) using 2nd order Newton's method (converges cubicly):
// mu_next = mu - f(mu)/f'(mu) + f''(mu)*f(mu)^2 / f'(mu)^3 / 2
double delta = mu;
double eps = 1.e-8;
while(fabs(delta/mu) > eps) {
  double f1 = poisson(k, mu);
  double f = (poissonCDF(k, mu) - P)/f1;
  double f2 = 1.-k/mu;
  delta = f*(1. + 0.5*f2*f);
  mu += delta;
}
return mu;

Thanks,
Jason

On Tue, Jul 10, 2007 at 7:49 AM, Brian Gough <bjg@network-theory.co.uk> wrote:
> At Mon, 9 Jul 2007 02:39:30 +0300,
> Heikki Orsila wrote:
>> Woud you consider a patch? I might convert the python code I posted
>> into C, and make that the first discrete distribution having an inverse.
>
> The basic code is already there, in the inverse chi-squared
> distribution, since the poisson distribution is related to that.  It's
> mainly a question of testing it in cdf/test.c.
>
> --
> Brian Gough
>

      reply	other threads:[~2011-08-31 10:51 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-07-06  7:30 Jason Detwiler
2007-07-06  9:31 ` Heikki Orsila
2007-07-08 21:54 ` Brian Gough
2007-07-08 23:39   ` Heikki Orsila
2007-07-10 14:49     ` Brian Gough
2011-08-31 10:51       ` Jason Detwiler [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CA+feh_ssYkhikX-p5ZesDMNSzw=VzR7Cg+fNztk5SM=XYB2ESA@mail.gmail.com' \
    --to=jasondet@gmail.com \
    --cc=bjg@network-theory.co.uk \
    --cc=gsl-discuss@sources.redhat.com \
    --cc=shd@jolt.modeemi.cs.tut.fi \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).