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

Shared Libraries
Forum rules
For sharing working examples of macros / scripts. These can be in any script language supported by OpenOffice.org [Basic, Python, Netbean] or as source code files in Java or C# even - but requires the actual source code listing. This section is not for asking questions about writing your own macros.
Locked
User avatar
MrProgrammer
Moderator
Posts: 5283
Joined: Fri Jun 04, 2010 7:57 pm
Location: Wisconsin, USA

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

Post 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.
Mr. Programmer
AOO 4.1.7 Build 9800, MacOS 13.7.6, iMac Intel.   The locale for any menus or Calc formulas in my posts is English (USA).
Locked