为什么Mathematica不简化sinh(arccosh(x))
Why Mathematica does not simplify sinh(arccosh(x))

原始链接: https://www.johndcook.com/blog/2026/03/10/sinh-arccosh/

这项探索始于研究三角函数和双曲函数的复合,旨在创建比较表。然而,过程发现Mathematica处理这些恒等式,特别是双曲函数时存在复杂性。虽然Mathematica正确地简化了圆函数复合,如`Sin[ArcCos[x]]`,但对于`Sinh[ArcCosh[x]]`和`Tanh[ArcCosh[x]]`却产生了意想不到的结果。 这种差异源于`ArcCosh(x)`的细微定义。由于`cosh`的偶数性质,`ArcCosh`需要在复平面上通过分支割来保持一致的定义——具体来说,是从负无穷到1的不连续性。此外,简化`√(x + 1)² = (x + 1)`并非普遍成立,尤其是在`x`小于-1时。 Mathematica的输出反映了结合了解析延拓和极限的严格定义,而更简单的公式则假定`x`是大于或等于-1的实数值。通过明确声明假设 (`Assumptions -> {x >= -1}`),Mathematica*可以*返回简化的形式。这强调了仔细定义诸如`ArcCosh`和`sqrt`之类的函数的重要性,以确保在所有可能的输入下都能保证正确性。

## Mathematica 简化问题与计算机代数系统讨论 最近的 Hacker News 讨论集中在 Mathematica 的一种令人困惑的行为上:它无法简化 `Sinh[ArcCosh(x)]`。作者最初给出了错误的结果,后来更正,强调了 Mathematica 处理反双曲函数中的复数和分支割裂时的一个特点。 该讨论扩展到关于计算机代数系统 (CAS) 中简化的更广泛的对话。用户指出,“简化”并不总是直接的,取决于上下文和期望的结果。核心问题包括对变量的假设的需求(例如,实数与复数)以及像 `sqrt(x^2)` 这样函数固有的歧义,它等于 `abs(x)`,而不仅仅是 `x`。 许多评论者提倡 CAS 算法的更大透明度,建议开源核心函数背后的启发式方法。虽然 Mathematica 的 CAS 备受推崇,但其“黑盒”性质让一些用户感到沮丧。最后,讨论涉及大型语言模型 (LLM) 和形式化验证工具在未来挑战传统 CAS 系统主导地位的可能性。
相关文章

原文

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.

\renewcommand{\arraystretch}{2.2} \begin{array}{c|c|c|c} & \sin^{-1} & \cos^{-1} & \tan^{-1} \\ \hline \sin & x & \sqrt{1-x^{2}} & \dfrac{x}{\sqrt{1+x^2}} \\ \hline \cos & \sqrt{1-x^{2}} & x & \dfrac{1}{\sqrt{1 + x^2}} \\ \hline \tan & \dfrac{x}{\sqrt{1-x^{2}}} & \dfrac{\sqrt{1-x^{2}}}{x} & x \\ \end{array}

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.

\renewcommand{\arraystretch}{2.2} \begin{array}{c|c|c|c} & \sinh^{-1} & \cosh^{-1} & \tanh^{-1} \\ \hline \sinh & x & \sqrt{x^{2}-1} & \dfrac{x}{\sqrt{1-x^2}} \\ \hline \cosh & \sqrt{x^{2} + 1} & x & \dfrac{1}{\sqrt{1 - x^2}} \\ \hline \tanh & \dfrac{x}{\sqrt{x^{2}+1}} & \dfrac{\sqrt{x^{2}-1}}{x} & x \\ \end{array}

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

\sqrt{\frac{x-1}{x+1}} (x+1)

and Tanh[ArcCosh[x]] returns

\frac{\sqrt{\frac{x-1}{x+1}} (x+1)}{x}

Why doesn’t Mathematica simplify as expected?

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 √(3² − 1) = √3. The expression Mathematica returns for Sinh[ArcCosh[x]] correctly evaluates to −√3.

Defining ArcCosh

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

\text{arccosh}(x) = \lim_{\varepsilon \to 0^+} \text{arccosh}(x + \varepsilon i)

or by

\text{arccosh}(x) = \lim_{\varepsilon \to 0^-} \text{arccosh}(x + \varepsilon i)

but we have to make a choice because the two limits are not the same. For example, Sinh[ArcCosh[-2 + 0.001 I]] returns 11.214 + 2.89845 I but Sinh[ArcCosh[-2 + 0.001 I]] returns 11.214 - 2.89845 I. By convention, we choose the limit from above.

Defining square root

Where did we go wrong when we assumed Mathematica’s expression for sinh(arccosh(x))

\sqrt{\frac{x-1}{x+1}} (x+1)

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.

Making assumptions explicit

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).

Related posts

联系我们 contact @ memedata.com