Google

i/gamma

yorick banner

Home

Manual

Packages

Global Index

Keywords

Quick Reference


/*
   GAMMA.I

   Gamma function, beta function, and binomial coefficients.

   $Id$
 */
/*    Copyright (c) 1994.  The Regents of the University of California.
                    All rights reserved.  */

/* Algorithms from Numerical Recipes, Press, et. al., section 6.1,
   Cambridge University Press (1988).
 */


func ln_gamma (z)
/* DOCUMENT ln_gamma(z)

     returns natural log of the gamma function.
     Error is less than 2.e-10 for real part of z>=1.

     Use lngamma if you know that all z>=1, or if you don't care much about
     accuracy for z<1.

   SEE ALSO: lngamma, bico, beta
 */
{

  if (structof(z)==complex) big= (z.re>=1.0);
  else big= (z>=1.0);
  list= where(big);

  if (numberof(list)) lg1= lngamma(z(list));
  list= where(!big);
  if (numberof(list)) {
    z= z(list);

    lg2= log(pi/sin(pi*z)) - lngamma(1.0-z)
  }
  return merge(lg1,lg2,big);
}


func lngamma (x)
/* DOCUMENT lngamma(x)

     returns natural log of the gamma function.
     Error is less than 2.e-10 for real part of x>=1.
     Use ln_gamma if some x<1.

   SEE ALSO: ln_gamma, bico, beta
 */
{
  tmp= x+4.5;
  tmp-= (x-0.5)*log(tmp);
  ser= 1.0 + 76.18009173/x - 86.50532033/(x+1.) + 24.01409822/(x+2.) -
    1.231739516/(x+3.) + 0.120858003e-2/(x+4.) - 0.536382e-5/(x+5.);
  return -tmp+log(2.50662827465*ser);
}


func bico (n,k)
/* DOCUMENT bico(n,k)
     returns the binomial coefficient n!/(k!(n-k)!) as a double.

   SEE ALSO: ln_gamma, beta
 */
{

  return floor(0.5+exp(lngamma(n+1.)-lngamma(k+1.)-lngamma(n-k+1.)));
}


func beta (z,w)
/* DOCUMENT beta(z,w)

     returns the beta function gamma(z)gamma(w)/gamma(z+w)

   SEE ALSO: ln_gamma, bico
 */
{

  return exp(lngamma(z)+lngamma(w)-lngamma(z+w));
}

func erfc(x)
/* DOCUMENT erfc(x)

     returns the complementary error function 1-erf with fractional

     error less than 1.2e-7 everywhere.
 */
{
  z= abs(x);
  t= 1.0/(1.0+0.5*z);
  ans= t*exp(-z*z +

	     poly(t, -1.26551223, 1.00002368, 0.37409196, 0.09678418,
		  -0.18628806, 0.27886807, -1.13520398, 1.48851587,
		  -0.82215223, 0.17087277));
  z= sign(x);
  return ans*z + (1.-z);
}