# 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```

##### 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]

##### 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

##### 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...

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

##### Share on other sites

Yes, I translated the python source from the Wikipedia entry.

Technically I didn't have to explicitly declare any of the variables. I just do. Also, I wrote it quickly. Improvements are nice though.

## 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