import java.util.*;
/**
* This class contains a mix of miscellaneous functions used
* by other routines: stirling's approximation and the log of
* the approximation for factorials, the beta function, and the
* log of the gamma function.
*
* @author Eric Ward
* @version August 31, 2006
*/
public class miscFunc
{
// these are constants
final double PI = 3.14159265358979;
final double ROOT2PI = 2.506628274631;
final double LOGRT2PI = 0.91893853320467;
// these variables are used for the gammln function
private double f;
// these variables are used for the gammln function
private double x, y, tmp, ser;
private int j;
final double cof[]={76.18009172947146,-86.50532032941677,24.01409824083091,
-1.231739572450155,0.1208650973866179e-2,-0.5395239384953e-5};
/**
* Constructor for objects of class misc
*/
public miscFunc()
{
}
/**
* This function returns the log of the gamma function.
*
* @param xx, the value to evaluate the function at
* @return val, function value
*/
public double gammln(double xx) {
y=x=xx;
tmp=x+5.5;
ser=1.000000000190015;
tmp -= (x+0.5)*Math.log(tmp);
for (j=0;j<=5;j++) ser += cof[j]/++y;
return (double)(-tmp+Math.log(2.5066282746310005*ser/x));
}
/**
* This method uses Stirling's approximation to generate Beta
* random variables.
*
* @param n1, the first beta parameter
* @param n2, the second beta parameter
* @return double
*/
public double betaFunction(int n1, int n2) {
// beta can be re-written as gamma(n1)*gamma(n2)/gamma(n1+n2)
return stirling(n1-1)*stirling(n2-1)/stirling(n1+n2-1);
}
/**
* This function returns Stirling's approximation to (n!).
*
* @param n, the integer to find the factorial of.
* @return double
*/
public double stirling(int n) {
f = 1.0;
if(n <= 10) {
// calculate the actual factorial
for(j = 1; j <= n; j++) f*=j;
return f;
}
return (ROOT2PI*Math.pow((float)n,(float)n+0.5)*Math.exp(-(double)n));
}
/**
* This function returns the log of Stirling's approximation to (n!).
*
* @param n, the value to find the factorial of.
* @return double
*/
public double logStirling(int n) {
f = 1.0;
if(n <= 10) {
// calculate the actual factorial
// f = f * j
for(j = 1; j <= n; j++) f*=j;
return Math.log(f);
}
return (LOGRT2PI + (n+0.5)*Math.log(n) -(double)n);
}
}