I am trying to use this factorial in an ErlangC Function.. However my number of Agents can get up to the 300s. With this you can get pretty large numbers. For example. My question is how do I store and calculate these numbers? Is there a way in native SQL. I know I can go to CLR and make an outside function. But for simplicity I would like to keep this native SQL. Really trying to get to 9 and 10 from here. But I will get that done when I solve this one. Thank you in advance for any assistance you can provide.
ALTER FUNCTION [dbo].[Factorial] ( @iNumber int )
RETURNS float
AS
BEGIN
Declare @i float
IF @iNumber <= 1
SET @i = 1
ELSE
SET @i = @iNumber
WHILE @iNumber > 1
BEGIN
SET @i = @i * (@iNumber - 1)
Set @iNumber = @iNumber -1
END
RETURN (@i)
END
ErlangC code is as follows:
ALTER FUNCTION [AMS].[ErlangC]
(
-- Add the parameters for the function here
@m float -- Number of Agents
,@u float -- Traffic floatensity
)
RETURNS float
AS
BEGIN
--Source http://www.mitan.co.uk/erlang/elgcmath.htm Number 6
-- Return Variable
DECLARE @Prob Float -- Probability of Call not being answered immediately and having to wait.
-- Variables
Declare @Numerator Float -- Top of Equation
Declare @Denominator Float -- Bottom of Equation
Declare @Summation float -- Summation part of Denominator
Declare @k float -- increment for summation
--Calculate Numerator
SET @Numerator = Power(@u,@m)/dbo.Factorial(@m)
-- Start Summation with k starting at 0.
SET @k = 0
SET @Summation = 0
While @k < @m-1
Begin
SET @Summation = @Summation + Power(@u,@k)/dbo.Factorial(@k)
SET @k = @k +1
End
--Calculate denominator
SET @Denominator = Power(@u,@m)/dbo.Factorial(@m) + (1-@u/@m)*@Summation
SET @Prob = @Numerator/@Denominator
-- Return the result of the function
RETURN @Prob
END
Well I found someone else's code and it works... But I am not sure why.. basically instead of doing the factorial they do the power and factorial together using a logarithm to get the same number as if you had exponentially multiplied out the numbers.
ALTER FUNCTION [dbo].[PowerFactorial] ( @m float, @u float)
RETURNS float
AS
BEGIN
Declare @counter float --counter
Declare @total float -- return value
SET @counter = 1
SET @total = 0
WHILE @counter <= @u
BEGIN
SET @total = @total + Log(@m/@counter)
Set @counter= @counter + 1
END
RETURN Exp(@total)
END
Which would change ErlangC to this.
ALTER FUNCTION [AMS].[ErlangC]
(
-- Add the parameters for the function here
@m float -- Number of Agents
,@u float -- Traffic intensity
)
RETURNS float
AS
BEGIN
--Source http://www.mitan.co.uk/erlang/elgcmath.htm Number 6
-- Return Variable
DECLARE @Prob Float -- Probability of Call not being answered immediately and having to wait.
-- Variables
Declare @Numerator Float -- Top of Equation
Declare @Denominator Float -- Bottom of Equation
Declare @Summation float -- Summation part of Denominator
Declare @k float -- increment for summation
--Calculate Numerator
SET @Numerator = dbo.PowerFactorial(@u,@m)
-- Start Summation with k starting at 0.
SET @k = 0
SET @Summation = 0
While @k < @m-1
Begin
SET @Summation = @Summation + dbo.PowerFactorial(@u,@k)
SET @k = @k +1
End
--Calculate denominator
SET @Denominator = dbo.PowerFactorial(@u,@m) + (1-@u/@m)*@Summation
SET @Prob = @Numerator/@Denominator
-- Return the result of the function
RETURN @Prob
END
If anyone has any insight on how the function works please comment. Thanks..