Giter Site home page Giter Site logo

Comments (1)

James103 avatar James103 commented on September 25, 2024

I've added some debug lines to the d_lambertw function to try to trace down the cause of this issue.

The cause appears to be that ew (derived from w.neg().exp() where w is Decimal.ln(z) assuming the principal branch) is not completely cancelled out by z when it normally is at these large numbers, causing z.mul(ew) to be some large number (≈ ee17) instead of 1, which then causes later calculations during that same iteration to break and the final result to be many thousands of orders of magnitude higher than what it should be.

Although z.mul(Decimal.ln(z).neg().exp()) $= z e^{-\ln(z)}$ simplifies to 1 for all z, it can in practice be very far away from 1 (like ee17 units off) due to incomplete cancellation of the number z and its reciprocal calculated with Decimal.ln(z).neg().exp().

d_lambertw output when running code in OP using the principal branch
17:40:17.881 lambertw trace: z = ee31.666733435898777
17:40:17.881   Iteration 0:
17:40:17.881     w = 1.0689296521861698e32, w.neg() = -1.0689296521861698e32, ew = w.neg().exp() = ee-31.666733435898777
17:40:17.881     z.mul(ew) = 1, wewz = w.sub(z.mul(ew)) = 1.0689296521861698e32
17:40:17.881     Decimal.mul(2, w).add(2) = 2.13785930437234e32
17:40:17.882     w.add(2).mul(wewz).div(Decimal.mul(2, w).add(2)) = 5.344648260930848e31
17:40:17.882     w.add(1).sub(w.add(2).mul(wewz).div(Decimal.mul(2, w).add(2))) = 5.344648260930848e31
17:40:17.882     wewz.div(w.add(1).sub(w.add(2).mul(wewz).div(Decimal.mul(2, w).add(2)))) = 2.0000000000000004
17:40:17.882     wn = w.sub(wewz.div(w.add(1).sub(w.add(2).mul(wewz).div(Decimal.mul(2, w).add(2))))) = 1.0689296521861698e32
17:40:17.882   Returning: 1.0689296521861698e32
17:40:17.882 lambertw trace: z = ee31.666733435898788
17:40:17.882   Iteration 0:
17:40:17.882     w = 1.0689296521861873e32, w.neg() = -1.0689296521861873e32, ew = w.neg().exp() = ee-31.666733435898784
17:40:17.882     z.mul(ew) = ee17.581375385438758, wewz = w.sub(z.mul(ew)) = -ee17.581375385438758
17:40:17.883     Decimal.mul(2, w).add(2) = 2.137859304372375e32
17:40:17.883     w.add(2).mul(wewz).div(Decimal.mul(2, w).add(2)) = -ee17.581375385438754
17:40:17.883     w.add(1).sub(w.add(2).mul(wewz).div(Decimal.mul(2, w).add(2))) = ee17.581375385438754
17:40:17.883     wewz.div(w.add(1).sub(w.add(2).mul(wewz).div(Decimal.mul(2, w).add(2)))) = -2.575091926685474e3133
17:40:17.883     wn = w.sub(wewz.div(w.add(1).sub(w.add(2).mul(wewz).div(Decimal.mul(2, w).add(2))))) = 2.575091926685474e3133
17:40:17.883   Iteration 1:
17:40:17.883     w = 2.575091926685474e3133, w.neg() = -2.575091926685474e3133, ew = w.neg().exp() = ee-3133.0485770485766
17:40:17.883     z.mul(ew) = ee-3133.0485770485766, wewz = w.sub(z.mul(ew)) = 2.575091926685474e3133
17:40:17.883     Decimal.mul(2, w).add(2) = 5.15018385337196e3133
17:40:17.883     w.add(2).mul(wewz).div(Decimal.mul(2, w).add(2)) = 1.287545963342484e3133
17:40:17.883     w.add(1).sub(w.add(2).mul(wewz).div(Decimal.mul(2, w).add(2))) = 1.287545963342484e3133
17:40:17.883     wewz.div(w.add(1).sub(w.add(2).mul(wewz).div(Decimal.mul(2, w).add(2)))) = 2.000000000000393
17:40:17.883     wn = w.sub(wewz.div(w.add(1).sub(w.add(2).mul(wewz).div(Decimal.mul(2, w).add(2))))) = 2.575091926685474e3133
17:40:17.884   Returning: 2.575091926685474e3133
17:40:17.884 lambertw trace: z = ee31.6667334358988
17:40:17.884   Iteration 0:
17:40:17.884     w = 1.0689296521862222e32, w.neg() = -1.0689296521862222e32, ew = w.neg().exp() = ee-31.6667334358988
17:40:17.884     z.mul(ew) = 1, wewz = w.sub(z.mul(ew)) = 1.0689296521862222e32
17:40:17.884     Decimal.mul(2, w).add(2) = 2.1378593043724448e32
17:40:17.884     w.add(2).mul(wewz).div(Decimal.mul(2, w).add(2)) = 5.344648260931111e31
17:40:17.884     w.add(1).sub(w.add(2).mul(wewz).div(Decimal.mul(2, w).add(2))) = 5.344648260931111e31
17:40:17.884     wewz.div(w.add(1).sub(w.add(2).mul(wewz).div(Decimal.mul(2, w).add(2)))) = 2.0000000000000004
17:40:17.884     wn = w.sub(wewz.div(w.add(1).sub(w.add(2).mul(wewz).div(Decimal.mul(2, w).add(2))))) = 1.0689296521862222e32
17:40:17.884   Returning: 1.0689296521862222e32

EDIT: Found it! Change this line in the d_lambertw function:

wewz = w.sub(z.mul(ew));

By replacing z.mul(ew) in the .sub() call of wewz = w.sub(z.mul(ew)) with 1, which is what it simplifies to after undoing the substitutions. Note: Only tested with certain numbers in the principal branch; needs testing for the real non-principal branch and over a wider range of numbers.
EDIT 2: The above fix does not appear to converge for smaller numbers (layer 1). A better solution may be needed.

from break_eternity.js.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.