My takeaway for other people like me from this is "computer is correct" because the proof shows that we can't define arccosh using a single proof across the entire complex plane (specifically imaginary, including infinity).
The representation of this means we have both complex functions that are defined as having coverage of infinity, and arccosh, that a proof exists in only one direction at a time during evaluation.
This distinction is a quirk in mathematics but means that the equation won't be simplified because although it looks like it can, the underlying proof is "one sided" (-ve or +ve) which means the variables are fundamentally not the same at evaluation time unless 2 approaches to the range definition are combined.
The QED is that this distinction won't be shown in the result's representation, leading to the confusion that it should have been simplified.
I think the author meant to say, "ArcCosh[-2 + 0.001 I] returns 1.31696 + 3.14102 I but ArcCosh[-2 - 0.001 I] returns 1.31696 - 3.14102 I," because we are talking about defining ArcCosh[] on the branch cut discontinuity, so there is no need to bring Sinh[] into it (and if we do, we find the limits are the same: the imaginary component goes to zero and Sinh[ArcCosh[-2 +/- t*I]] approaches -Sqrt[3] as t goes to zero from above or below). I am not sure what went wrong to get what they wrote.
I’m algebraist at heart and training, but I remember beautiful many-layered surfaces of ordinary complex functions in books and on blackboards.
Certainly, people don't need Wolfram Alpha as much.
On another point, it sucks to know what this means for Algebraic Geometry (the computational variant), which you could partly motivate, until now, for its use in constructing CASes.
Is x*x simpler than x^2? Probably? Is sqrt(5)^3 simpler than 5^(3/2)? I don't know.
It entirely depends on what you're going to be doing with the expression later.
This is actually subjective. For the vibe coding folks, they don’t care if the code is long winded and verbose. For others, the conciseness is part of the point; see APL and Notation as a Tool of Thought.
The default is a balance between leaf count and number of digits. But the documentation page above gives an example of how to nudge the cost function away from specialised functions.
Coq/Lean target very different use cases.
For a programmer, it's clear that we have lost the sign information but not the magnitude.
Simple. Makes most sign and solution reasoning explicit instead of implicit when solving quadratics or otherwise working with square roots.
This is completely different from the phenomenon described in the article: arccosh discontinuity can’t be dealt the same way. In fact complex analysis prefers to deal with it my making functions path-dependent (multi-valued).
Hyperbolic functions aren't used as much but the same principle applies. Here the core identity is cosh^2(x) = sinh^2(x) = 1 so:
sinh(arccosh(x))
= sqrt(1 + cosh^2(arccosh(x))
= sqrt(1 + x^2)
You should absolutely expect that from "simplify".Edit: Fixed stuff.
It will have simple rules such as constant folding, “replace x - x by zero”, “replace zero times something with the conditions under which ‘something’ has a value”, etc, lots of more complex but still easy to understand rules with conditionals such as “√x² = |x| if x is real”, and some weird logic that decides the order in which to try simplification rules.
There’s an analogy with compilers. In LLVM, most optimization passes are easy to understand, but if you look at the set of default optimization passes, there’s no clear reason for why it looks like it looks, other than “in our tests, that’s what performed best in a reasonable time frame”.
I’ve written several posts about applying trig functions to inverse trig functions. I intended to write two posts, one about the three basic trig functions and one about their hyperbolic counterparts. But there’s more to explore here than I thought at first. For example, the mistakes that I made in the first post lead to a couple more posts discussing error detection and proofs.
I was curious about how Mathematica would handle these identities. Sometimes it doesn’t simplify expressions the way you expect, and for interesting reasons. It handled the circular functions as you might expect.
So, for example, if you enter Sin[ArcCos[x]] it returns √(1 − _x_²) as in the table above. Then I added an h on the end of all the function names to see whether it would reproduce the table of hyperbolic compositions.
For the most part it did, but not entirely. The results were as expected except when applying sinh or cosh to arccosh. But Sinh[ArcCosh[x]] returns
and Tanh[ArcCosh[x]] returns
Why didn’t Sinh[ ArcCosh[x] ] just return √(_x_² − 1)? The expression it returned is equivalent to this: just square the (x + 1) term, bring it inside the radical, and simplify. That line of reasoning is correct for some values of x but not for others. For example, Sinh[ArcCosh[2]] returns −√3 but √(2² − 1) = √3. The expression Mathematica returns for Sinh[ArcCosh[x]] correctly evaluates to −√3.
To understand what’s going on, we have to look closer at what arccosh(x) means. You might say it is a function that returns the number whose hyperbolic cosine equals x. But cosh is an even function: cosh(−x) = cosh(x), so we can’t say the value. OK, so we define arccosh(x) to be the positive number whose hyperbolic cosine equals x. That works for real values of x that are at least 1. But what do we mean by, for example, arccosh(1/2)? There is no real number y such that cosh(y) = 1/2.
To rigorously define inverse hyperbolic cosine, we need to make a branch cut. We cannot define arccosh as an analytic function over the entire complex plane. But if we remove (−∞, 1], we can. We define arccosh(x) for real x > 1 to be the positive real number y such that cosh(y) = x, and define it for the rest of the complex plane (with our branch cut (−∞, 1] removed) by analytic continuation.
If we look up ArcCosh in Mathematica’s documentation, it says “ArcCosh[z] has a branch cut discontinuity in the complex z plane running from −∞ to +1.” But what about values of x that lie on the branch cut? For example, we looked at ArcCosh[-2] above. We can extend arccosh to the entire complex plane, but we cannot extend it as an analytic function.
So how do we define arccosh(x) for x in (−∞, 1]? We could define it to be the limit of arccosh(z) as z approaches x for values of z not on the branch cut. But we have to make a choice: do we approach x from above or from below? That is, we can define arccosh(x) for real x ≤ 1 by
or by
but we have to make a choice because the two limits are not the same. For example, ArcCosh[-2 + 0.001 I] returns 1.31696 + 3.14102 I but ArcCosh[-2 - 0.001 I] returns 1.31696 - 3.14102 I. By convention, we choose the limit from above.
Where did we go wrong when we assumed Mathematica’s expression for sinh(arccosh(x))
could be simplified to √(_x_² − 1)? We implicitly assumed √(x + 1)² = (x + 1). And that’s true, if x ≥ − 1, but not for smaller x. Just as we have be careful about how we define arccosh, we have to be careful about how we define square root.
The process of defining the square root function for all complex numbers is analogous to the process of defining arccosh. First, we define square root to be what we expect for positive real numbers. Then we make a branch cut, in this case (−∞, 0]. Then we define it by analytic continuation for all values not on the cut. Then finally, we define it along the cut by continuity, taking the limit from above.
Once we’ve defined arccosh and square root carefully, we can see that the expressions Mathematica returns for sinh(arccosh(x)) and tanh(arccosh(x)) are correct for all complex inputs, while the simpler expressions in the table above implicitly assume we’re working with values of x for which arccosh(x) is real.
If we are only concerned with values of x ≥ − 1 we can tell Mathematica this, and it will simplify expressions accordingly. If we ask it for
Simplify\[Sinh\[ArcCosh\[x\]\], Assumptions -> {x >= -1}\]
it will return √(_x_² − 1).
The first time I looked at the comment above, there was a reply, a reply to that reply, and a reply to the reply to the reply.
Later I came back and this time there were no replies. Since HN won't let you delete a comment that has a reply the only ways a comment chain should be able to go away are (1) the participants delete them in reverse order, or (2) a moderator intervenes.
I came back again and the comments are back!
I wonder if this is related to another comment problem I've seen many times in the past few weeks? I'll be using the "next" or "prev" links on top level comments to move through the comment and will come to a point where that breaks. Next reaches a comment that it will not go past. Coming from below prev will also not go past that point. Examining the links, next and prev are pointing to a nonexistent comment.
i would disagree with that (pun intended).
1. Multiply the input by itself
2. Add 1
3. Take the square root. There is often a fast square root function available.
The above is a fairly simply sequence of SIMD instructions. You can even do it without SIMD if you want.
Compare this to sinh being (e^x - e^-x) / 2 (you can reduce this to one exponentiation in terms of e^2x but I digress) and arccosh being ln(x + sqrt(s^2 - 1)) and you have an exponentiation, subtraction, division, logarithm, addition, square root and a subtraction. Computers generally implement e^2 and logarithm using numerical method approximations (eg of a Taylor's series expansion).
so sqrt(square(-i)) = +-i, one of which is x
That doesn't work in general for mathematica because it's too powerful.
"Simplify" is a very old term (>50y) in computer algebra. Its meaning has become kind of layered in that time.
But consider sqrt(i) = sqrt(exp(i\pi/2)). That's exp(i\pi/4). Your rule would give 1 as the answer. It's not helpful for a serious math system to give that answer to this problem.
When I square 1 I don't get i.
So no, it’s not unconditionally correct either.