[HN Gopher] Why Mathematica does not simplify sinh(arccosh(x))
       ___________________________________________________________________
        
       Why Mathematica does not simplify sinh(arccosh(x))
        
       Author : ibobev
       Score  : 143 points
       Date   : 2026-03-11 13:30 UTC (4 days ago)
        
 (HTM) web link (www.johndcook.com)
 (TXT) w3m dump (www.johndcook.com)
        
       | hnarayanan wrote:
       | This is a general pattern in CAS. For a more basic case, it's not
       | obvious sqrt(square(x)) will simplify to x without any further
       | assumptions on x.
        
         | burnt-resistor wrote:
         | That's not what it simplifies to using a real or complex number
         | domains for x, it's abs(x). CAS need type inference assumptions
         | and/or type qualifiers to be more powerful.
         | 
         | Edit: Fixed stuff.
        
           | jstanley wrote:
           | Right, that's why you need further assumptions on x in order
           | for that simplification to hold.
        
             | contubernio wrote:
             | It's not a simplification, it's wrong. Sqrt(square(x))
             | _equals_ abs(x).
        
               | MForster wrote:
               | It also equals x with appropriate assumptions (x > 0).
        
               | exe34 wrote:
               | so there's an unconditionally correct answer (it's also
               | equal to abs(x) for x>0), and then there is an answer
               | that is only correct for half the domain, which requires
               | an additional assumption.
        
               | crubier wrote:
               | sqrt(square(i)) != abs(i)
               | 
               | So no, it's not unconditionally correct either.
        
               | notarget137 wrote:
               | Well, then sin(x) = x if x is infinitely small
        
               | oh_my_goodness wrote:
               | Not in general. As people have pointed out elsewhere,
               | it's true if x is real. That isn't always a helpful
               | assumption. (When x is real you can plug that assumption
               | into Mathematica. Then Mathematica should agree with
               | you.)
               | 
               | 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.
        
           | yorwba wrote:
           | For x = -i, square(x) = -1, sqrt(square(x)) = i. Meanwhile,
           | abs(x) = 1. You're right that it simplifies to abs(x) for
           | real x, but that no longer holds for arbitrary complex
           | values.
        
             | NooneAtAll3 wrote:
             | for arbitrary complex values sqrt() gives 2 answers with +-
             | signs
             | 
             | so sqrt(square(-i)) = +-i, one of which is x
        
               | syockit wrote:
               | I've never seen a CAS that gives two answers for sqrt.
               | Mathematica doesn't, sympy doesn't, and IIRC Maxima also
               | doesn't.
        
               | Armisael16 wrote:
               | The sqrt function returns the principle square root, not
               | both. That's true for all numbers, positive, negative,
               | and complex alike.
        
           | fph wrote:
           | It's abs(x) only over the reals, for complex numbers it's
           | more complicated.
        
           | SoftTalker wrote:
           | That abs(x) (or |x| as we wrote it) used to catch out so many
           | of us in HS trig and algebra.
        
         | ogogmad wrote:
         | I think you would get sqrt(x^2) = x, if x belonged to the
         | _natural domain of sqrt_ , which is a Riemann surface, that may
         | also be defined using the language of "sheaves". I don't know
         | how to connect this to the article or Mathematica.
        
           | mathisfun123 wrote:
           | it's literally the prototypical example for `Assuming`
           | 
           | https://reference.wolfram.com/language/ref/Assuming.html
        
       | noosphr wrote:
       | More generally it's not at all clear what 'simplify' means.
       | 
       | 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.
        
         | jmyeet wrote:
         | I think "simplify" is pretty clear here. For trigonometric
         | functions you would expect a trig function and an inverse trig
         | function to be simplified. We all know what we'd expect if we
         | saw sin(arcsin(x)) (ie x). If we saw cos(arcsin(x)) I'll spoil
         | it for you: it simplifies to sqrt(1-x^2).
         | 
         | 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".
        
           | noosphr wrote:
           | How is going from two functions with one variable to three
           | functions with a variable and a constant a simplification?
        
             | jmyeet wrote:
             | If you can't recognize how much simpler the simplified
             | version is, I'm not sure exactly what to tell you. But
             | let's think about it in terms of assembly steps:
             | 
             | 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).
        
               | noosphr wrote:
               | If simplify means make it fast for a computer to run we
               | might as well make division illegal.
        
               | oh_my_goodness wrote:
               | This is sometimes helpful. But more often it has very
               | little overlap with what I need when I "simplify" some
               | math.
               | 
               | "Simplify" is a very old term (>50y) in computer algebra.
               | Its meaning has become kind of layered in that time.
        
           | tzs wrote:
           | OK, something weird is going on with HN here.
           | 
           | 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.
        
         | nurettin wrote:
         | In this case, a heuristic like "less parameters, less operators
         | and less function calls" covers all the cases.
        
           | oh_my_goodness wrote:
           | It doesn't, because we might consider different outputs
           | "simple" depending on what we're going to do next.
        
         | henrikeh wrote:
         | While some comments do point out the general opaqueness of
         | Mathematica, the goal of Simplify is actually documented in
         | Mathematica and something which can be changed:
         | https://reference.wolfram.com/language/ref/ComplexityFunctio...
         | 
         | 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.
        
       | bryango wrote:
       | I really wish Mathematica would open-source the heuristics behind
       | these core functions (including common mathematical functions,
       | Simplify, Integrate, etc.). The documentation is good, but it
       | still lags behind the actual implementation. It would be much
       | easier if we could peek inside the black box.
        
         | MinimalAction wrote:
         | That blackbox being their entire moat, I would assume they'd
         | never want to open-source any function. Mathematica as a front-
         | end has innumerable frustrating bugs, but its CAS is top-notch.
         | Especially combined with something like Rubi for integration,
         | for me nothing comes close to Mathematica for algebraic
         | computations.
        
           | eulerboiler wrote:
           | Many functions source ate viewable. Use https://resources.wol
           | framcloud.com/FunctionRepository/resour...
        
             | gdelfino01 wrote:
             | Many built-in functions are open source too. Use the
             | "PrintDefinitions" ResourceFunction to see the code of
             | functions that are implemented in Wolfram Language itself.
        
               | mkl wrote:
               | Source available? The license is still proprietary,
               | right?
        
               | LegionMammal978 wrote:
               | Yes, it is all proprietary, but there are still ways to
               | inspect most of the WL-implemented functions since the
               | system does not go to extreme pains to keep them hidden
               | from introspection. It is not unlike Maple in that sense.
        
               | oh_my_goodness wrote:
               | Yeah, hiding the recipes for how the math is really done
               | would make the whole system kinda guess-and-hope for
               | serious users.
        
         | Someone wrote:
         | For Simplify, I expect its a black, or at least gray box to
         | Mathematica maintainers, too.
         | 
         | 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
         | "[?]x2 = |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".
        
           | kccqzy wrote:
           | A lot of problems look like this. A while ago I was working
           | on a calendar event optimization (think optimizing "every
           | Monday from Jan 1, 2026 to March 10, 2026" + "every Monday
           | from March 15, 2026 to March 31, 2026" to simply "every
           | Monday from Jan 1, 2026 to March 31, 2026"). I wrote a number
           | of intuitive and simple optimization passes as well as some
           | unit tests. To my horror, some passes need to be repeated
           | twice in different parts of the pipeline to get the tests to
           | pass.
        
             | AlotOfReading wrote:
             | You can simplify most of _those_ problems by writing the
             | constraints down in conjunctive /disjunctive normal forms
             | and applying standard simplification on them, like you're
             | back in school. That also eliminates things like
             | repetition, since doing so also makes the problem
             | declarative. If you need the recursive loops, you're
             | guaranteed to be to stratify them for any reasonable
             | problem. If you wanted, you could solve the problem
             | optimally from this point by finding the prime implicants,
             | or just accept a suboptimal solution that runs faster than
             | you have any reason to care about, like datalog and sql do.
             | 
             | That doesn't work in general for mathematica because it's
             | too powerful.
        
               | LegionMammal978 wrote:
               | Even for boolean logic problems, a minimum-size CNF or
               | DNF will not necessarily be the cheapest solution in
               | terms of gates. As far as I know, hardly anyone has even
               | attempted automatic minimization in terms of general
               | binary operators.
        
           | evanb wrote:
           | As a term-rewriting system the rule x-x=0 presumably won't be
           | in Simplify, it'll be inside - (or Plus, actually). Instead
           | I'd expect there to be strategies. Pick a strategy using a
           | heuristic, push evaluation as far as it'll go, pick a
           | strategy, etc. But a lot of the work will be normal
           | evaluation, not Simplify-specific.
        
       | SillyUsername wrote:
       | I've only an A-Level in Further Maths from 1997, but understand
       | complex numbers and have come across complex inverse trig
       | functions before.
       | 
       | 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.
        
         | kzrdude wrote:
         | Simple rule to keep in mind that even math savvy people seem to
         | forget about is that: sqrt(x2) = |x| with bars for absolute
         | value.
         | 
         | 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.
        
           | tzs wrote:
           | > Simple rule to keep in mind that even math savvy people
           | seem to forget about is that: sqrt(x2) = |x| with bars for
           | absolute value.
           | 
           | i would disagree with that (pun intended).
        
       | derf_ wrote:
       | This sentence confused me: "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," not the least of which because the
       | two input expressions are the same, but also because we started
       | out by saying Sinh[ArcCosh[-2]] = -Sqrt[3], which is not at all
       | near 11.214 +/- 2.89845 I.
       | 
       | 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.
        
         | johndcook wrote:
         | Thanks. That was a mess. Don't know what happened, but I fixed
         | it this morning.
        
       | ogogmad wrote:
       | Does anyone else think that the latest LLMs - some of which can
       | be used locally for free - combined with proof-verifying software
       | like Coq or Lean for mistake-detection, might make many uses of
       | Computer Algebra Systems like Mathematica obsolete?
       | 
       | 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.
        
         | densh wrote:
         | For me Mathematica is much more akin to
         | numpy+sympy+matplotlib+... with absolutely crazy amount of
         | batteries included in a single coherent package with IDE and
         | fantastic documentation. In a way numpy ecosystem already "won"
         | industry users over, yet Wolfram stack is still appealing to me
         | personally for small experiments.
         | 
         | Coq/Lean target very different use cases.
        
         | kccqzy wrote:
         | Do you want your LLM to generate one hundred lines of code to
         | do things using open source libraries, or five lines in
         | Mathematica?
         | 
         | 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_.
        
       | Almondsetat wrote:
       | And yet it incorrectly simplifies f(x) = x/x with f(x) = 1
        
         | rfc3092 wrote:
         | I believe this is correct: x/x = 1 everywhere except 0, where
         | it has a removable singularity. So you can extend x/x
         | holomorphically to full C.
         | 
         | 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).
        
           | newobj wrote:
           | PLEASE explain "So you can extend x/x holomorphically to full
           | C" to someone with only a BSc in math/cs; something about
           | this thread is giving me an existential crisis right now.
        
             | rfc3092 wrote:
             | - function extension is defining a function where it is not
             | defined
             | 
             | - <Adj> function extension is an extension that keeps (or
             | gives) Adj property
             | 
             | - extended function is usually treated as originals if
             | extension is good enough. Real analysis starts with
             | defining real numbers and extending familiar functions onto
             | them
             | 
             | - in this particular case we do not need C - even
             | continuous extension on R works and agrees with x/x = 1 at
             | 0
             | 
             | - holomorphic (analytic) extension makes function
             | infinitely differentiable at every point of C
             | 
             | - because of the nature of discontinuity you can't extend
             | the simple arccosh in any reasonable way on C without
             | introducing multivalued or path-dependent functions
             | 
             | - this continuity makes x/x=1 a reasonable simplification
             | for CAS imo but not for complex functions as in the OP
             | 
             | - many things with point singularities in R have more
             | structure in C, but x/x is not one of them. Even 1/x is of
             | a different nature.
             | 
             | "You do not divide by zero" that forces you to carry x != 0
             | is more of a high-school construct than a real thing.
             | Physicists ignore even more important stuff, and in the end
             | their formulas work "just fine".
        
             | rfc3092 wrote:
             | As for existential crisis, you probably have missed this
             | one: https://news.ycombinator.com/item?id=46962402
             | 
             | It was really fun
        
       | rfc3092 wrote:
       | This is what differentiates (pun intended) between Complex
       | Algebra and Complex Analysis: complex functions in analysis are
       | multivalued (or path dependent in some schools). Even a simple
       | concept of value of F at complex point x becomes a topic of
       | several lectures.
       | 
       | I'm algebraist at heart and training, but I remember beautiful
       | many-layered surfaces of ordinary complex functions in books and
       | on blackboards.
        
       | meatmanek wrote:
       | > For example, Sinh[ArcCosh[2]] returns -[?]3 but [?](22 - 1) =
       | [?]3. The expression Mathematica returns for Sinh[ArcCosh[x]]
       | correctly evaluates to -[?]3
       | 
       | but the expression given is sqrt((x-1)/(x+1))(x+1), which for x=2
       | would be sqrt(1/3)*3 = sqrt(3)
       | 
       | did you mean Sinh[ArcCosh[-2]]?
        
       ___________________________________________________________________
       (page generated 2026-03-15 23:01 UTC)