Attribute VB_Name = "Module1"
Function LambertW(x As Double, Optional branch As Integer = 0) As Double
    Dim W As Double     ' Initial guess and solution
    Dim W_new As Double ' Next iteration value
    Dim tolerance As Double
    Dim maxIterations As Integer
    Dim i As Integer
    Dim e As Double
    
    e = Exp(1) ' Euler's number (~2.71828)
    tolerance = 0.0000001 ' Convergence tolerance
    maxIterations = 100   ' Max iterations
    
    ' Validate input range based on branch
    If branch = 0 Then
        If x < -1 / e Then
            LambertW = CVErr(xlErrValue) ' #VALUE! for x < -1/e
            Exit Function
        End If
    ElseIf branch = -1 Then
        If x < -1 / e Or x >= 0 Then
            LambertW = CVErr(xlErrValue) ' #VALUE! for x < -1/e or x >= 0
            Exit Function
        End If
    Else
        LambertW = CVErr(xlErrValue) ' Invalid branch
        Exit Function
    End If
    
    ' Use approximation for small |x|
    If Abs(x) < 0.001 Then
        LambertW = x - x ^ 2 + 1.5 * x ^ 3
        Exit Function
    End If
    
    ' Set initial guess based on x and branch
    If branch = 0 Then
        If x >= 0 Then
            W = 0
        ElseIf x > -0.1 Then
            W = x ' Better guess for small negative x
        Else
            W = -1
        End If
    ElseIf branch = -1 Then
        If x > -0.367879 Then
            W = -2
        Else
            W = Log(-x) - Log(-Log(-x))
        End If
    End If
    
    ' Newton's method
    For i = 1 To maxIterations
        Dim numerator As Double
        Dim denominator As Double
        numerator = W * Exp(W) - x
        denominator = Exp(W) * (1 + W)
        
        If Abs(denominator) < tolerance Then
            W_new = W - 0.01 * Sgn(numerator)
        Else
            W_new = W - numerator / denominator
        End If
        
        ' Enforce branch constraints
        If branch = 0 And W_new < -1 Then
            W_new = -1
        ElseIf branch = -1 And W_new >= -1 Then
            W_new = -1 - 0.01
        End If
        
        If Abs(W_new - W) < tolerance Then
            LambertW = W_new
            Exit Function
        End If
        W = W_new
    Next i
    
    LambertW = W_new
End Function
