Search code examples
t-sqlsqldatatypesfactoriallargenumber

SQL Factorial ErlangC


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

Solution

  • 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..