Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tetration/iteratedexp has incorrect behavior for large heights on small bases with large payloads #159

Closed
MathCookie17 opened this issue Feb 26, 2024 · 3 comments
Labels
bug Something isn't working

Comments

@MathCookie17
Copy link
Collaborator

Tetration for bases <= e^1/e normally converges to a finite value as the height of the tetration increases, meaning b^^Infinity is defined for e^-e <= b <= e^1/e. break_eternity handles this correctly... but what happens once there's a payload? 1.3^100 is around 248 billion, so 1.3^1.3^100 is around 10^(28.25 billion), and even though 1.3 is within the convergence range for infinite tetration, the large payload of 100 sets it over the edge and the iterated exponentiation "goes tetrational". break_eternity doesn't handle this correctly: it stops doing exponentiations after 10k iterations for bases within the convergence range (and it doesn't do the "oh, it went tetrational, time to just add to the layer number" shortcut like it does for larger bases since it doesn't know that it can "go tetrational" for smaller bases), and it completely ignores the payload for infinite height.

Looking at https://www.desmos.com/calculator/ljgzeqgpz5, we see that for 1 < b < e^1/e, the equation b^x = x, which finds the fixed point for infinite-height tetration, actually has two solutions. The lower solution is what we see for infinite-height tetration without a payload, but these two solutions actually split iterated exponentiation into three cases:

  • If the payload is itself one of the two solutions, it will remain at that fixed point.
  • With a payload less than the lower solution (including tetration "without a payload", since that means the payload is 1), b^x is greater than x, so the iterated exponentiation will increase and converge on the lower solution.
  • With a payload between the two solutions, b^x is less than x, so the iterated exponentiation will decrease and converge on the lower solution.
  • However, if the payload is above the higher solution, then b^x is greater than x, so the iterated exponentiation will increase without bound and "go tetrational". This is the case that break_eternity currently fails to account for.

I believe we're good for bases less than 1 - they only have one b^x = x solution, which the iterated exponentiation converges to regardless of the payload.

@Patashu Patashu added the bug Something isn't working label Feb 26, 2024
@MathCookie17
Copy link
Collaborator Author

OK, this is turning out to be harder than I thought. I've coded up a solution that I think works for integer-height (and infinite-height) tetration, but in order to do fractional height I need layeradd to work for these small bases, which means I need an idea of what slog means on these smaller bases. slog_1.3(20) sure seems meaningless since no power tower of only 1.3s will ever get up to 20, but whatever it is, slog_1.3(1.3^20) (1.3^20 is around 190.0496377) should be 1 more than it.

The solution I'm thinking of is to write a function called "excess_slog", so named because it handles numbers that are above ("in excess of") the limit of usual slog for these smaller bases. excess_slog returns a pair (an array of two entries since this is TypeScript rather than a language with built-in tuples) whose first entry is a Decimal and whose second entry is a number - that number is either 0, 1, or 2. If it's 0, that means it's the usual slog, which operates in the lower range (the value is below the lower b^x = x solution) - for example, excess_slog(1.4, 1.3), i.e. the base 1.3 slog of 1.4, would return [1.9393492860381027, 0]. If the number is 1, that means we're in the middle range (the value is between the two b^x = x solutions - in this range, slog of the upper solution is -Infinity and slog of the lower solution is +Infinity, so slog is actually decreasing), and if the number is 2, that means we're in the upper range (slog of the upper solution is -Infinity here too). What I'm unsure of is what should be set as the 0 value for each range. For range 0, obviously excess_slog(1) is [0, 0], but what about the other two? I'm thinking I use the geometric mean of the two b^x = x solutions as the 0 value for range 1 (since those are the endpoints of range 1), but since range 2 only has a left endpoint (it shoots off to infinity on the right), I can't think of any choice for excess_slog(x) = [0, 2] that isn't arbitrary - the ideas that have come to my mind all involve the upper b^x = x solution (I'll call it "u" here), such as u + 1, u * 2, u^2, or perhaps u * l (where l is the lower b^x = x solution), but all of those are pretty arbitrary.

Any thoughts on this idea? Is the two-element array approach to return both a value and the range it's in a good idea, or do you have a better one? What should I use as the 0 values in the middle and high ranges of this "excess_slog" function? And if I do make the excess_slog function, should it be public like the rest of the Decimal functions, or do we say "every other Decimal function returns something like a number, a boolean, or another Decimal, an array of a Decimal and a number would be too confusing, so just make it private"?

@Patashu
Copy link
Owner

Patashu commented Mar 4, 2024

Hmm, this sounds a bit above my paygrade (unless I spent time of my own researching it). It'd be great if we had arbitrary analytical tetration at this point but it remains hard to port to javascript :p I would suggest:

  • This sounds extremely like an internal implementation detail, so keep it private.
  • However you implement it, come up with some unit tests that make reasonable assertions on how it works. That way, it doesn't matter how it's implemented as long as it satisfies the unit tests.

@MathCookie17
Copy link
Collaborator Author

Fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants