Ei Function

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 2

'Computes ONLY the Ei function of a given argument, x.

Where x is a real number


'Not to be confused with Expint(n,x) as this function doesn't compute Expint(n,x)
'Ei(x) = -[int(-x,inf)(exp(-u)*(1/u)*du), where x>0
'To find Ei(-x), the argument x, should be negative when entering values on the spreadsheet
'Computation is done using the Series representation, Continued fraction representation and
'Asymptotic expansion
'==================================================================================================
'The Continued fraction is applied for Ei(-x) values where |x|>=1.
'Ei(-x)=-E1(x) by analytic continuation.
'The Ei(-x) is computed by taking a branch cut on the negative real axis and then, defined
'by analytic continuation on the complex plane. E1(x)=Expint(1,x); it is the case of n=1
'E1(x)= int(x,inf)(exp(-u)*(1/u)*du); where x is in the complex plane and x> 0
'Ei(-x)=-E1(x)
'Applying the more rapidly converging even form of the continued fraction:
'Ei(-x)=-[(exp(x))(1/x+n-(1*n)/x+n+2-(2*(n+1))/x+n+4-...)] where n=1
'The above continued fraction is solved using the Lentz's algorithm.
'==================================================================================================
'The Power series representation is used for two different conditions:
' - To compute Ei(-x) when 0<|x|<=1:
'Ei(-x) = -[-EulerMascheroni Constant - ln(x) - [sum(((-x)^n)/(n*n!));where n starts from 1 to inf];
'where x is now in the complex plane. Since the series representation converges fast enough for
'conditions, 0<x<=1, a maximum value of n=100 was used, although, there are situtations when it
'could exit the loop.
' - To compute Ei(x) when 0<x<=ll:
'where ll is the lower limit for the use of the asymptotic expansion and is given by: ll=|ln(EPS)|
'Ei(x) = Euler-Mascheroni Constant + ln(x) + [sum((x^n)/(n*n!));where n starts from 1 to inf]
'Also a maximum value of n=100 was used
'==================================================================================================
'The Asymptotic expansion is used to approximate larger values of x. When x>=|ln(EPS)|
'Ei(x)~=(exp(x)/x)*(1 + [sum(n!/x^n); where n starts from 1 to inf])
'A maximum value of n=100 was used
'The divergent characteristic of the expansion as the iteration proceeds was also taken in to
'consideration.
'==================================================================================================
'References: Press W.H., Teukolsky S. A., Vetterling W. T. and Flannery B. P. 1986,
' Numerical Recipes in Fortran 77, The Art of Scientific Computing,
' 2nd Ed., Vol 1, (Newyork: Cambridge University Press), p. 216-220
' Adewole, E.S. and Bello, K.O. 2004, Application of the Gauss-Laguerre
' Quadrature for Computing the Exponential Integral Functions, (Ei),
' Society of Petroleum Engineers (Nigeria), SPE 98829, pp. 2.
' Abramowitz, M., and Stegun, I.A. 1964, Handbook of Mathematical Functions,
' Applied Mathematics Series, Volume 55 (Washington: National Bureau of Standards;
' reprinted 1968 by Dover Publications, New York), Chapter 5.
'==================================================================================================
Option Explicit
Public Function Ei(x As Double) As Variant
Dim i, n, nmax As Integer
Dim sum, fact, nterm, prevterm, ll As Double
Dim a, b, c, d, h, del As Double
Const EPS As Double = 0.000000000000002 'EPS is the floating point precision; an approximation of
'the significance of the nth term in the sum of all the terms
'FPMIN is a number near the smallest representable positive floating-point number; for Microsoft Excel,
'the smallest representable positive floating-point number is 4.94065645841247E-324
Const FPMIN As Double = 4.9E-308
Const EulerMascheroni As Double = 0.577215664901533
ll = -Log(EPS)
Select Case x
Case 0#
Ei = "-inf"
Case 0# To ll
sum = 0#
fact = 1#
nmax = 100
For i = 1 To nmax
fact = fact * (x / i)
nterm = fact / i
sum = sum + nterm
If nterm < sum * EPS Then
Exit For
End If
Next i
Ei = EulerMascheroni + Log(x) + sum
Case Is > ll
sum = 0#
nterm = 1# 'Value of the first term
nmax = 100
For i = 1 To nmax
prevterm = nterm
nterm = nterm * i / x
If nterm < EPS Then 'Since the final sum will involve adding 1, it will be
GoTo 2 'greater than 1. Therefore, the "nterm"
Else 'could act as an approximation for the relative error.
If nterm < prevterm Then 'Expansion still converging: add new term.
sum = sum + nterm
Else 'Expansion diverging: Subtract previous term and exit
sum = sum - prevterm
GoTo 2
End If
End If
Next i
2: Ei = Exp(x) * (1# + sum) / x
Case -1# To 0#
x = -x
sum = 0#
fact = 1#
nmax = 100
For i = 1 To nmax
fact = fact * (-x / i)
nterm = fact / i
sum = sum + nterm
If Abs(nterm) < Abs(sum) * EPS Then
Exit For
End If
Next i
Ei = -(-EulerMascheroni - Log(x) - sum)
Case Is < -1#
nmax = 100
x = -x
n = 1
b = x + n
c = 1# / FPMIN
d = 1# / b
h = d
For i = 1 To nmax
a = -i * i
b = b + 2#
d = 1# / (a * d + b) 'Denominators cannot be zero.
c = b + a / c
del = c * d
h = h * del
If (Abs(del - 1#) < EPS) Then
Ei = -(h * Exp(-x))
Exit For
End If
Next i
End Select
End Function
'=====================================================================================================
'An added function to compute the Exponential Integral, E(n,x) when n=1
'when n=1; E(n,x)=E1(x)
'This function EXCLUSIVELY defines E1(x) as Expint(x)
Public Function Expint(x As Double) As Variant
If x = 0# Then
Expint = "inf"
Else
If x < 0# Then
Expint = "NaN" 'x>0
Else
Expint = -Ei(-x) 'Ei(-x)=-E1(x) by analytic continuation; therefore, E1(x)=-Ei(-x)
End If
End If
End Function

'=====================================================================================================
' Molokwu Victor Chinemelu
'Contact: molokwuvictor@gmail.com
' technicaldiscussions.wordpress.com
' 2014
'=====================================================================================================

You might also like