namespace HH.WMS.Utils.NPOI.SS.Formula.Functions
|
{
|
using HH.WMS.Utils.NPOI.SS.Formula.Eval;
|
using System;
|
|
public class Poisson : Fixed3ArgFunction
|
{
|
private static double DEFAULT_RETURN_RESULT = 1;
|
/**
|
* This checks is x = 0 and the mean = 0.
|
* Excel currently returns the value 1 where as the
|
* maths common implementation will error.
|
* @param x The number.
|
* @param mean The mean.
|
* @return If a default value should be returned.
|
*/
|
private bool IsDefaultResult(double x, double mean)
|
{
|
|
if (x == 0 && mean == 0)
|
{
|
return true;
|
}
|
return false;
|
}
|
|
private bool CheckArgument(double aDouble)
|
{
|
|
NumericFunction.CheckValue(aDouble);
|
|
// make sure that the number is positive
|
if (aDouble < 0)
|
{
|
throw new EvaluationException(ErrorEval.NUM_ERROR);
|
}
|
|
return true;
|
}
|
|
private double probability(int k, double lambda)
|
{
|
return Math.Pow(lambda, k) * Math.Exp(-lambda) / Factorial(k);
|
}
|
|
private double cumulativeProbability(int x, double lambda)
|
{
|
double result = 0;
|
for (int k = 0; k <= x; k++)
|
{
|
result += probability(k, lambda);
|
}
|
return result;
|
}
|
|
/** All long-representable factorials */
|
private long[] FACTORIALS = new long[] {
|
1L, 1L, 2L,
|
6L, 24L, 120L,
|
720L, 5040L, 40320L,
|
362880L, 3628800L, 39916800L,
|
479001600L, 6227020800L, 87178291200L,
|
1307674368000L, 20922789888000L, 355687428096000L,
|
6402373705728000L, 121645100408832000L, 2432902008176640000L };
|
|
|
public long Factorial(int n)
|
{
|
if (n < 0 || n > 20)
|
{
|
throw new ArgumentException("Valid argument should be in the range [0..20]");
|
}
|
return FACTORIALS[n];
|
}
|
public override ValueEval Evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, ValueEval arg2)
|
{
|
// arguments/result for this function
|
double mean = 0;
|
double x = 0;
|
bool cumulative = ((BoolEval)arg2).BooleanValue;
|
double result = 0;
|
|
try
|
{
|
x = NumericFunction.SingleOperandEvaluate(arg0, srcRowIndex, srcColumnIndex);
|
mean = NumericFunction.SingleOperandEvaluate(arg1, srcRowIndex, srcColumnIndex);
|
|
// check for default result : excel implementation for 0,0
|
// is different to Math Common.
|
if (IsDefaultResult(x, mean))
|
{
|
return new NumberEval(DEFAULT_RETURN_RESULT);
|
}
|
// check the arguments : as per excel function def
|
CheckArgument(x);
|
CheckArgument(mean);
|
|
// truncate x : as per excel function def
|
if (cumulative)
|
{
|
result = cumulativeProbability((int)x, mean);
|
}
|
else
|
{
|
result = probability((int)x, mean);
|
}
|
|
// check the result
|
NumericFunction.CheckValue(result);
|
|
}
|
catch (EvaluationException e)
|
{
|
return e.GetErrorEval();
|
}
|
|
return new NumberEval(result);
|
}
|
}
|
}
|