T.Setso - 1 year ago 169
C Question

# Poisson calculation (erlang C)

i posted this before, user told me to post it on codereview. i did, and they closed it...so one more time here: (i deleted the old question)

I have these formulas:
http://i.stack.imgur.com/nZzLd.png

and I need the Poisson formulas for the erlangC formula:

http://www.mitan.co.uk/erlang/elgcpois.gif

I tried to rebuild the formulas in C:

``````double getPoisson(double m, double u, bool cumu)
{
double ret = 0;
if(!cumu)
{
ret = (exp(-u)*pow(u,m)) / (factorial(m));
}
else
{
double facto = 1;
double ehu = exp(-u);
for(int i = 0; i < m; i++)
{
ret = ret + (ehu * pow(u,i)) / facto;
facto *= (i+1);
}
}
return ret;
}
``````

The Erlang C Formula:

``````double getErlangC(double m, double u, double p)
{
double numerator = getPoisson(m, u, false);
double denominator = getPoisson(m, u, false) + (1-p) * getPoisson(m, u, true);
return numerator/denominator;
}
``````

The main problem is, the
`m`
parameter in
`getPoisson`
is a big value (>170)
so it wants to calculate >170! but it cannot handle it. I think the primitive data types are too small to work correctly, or what do you say?

BTW: This is the factorial function I use for the first Poisson:

``````double factorial(double n)
{
if(n >= 1)
return n*factorial(n-1);
else
return 1;
}
``````

Some samples:

Input:

``````double l = getErlangC(50, 48, 0.96);
printf("%g", l);
``````

Output:

``````0.694456 (correct)
``````

Input:

``````double l = getErlangC(100, 96, 0.96);
printf("%g", l);
``````

Output:

``````0.5872811 (correct)
``````

if i use a value higher than 170 for the first parameter (m) of getErlangC like:

Input:

``````double l = getErlangC(500, 487, 0.974);
printf("%g", l);
``````

Output:

``````naN (incorrect)
``````

Excepted:

``````0.45269
``````

How's my approach? Would be there a better way to calculate Poisson and erlangC?

Some Info: Excel has the POISSON Function, and on Excel it works perfekt... would there be a way to see the algorithm(code) EXCEL uses for POISSON?

`(pow(u, m)/factorial(m))` can be expressed as a recursive loop with each element shown as u/n where each n is an element of m!.

``````double ratio(double u, int n)
{
if(n > 0)
{
// Avoid the ratio overflow by calculating each ratio element
double val;
val = u/n;
return val*ratio(u, n-1);
}
else
{
// Avoid division by 0 as power and factorial of 0 are 1
return 1;
}
}
``````

Note that if you want to avoid recursion, you can do it as a loop as well

``````double ratio(double u, int n)
{
int i;
// Avoid the ratio overflow by calculating each ratio element
// default the ratio to 1 for n == 0
double val = 1;
// calculate the next n-1 ratios and put them into the total
for (i = 1; i<=n; i++)
{
// Put in the next element of the ratio
val *=  u/n;
}
// return the final value of the ratio
return val;
}
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download