Function to calculate Lambert's W-function.
Algorithm found at http://en.citizendium.org/wiki/Lambert_W_function#Numerical_calculation
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
real(kind=wp), | intent(in) | :: | z | The input value. |
The return value Lambert(z).
function Lambert ( z )
!! Function to calculate Lambert's W-function.
!!
!! Algorithm found at
!! http://en.citizendium.org/wiki/Lambert_W_function#Numerical_calculation
implicit none
real(wp), intent(in) :: z
!! The input value.
real(wp) :: Lambert
!! The return value Lambert(z).
real(wp) :: wcurrent, wnew, expw, diff
integer(ip) :: iter
! real(wp), parameter :: eps = 1.0e-12_wp
iter = 0
wcurrent = 1.0_wp
loop: do
iter = iter+1
expw = exp(wcurrent)
diff = wcurrent*expw - z
wnew = wcurrent - diff / ( expw*(wcurrent+1) - &
((wcurrent+2)*diff/(2*wcurrent+2)))
if ( abs(wnew - wcurrent) < eps(1.0_wp) ) exit loop
if (iter>maxiter) stop 'Function Lambert failed to converge. Aborting'
wcurrent = wnew
end do loop
Lambert = wnew
end function Lambert