Attribute VB_Name = "mLambertW"
Option Explicit


'   #
'   # The LambertW function (real)
'   #
Public Function LambertW(dInput As Double)

    Dim dX As Double
    Dim dZ As Double
    Dim dE As Double
    Dim dF As Double
    Dim dZ1 As Double
    Dim iIteration As Long
    Dim IsFound As Boolean
    Dim dReturn As Double

    ' Respond to zero input
    If dInput = 0 Then
        dReturn = 0
        GoTo ExitFunction
    End If
    
    ' Convert input to complex
    dX = dInput
    
    ' Initialize
    IsFound = False

    ' Determine initial value
    dZ = 1
    
    ' Iterate to find Lambert's W
    For iIteration = 1 To 100
    
        ' Calculate next value
        dE = Exp(dZ)
        dF = dZ * dE - dX
        dZ1 = dZ - dF / ((dE * (dZ + 1) - dF * (dZ + 2) / (2 * dZ + 2)))

        ' See if found to desired precision
        If ((Abs(dZ - dZ1) < 0.000000000001)) Then
            IsFound = True
            Exit For
        Else
            dZ = dZ1
        End If
        
    Next iIteration
    
    ' Validate
    Debug.Assert (IsFound)
    
    ' Determine return value
    dReturn = dZ
  
ExitFunction:
  
    ' Return value
    LambertW = dReturn
  
End Function

