Comments (1)
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
, 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:
break_eternity.js/src/index.ts
Line 346 in 9690197
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)
- Can't convert BigInt to Decimal without setting its value to 0 HOT 8
- different results when expexting the same result HOT 5
- `Decimal.lambertw("ee4992767175317001")` errors instead of returning a value HOT 2
- The next step HOT 5
- [enhancement] I think I’ve figured out how to do arbitrary-height super-roots. HOT 3
- Tetration/iteratedexp has incorrect behavior for large heights on small bases with large payloads HOT 3
- Wrong String for reciprocals HOT 1
- Wrong factorial approximation HOT 3
- Unexpected NaN from sqrt() HOT 1
- Decimal.isValid() ?
- `new Decimal("(e^x)1")` returns `Decimal` with fractional `layer` if `x` is not an integer HOT 1
- `new Decimal("(e^x)1")` returns `Decimal` with negative `layer` if `x` is negative HOT 1
- The normalization of `new Decimal(-Infinity)` breaks some operations and may be incorrect HOT 3
- Throws a TypeError with standard EcmaScript class fields
- Max Value constant HOT 8
- Some constants don't match break_infinity.js documentation HOT 6
- -Infinity times -Infinity is Infinity, not -Infinity. HOT 1
- new Decimal(2).pow(3) is 7.999999999999999 HOT 1
- How to run unit tests? HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from break_eternity.js.