public static double logregularizedGammaP(final double a,final double x){
  if (Double.isNaN(a) || Double.isNaN(x) || (a <= 0.0)|| (x < 0.0)) {
    return Double.NaN;
  }
  if (x == 0.0) {
    return Double.NEGATIVE_INFINITY;
  }
  if (x >= a + 1) {
    return Math.log(1.0 - regularizedGammaQ(a,x));
  }
  double del=1.0 / a;
  double sum=del;
  for (int n=1; n < Integer.MAX_VALUE; n++) {
    del*=x / (a + n);
    sum=sum + del;
    if (Math.abs(del / sum) < NUM_PRECISION || sum >= Double.POSITIVE_INFINITY) {
      break;
    }
  }
  if (Double.isInfinite(sum)) {
    return 0;
  }
  return -x + (a * Math.log(x)) - logGamma(a) + Math.log(sum);
}

public static double logregularizedGammaP ( final double a , final double x ) { if ( Double . isNaN ( a ) || Double . isNaN ( x ) || ( a <= 0.0 ) || ( x < 0.0 ) ) { return Double . NaN ; } if ( x == 0.0 ) { return Double . NEGATIVE_INFINITY ; } if ( x >= a + 1 ) { return Math . log ( 1.0 - regularizedGammaQ ( a , x ) ) ; } double del = 1.0 / a ; double sum = del ; for ( int n = 1 ; n < Integer . MAX_VALUE ; n ++ ) { del *= x / ( a + n ) ; sum = sum + del ; if ( Math . abs ( del / sum ) < NUM_PRECISION || sum >= Double . POSITIVE_INFINITY ) { break ; } } if ( Double . isInfinite ( sum ) ) { return 0 ; } return - x + ( a * Math . log ( x ) ) - logGamma ( a ) + Math . log ( sum ) ; }
returns the regularized gamma function log p ( a , x ) . includes the quadrature way of computing . todo : find " the " most accurate version of this . we seem to agree with others for the first 10 + digits , but diverge a bit later than that .
