Jump to content

Lambert W function


Recommended Posts

In solving a math problem for Kiti here, I created a function that solves the Lambert W function. This is also known as product log or the Omega function.

I hope that maybe this will help some poor fool who needs to use the function in the future. It's not a standard UDF. I don't really think it needs to be since I can't see it having widespread use.

It solves for w in the equation "x = w * e ^ w".

Func LambertW($x, $prec = 0.000000000001, $maxiters = 100)
    Local $w = 0, $i, $we, $w1e, $e = 2.71828183
    For $i = 0 To $maxiters
        $we = $w * $e ^ $w
        $w1e = ($w + 1) * $e ^ $w
        If $prec > Abs(($x - $we) / $w1e) Then Return $w
        $w = $w - (($we - $x) / ($w1e - ($w + 2) * ($we - $x) / (2 * $w + 2)))
    Next
    ConsoleWrite("W doesn't converge fast enough." & @CRLF)
    Return 0
EndFunc
Link to comment
Share on other sites

Hi.

I have just checked this page -> http://en.wikipedia.org/wiki/Lambert_W

The algorithm is there.

There is no need to declare $i. Its automatically assumed Local while in a For To Next loop.

Also you can use AutoIt's internal "Exp()" function instead of declaring $e.

So I made these modifications:

Func LambertW($x, $prec = 1E-12, $maxiters = 100)
    Local $w = 0, $we, $w1e
    For $i = 0 To $maxiters
        $we = $w * Exp($w)
        $w1e = ($w + 1) * Exp($w)
        If $prec > Abs(($x - $we) / $w1e) Then Return $w
        $w -= ($we - $x) / ($w1e - ($w + 2) * ($we - $x) / (2 * $w + 2))
    Next
    ConsoleWrite("W doesn't converge fast enough." & @CRLF)
    Return 0
EndFunc

My contributions:Local account UDF Registry UDFs DriverSigning UDF Windows Services UDF [url="http://www.autoitscript.com/forum/index.php?showtopic=81880"][/url]

Link to comment
Share on other sites

Why do I not get the same result? Which is right?

Func LambertW1($x, $prec = 0.000000000001, $maxiters = 100)
    Local $w = 0, $i, $we, $w1e, $e = 2.71828183
    For $i = 0 To $maxiters
        $we = $w * $e ^ $w
        $w1e = ($w + 1) * $e ^ $w
        If $prec > Abs(($x - $we) / $w1e) Then Return $w
        $w = $w - (($we - $x) / ($w1e - ($w + 2) * ($we - $x) / (2 * $w + 2)))
    Next
    ConsoleWrite("W doesn't converge fast enough." & @CRLF)
    Return 0
EndFunc

Func LambertW2($x, $prec = 1E-12, $maxiters = 100)
    Local $w = 0, $we, $w1e
    For $i = 0 To $maxiters
        $we = $w * Exp($w)
        $w1e = ($w + 1) * Exp($w)
        If $prec > Abs(($x - $we) / $w1e) Then Return $w
        $w -= ($we - $x) / ($w1e - ($w + 2) * ($we - $x) / (2 * $w + 2))
    Next
    ConsoleWrite("W doesn't converge fast enough." & @CRLF)
    Return 0
EndFunc

$number = 12
ConsoleWrite( LambertW1( $number ) & @CRLF)
ConsoleWrite( LambertW2( $number ) & @CRLF)

Output:

1.86281686374522
1.86281686443236

Edit:

Nevermind. Got the same answer when I changed to $e = 2.71828182845905.

Edited by zfisherdrums
Link to comment
Share on other sites

Both functions are right.

But since AutoIt's internal function "Exp()" uses more decimal places for the base of the natural logarithm, my modification is more precise.

Since e is transcendental, and therefore irrational, its value cannot be given exactly as a finite or eventually repeating decimal.

The numerical value of e truncated to 20 decimal places is:

2.71828 18284 59045 23536...

from -> http://en.wikipedia.org/wiki/E_(mathematical_constant)

My contributions:Local account UDF Registry UDFs DriverSigning UDF Windows Services UDF [url="http://www.autoitscript.com/forum/index.php?showtopic=81880"][/url]

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...