use commons-math3 for poisson dist

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1901661 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
PJ Fanning 2022-06-05 09:49:10 +00:00
parent 5bd31b6f8e
commit 81b4d6cd69

View File

@ -17,6 +17,7 @@
package org.apache.poi.ss.formula.functions;
import org.apache.commons.math3.distribution.PoissonDistribution;
import org.apache.poi.ss.formula.OperationEvaluationContext;
import org.apache.poi.ss.formula.eval.BoolEval;
import org.apache.poi.ss.formula.eval.ErrorEval;
@ -30,16 +31,6 @@ public class Poisson implements FreeRefFunction {
private static final double DEFAULT_RETURN_RESULT = 1;
/** All long-representable factorials */
private static final long[] FACTORIALS = {
1L, 1L, 2L,
6L, 24L, 120L,
720L, 5040L, 40320L,
362880L, 3628800L, 39916800L,
479001600L, 6227020800L, 87178291200L,
1307674368000L, 20922789888000L, 355687428096000L,
6402373705728000L, 121645100408832000L, 2432902008176640000L };
/**
* This checks is x = 0 and the mean = 0.
* Excel currently returns the value 1 where as the
@ -61,25 +52,6 @@ public class Poisson implements FreeRefFunction {
}
}
private static double probability(int k, double lambda) {
return Math.pow(lambda, k) * Math.exp(-lambda) / factorial(k);
}
private static double cumulativeProbability(int x, double lambda) {
double result = 0;
for(int k = 0; k <= x; k++){
result += probability(k, lambda);
}
return result;
}
private static long factorial(final int n) {
if (n < 0 || n > 20) {
throw new IllegalArgumentException("Valid argument should be in the range [0..20]");
}
return FACTORIALS[n];
}
@Override
public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) {
return evaluate(args, ec.getRowIndex(), ec.getColumnIndex());
@ -114,7 +86,10 @@ public class Poisson implements FreeRefFunction {
// truncate x : as per excel function def
boolean cumulative = ((BoolEval)arg2).getBooleanValue();
double result = cumulative ? cumulativeProbability((int) x, mean) : probability((int) x, mean);
PoissonDistribution poissonDistribution = new PoissonDistribution(mean);
double result = cumulative ?
poissonDistribution.cumulativeProbability((int) x) :
poissonDistribution.probability((int) x);
// check the result
NumericFunction.checkValue(result);