HP49-50G,VER16.2 Lambert Funktion Wk(x), k=k= 0, ±1, ±2, ±3, ±4..., x real or complex - Printable Version +- HP Forums (https://www.hpmuseum.org/forum) +-- Forum: HP Software Libraries (/forum-10.html) +--- Forum: General Software Library (/forum-13.html) +--- Thread: HP49-50G,VER16.2 Lambert Funktion Wk(x), k=k= 0, ±1, ±2, ±3, ±4..., x real or complex (/thread-21161.html) |
HP49-50G,VER16.2 Lambert Funktion Wk(x), k=k= 0, ±1, ±2, ±3, ±4..., x real or complex - Gil - 01-14-2024 01:58 PM My apologies, I deleted my whole previous post discussion relative to Lambert function W(x). Here a partial summary of it with the newest version 16.2 of W(x). This version permits to calculate Wk(x), like WolframAlpha does, k being the branch number of W(x) and is equal to 0, ±1, ±2, ±3, ±4... x may be a real or a complex number. Input a) k and x: - k, in stack level 2, for the branch - and argument x, in stack level 1 b) or simply x when by default k is supposed to be 0 (here, note the following, however: if there is already a number like 0, ±1, ±1., ±2, ±2., ±3, ±3., etc. in stack level 2, that number will be automatically taken as the branch level). Output a) Wk(x): w< b) automatically 2 solution outputs W0(x): w1 & W-1(x): w2, for x real -1/e<=x<=0 Observations a) For initial guess of W-1 iteration process & -1/e<x<0, see Wikipedia; b) when possible, we try to find W, with the built-in ROOT solver for 'W×EXP(W)-x'; c) for complex solution W, we try to use likewise the built-in MLSV solver for ['W×EXP(W)-x']; d) for limit values, for instance by endless search near -1/e, we used instead one of the many methods proposed by Albert Chan in his own Lambert thread; e) likewise, we used one of the many methods proposed by Albert Chan in his own Lambert thread when the output could be clearly much improved; f) see also initial guesses according to Albert Chan, http://www.finetune.co.jp/~lyuka/technote/lambertw/clambertw.html, for W0 (and also for other integer values of k≠0); g) general calculation of the different k branches, see https://www.johndcook.com/blog/2021/11/15/lambert-w-branch-number/ h) up to now, all test results, with k=0, ±1, ±2, ±3, ±4..., and x real or complex number, corresponded largely (with the exception, generally, of the last two digits) to WolframAlpha outputs; i) however, contrarily to Wolfram Alpha, for inputs like {100 0}, ie k=100, argument=0, the program output is double, whereas Wolfram simplifies the result to -infinity: for x—> -0, ie just negative, result here is a complex form: "-infinity + i×200PI"; for x—> 0+, ie just positive, result will also present a complex form: "-infinity+i×199PI; j) the same applies for instance for {50, infinity}, ie k=50 & x a "real" (9.99999999999E499) that tends to infinity, for which the program, here again, gives a complex output: "infinity + i×100PI", when Wolfram simplifies the answer and just gives infinity; k) extreme tiny input x ≠0, in particular ±1E-497, ±1E-498 ±1E-499, are accepted and calculated correctly; l) entering the algebraic expression '-1/e' as input, you will get W0 & W-1 = exactly -1: W0('-(1/e)'~-.367879441171): -1 & W-1('-(1/e)'~-.367879441171): -1; but entering the approximate value of -1/e, ie the real number -.367879441171, will produce the double, different output W0(-.367879441171): -.999997710398 & W-1(-.367879441171): -1.00000141421. RE: Lambert Funktion Wk(x), k=k= 0, ±1, ±2, ±3, ±4..., x real or complex - Albert Chan - 01-14-2024 02:22 PM What algorithm were used for Wk(x) ? Is the result guaranteed for k-th branch? Numbering the branches of the Lambert W function Perhaps of interest: thread lambertw, all branches RE: Lambert Funktion Wk(x), k=k= 0, ±1, ±2, ±3, ±4..., x real or complex - Gil - 01-14-2024 02:50 PM Yes, it's the algorithm that I found with the given reference. The results found match well with Wolfram Alpha ones, at least for the numerous examples I tested. Just a mistake: W('k≠0',x=0), gives error instead of -infinity; will correct it soon. Another special case W(k=-1,0) = -infinity, and not zero! But, for the rest I would not guarantee anything... the Mr Maths being you! But tell me otherwise how to implement a feasible solution for the different k branches. Wolfram Alpha shows definitions with complex integrals. Regards and thanks in advance for your insights, Albert. Gil RE: Lambert Funktion Wk(x), k=k= 0, ±1, ±2, ±3, ±4..., x real or complex - Albert Chan - 01-14-2024 05:03 PM (01-14-2024 02:50 PM)Gil Wrote: Yes, it's the algorithm that I found with the given reference. If you meant given reference here, it is guaranteed to return correct branch. x = W(a, k), we rewrite definition of branch k as function. f(x) = x + log(x) - log(a) - 2*k*pi*I f'(x) = 1 + 1/x Newton: x ← x - f/f' Solve for f(x)=0 thus guaranteed correct branch. Without signed zero, code assumed real a == a+0*I For illustration, here is lambertw code that support signed zeros. lua> require'expW' lua> I.W(-0.1, -1) (-3.577152063957297-0*I) lua> I.W(I.conj(-0.1), -1) (-4.44909817870089-7.3070607892176085*I) Technically, W-1(-0.1) does not exist. (we have 2 different limits!) By convention, we returned W-1(-0.1+0*I), which does exist. For comparison, W0(-0.1) does exist. lua> I.W(-0.1, 0) (-0.11183255915896298+0*I) lua> I.W(I.conj(-0.1), 0) (-0.11183255915896298-0*I) Note that 2nd result is conjugate of 1st. In general: W(a,k) = conj(W(conj(a),-k)) RE: Lambert Funktion Wk(x), k=k= 0, ±1, ±2, ±3, ±4..., x real or complex - Gil - 01-14-2024 05:45 PM Instead of Newton's method, I solved f(x) = 0, with the built-in HP50G MSLV command-solver, that is very fast,above all with EMU48 on the phone. As initial value xo (complex value or not), I used the formula indicated in Takayuki HOSODA's paper. Is it correct to use the same xo also, as I did, in the formulae (for the k branch) given in https://www.johndcook.com/blog/2021/11/15/lambert-w-branch-number/ ? It seems that I get always the correct (Wolfram Alpha) output for the given k branch. Thanks for you insight. RE: Lambert Funktion Wk(x), k=k= 0, ±1, ±2, ±3, ±4..., x real or complex - Gil - 01-14-2024 07:13 PM (01-14-2024 05:03 PM)Albert Chan Wrote:(01-14-2024 02:50 PM)Gil Wrote: Yes, it's the algorithm that I found with the given reference. RE: Lambert Funktion Wk(x), k=k= 0, ±1, ±2, ±3, ±4..., x real or complex - Gil - 01-14-2024 07:23 PM “Technically, W-1(-0.1) does not exist. (we have 2 different limits!) By convention, we returned W-1(-0.1+0*I), which does exist." Sorry, but for the interval - 1/e<x<0, doesn't W(k=-1,x) represent —by convention ? — the lower part of the function? For me, the solution z=(-4.4490981787,-7.30706078926) is for W{k=-2,-.1) = (-4.4490981787,-7.30706078926). RE: Lambert Funktion Wk(x), k=k= 0, ±1, ±2, ±3, ±4..., x real or complex - Albert Chan - 01-14-2024 08:51 PM (01-14-2024 07:23 PM)Gil Wrote: “Technically, W-1(-0.1) does not exist. (we have 2 different limits!) Yes, if you limited x to real, -1 branch is the lower part. But, if we expand x to complex numbers, sign of 0 matters. lua> x, k = -0.1, -1 lua> w = I.W(x, k) lua> f = w + I.log(w) - I.log(x) - 2*k*pi*I lua> f, w (-4.440892098500626e-16+0*I) (-3.577152063957297-0*I) Note that w has -0*I, with arg(w) = -pi Sign matters! If it were +0*I, we would get f ≈ 2*pi*I ≠ 0 Unfortunately, most calculators does not support signed zeros. Without signed zero, my code compensate for this with customized LN(x). We pick a result, based on some convention. W(-0.1, -1) --> W(-0.1+0*I, -1) But it is all arbitrary! We could have pick -0*I, with +1 branch: W(-0.1-0*I, +1) = (-3.577152063957297+0*I) This is not that far-fetched! Example, ASIN/ACOS picked -0*I branch. It is a mess. lua> I.acos(2) (0-1.3169578969248166*I) lua> I.acos(I.conj(2)) (0+1.3169578969248166*I) Free42: 2 ACOS → 0+1.316957896924816708625046347307968i Branch Cuts for Complex Elementary Functions or Much Ado About Nothing' s Sign RE: Lambert Funktion Wk(x), k=k= 0, ±1, ±2, ±3, ±4..., x real or complex - Gil - 01-14-2024 09:52 PM Well, well. Thanks for your explanations!, Albert! RE: Lambert Funktion Wk(x), k=k= 0, ±1, ±2, ±3, ±4..., x real or complex - Albert Chan - 01-15-2024 01:18 PM (01-14-2024 08:51 PM)Albert Chan Wrote: Without signed zero, my code compensate for this with customized LN(x). Customized LN(x) is needed to account for lost of signed zero. This is because of the discontinuity of W-1(-0.1 ± 0*I) p2> from mpmath import * # functions without signed zeros p2> mp.pretty = 1 p2> a, k = -0.1, -1 p2> x = ln(-a) # guess = -2.302585... p2> f = x + ln(x) - ln(a) - 2*k*pi*1j p2> f (0.834032445247956 + 6.28318530717959j) f has complex parts, (x - f/f') also have complex parts, game over! Newton's step will get across the discontinuity, unable to converge. Customized LN(x) accounted for this, by knowing final x imag part sign. p2> s = (im(a)<0) # im(a)=0 treated as +0 p2> s = 1 - 2 * (k<0 or k==0 and s) p2> s # final x imag part sign -1 p2> def LN(x, bad=-s*pi): x=ln(x); return conj(x) if im(x)==bad else x ... p2> f = x + LN(x) - ln(a) - 2*k*pi*1j p2> f (0.834032445247956 + 0.0j) f still on real line, so does (x - f/f'). Iterations stay on real line, not crossing discontinuity. To illustrate what happens without customized LN, we can use HP Prime Cas> arg(-1.), arg(conj(-1.)) → [pi, pi], no signed zero support Code: #cas Cas> f := x + ln(x) - ln(a) - 2*k*pi*i Cas> a, k := -0.1, -1 Cas> nestlist(unapply(x-f/f',x), ln(-a), 5) [−2.30258509299, −3.77690771946−11.1068128314*i, −3.94994870209−0.950318443389*i, −3.55835549121−4.10468678203e−2*i, −3.57707753385+8.29770660431e−5*i, −3.57707356148−8.72129018367*i] For comparison, this is Python code with customized LN(x) p2> x = W(-0.1, -1, True) -2.30258509299405 (-3.77690771946225 + 0.0j) (-3.57912417640232 + 0.0j) (-3.57715227469581 + 0.0j) (-3.5771520639573 + 0.0j) RE: Lambert Funktion Wk(x), k=k= 0, ±1, ±2, ±3, ±4..., x real or complex - Gil - 01-19-2024 11:05 PM New version, 8.02, with my thanks to Albert Chan. The program accepts now all kind of argument : real(x) or imaginary (x) —>± infinity, for any integer branch k. Input {k x}, x complex number or not. Let's try some large values of x (large for the real or for the imaginary part) 1) x=1E450, k=0 Input in HP50G 1E450 or {0, 1E450} Then press LAMBERT Output :W0(1.E450): 1029.2267288 Does it go to +inf? Try with Wolfram Write LambertW (0,1E5000000) Output: 1.15E7 Or write LambertW (0, infinity) Output: infinity And with HP50G? Write sign for infinity LS+0 Then press LAMBERT Output: 'infinity' 2) x=1E450, k=15 Input in HP50G {15 1E450} Then press LAMBERT Output :W15(1.E450): (1029.22256567,94.1565503694) Does that result go to +inf (with no imaginary part, here = 94,16) Try with Wolfram Write LambertW (15,1E5000000) Output: (1.15E7+94.24777) And you see that 94.24777=30pi But, if you try and write LambertW (0, infinity) Output: infinity. Well, let's admit it is correct. Next example will put in question that kind of answer. And with HP50G? Write {15 infinity} (LS+0 for infinty) Then press LAMBERT Output: "infinity + i(30pi)" 3) x=(-1E450), k=0, Input in HP50G (0,-1E450) or {0, - 1E450} Then press LAMBERT Output { "W0(-inf):" inf-ipi" } Does it go to +inf? Try with Wolfram Write LambertW(-9999E5000000) Output: 1.15E7+i*3.14159238 (almost pi) Or write LambertW (-i*infinity) Output: infinity?! And with HP50G? Write sign for infinity LS+0 Then press key ± (letter M) Then press LAMBERT Output: "infinity+ i(pi)" 4) x=(0, 1E450), k=0, ie a large imaginary part Input in HP50G (0,1E450) or {0, (0,1E450)} Then press LAMBERT Output ::W0((0.,1.E450)): (1029.22672764,1.56927161862) Does it go to +inf? Try with Wolfram Write LambertW(0+i*9999E5000000) Output: 1.15E7+i*1.570796 Or write LambertW (0+i*infinity) Output: infinity?! And with HP50G? Write sign for infinity LS+0 Then press LAMBERT Output: "infinity+ i(pi/2)" 5) case x=(inf-i*inf), k= 30 Write 30 ENTER key oo, ie LS+0[/code] —>NUM DUP key ± (letter M) R—>C (to get together inf, real part, and -inf, imaginary part, into a complex number) 2 —> list You should get the following list {30, (9.999999999E499, 9.999999999E499)} Then press LAMBERT on the HP50G. Output on HP50G "oo +i(60pi). Approximation with Wolfram LambertW(30, 1E10000+i*E10000) Result: 23015.807+i×188.487, about i×(60 pi)[code] RE: HP49-50G, VER 12 Lambert Funktion Wk(x), k=k= 0, ±1, ±2, ±3, ±4..., x real or complex - Gil - 01-27-2024 10:44 PM New version 16.2 of W(x). For x real between -1/e and 0, two results: one for the upper branch, the default branch W0(x); and the other, for the lower branch branch, W-1. For W-1, x—>0 is a special case: if x—>0- (x "slightly negative") —> W-1 = -infinity; and if x—>0+ (x "slightly positive"), W-1—> "- infinity - iPI“, but simplified in Wolfram to -infinity. To get the answer for W (k=100, z=i×infinity), procede as follows: 1) 100 ENTER 2) 0 (for the real part) 3) LS +" number zero", ie white arrow + "key right to On-key" (to get the infinity character or corresponding the infinity number 9.99999999999E499) 4) —>NUM (to convert infinity character to the real number 9.99999999999E499) 5) command R—>C (to convert the two numbers in the stack, 0 and 9.99999999999E499, into a complex (0, 9.99999999999E499)) 6) 2 —>LIST (to get a list with two objects: 100, =k the branch number, as first object of the list ; and (0, 9.99999999999E499), the complex z, as second object of the list) 7) Having the appropriate list {100 (0, 9.99999999999E499)} in stack level 1, launch the program. You should get, as a result, "infinity + i × 401×pi/2“. Approximate check with Wolfram LambertW (100, i*1E500000) gives1.1512785901131729534744838666712253701249035476598766913241 × 10^6 +629.88877992373306983756183247568673861816336497433660193071 i And 629.8887799/(pi/2) gives 400.99965169 —> 401 Note that, if you enter in Wolfram LambertW (100, i*infinity), you get infinity, and not "infinity + i × 401×pi/2“. For more details about the LambertW function and its subtilities, look at the recent special thread in this forum on LambertW function by Albert Chan. RE: HP49-50G, VER 15 Lambert Funktion Wk(x), k=k= 0, ±1, ±2, ±3, ±4..., x real or complex - Gil - 02-09-2024 12:43 AM New version 16.2 Initially, only ROOT or MLSV built-in commands of the calculator were used —> and the answer then might take a while to appear — or even never appear at all. Because of many "pitfalls", all nicely solved by Albert Chan in his thread LambertW, the program had to be modified, hopefully more or less correctly, thanks to and according to Albert Chan's implementations. The resulting program, with its possible apparent lack of continuity in the structure and its redundancies, is not supposed to be elegant or always most efficient; it just works fine, above all with Android phone application EMU48, and reflects, with more or less success, its successive "improvements" according to the different situations. Don't hesitate to compare the exactness of the results with Wolfram Alpha or with the very fast and compact program by John Keith after Albert Chan's suggestions. Regarding the accuracy of the results Entering the algebraic expression '-1/e' as input, you will get W0 & W-1 = exactly -1: W0('-(1/e)'~-.367879441171): -1 & W-1('-(1/e)'~-.367879441171): -1. But entering the approximate value of -1/e, ie the real number -.367879441171, will produce the double output ≠-1 W0(-.367879441171): -.999997710398 & W-1(-.367879441171): -1.00000141421. RE: HP49-50G,VER16.2 Lambert Funktion Wk(x), k=k= 0, ±1, ±2, ±3, ±4..., x real or complex - Gil - 02-11-2024 09:17 PM New version 16.2 Main change: - Branch k in stack level 2 - Argument x in stack level 1 (previously it was a list) Code: \<< "Lambert (ver 16.2) |