Page 1 of 1

Lambert W₀ and W₋₁ functions, real argument, real result

Posted: Thu Jul 25, 2024 1:39 am
by MrProgrammer
Rem Lambert W₀ and W₋₁ functions, real argument, real result
Rem https://en.wikipedia.org/wiki/Lambert_W_function

Function LAMBERTW0(R As Variant) As Variant
Rem Allowed range: R must not be smaller than -EXP(-1), thus -0.367879441171442 <= R < ∞
Const NUM = "#NUM! LAMBERTW0 argument is "
Dim E_1  As Double  : E_1  = EXP(-1) ' 1/e
Dim W    As Double  : Dim T0 As Double : Dim T1 As Double
Dim I    As Integer : Dim N As Integer
If VARTYPE(R) <> 5 Then LAMBERTW0 = NUM & "not numeric" : Exit Function ' 5 is Double
Select Case True
   Case R < -E_1  : LAMBERTW0 = NUM & "less than -EXP(-1)" : Exit Function
   Case R = -E_1  : LAMBERTW0 = -1 : Exit Function
   Case R < 0     : N = 4 : T0 = R/E_1 : T1 = SQR(1+T0) ' T0 = R·e, T1 = √(1+R·e)
                            W = T0*LOG(1+T1)/(1+T0+T1)
   Case R = 0     : LAMBERTW0 = 0 : Exit Function
   Case R < 1/E_1 : N = 7 : W = R*E_1 ' R/e
   Case Else      : N = 5 : W = LOG(R) : W = W-LOG(W)
End Select
For I = 1 To N
   W = W/(1+W)*(1+LOG(R/W))
Next I
LAMBERTW0 = W
End Function

Function LAMBERTW_1(R As Variant) As Variant
Rem Allowed range: R must negative but not be smaller than -EXP(-1), thus -0.367879441171442 <= R < 0
Const NUM = "#NUM! LAMBERTW_1 argument is "
Dim E_1  As Double  : E_1  = EXP(-1) ' 1/e
Dim W    As Double  : Dim I As Integer
If VARTYPE(R) <> 5 Then LAMBERTW_1 = NUM & "not numeric" : Exit Function ' 5 is Double
Select Case True
   Case R < -E_1 : LAMBERTW_1 = NUM & "less than -EXP(-1)" : Exit Function
   Case R >= 0   : LAMBERTW_1 = NUM & "not negative" : Exit Function
   Case R = -E_1 : LAMBERTW_1 = -1 : Exit Function
   Case R < -.25 : W = -1-SQR(2+2*R/E_1) ' -1-√(2+2·e·R)
   Case Else     : W = LOG(-R) : W = W-LOG(-W)
End Select
For I = 1 To 6
   W = W/(1+W)*(1+LOG(R/W))
Next I
LAMBERTW_1 = W
End Function

Do not ask questions in the Code Snippets forum. Open a topic in Macros and UNO API for that.