Pavel Panchekha

By

Share under CC-BY-SA.

Deciding Equality for Trigonometric Expressions

One thing Herbie does is simplify stuff, and one that I am personally interested in is simplifying trigonometric expressions. For example, did you know that sin(x) / (1 + cos(x)) and (1 - sin(x)) / cos(x) are the same? Or that both are equal to tan(x / 2)? But how can we do this automatically?

Before I move on, a thank you to ChatGPT, mostly o3 and 4.1, for generative discussions.

The Weirstrass Substitution

One key to any discussion of trigonometric stuff is the Weirstrass substitution.1 [1 Which Wikipedia informs me was actually invented by Euler and doesn't have much to do with Weirstrass! If we didn't want to name it after Euler (reasonable) we should name it after Legendre.]

This substitution just observes the following fact. Both sin(x) and cos(x) can be rewritten as rational functions of tan(x/2). If \(t = \tan(x/2)\) then:

\[ \sin(x) = \frac{2t}{1 + t^2} \text{ and } \cos(x) = \frac{1 - t^2}{1 + t^2} \]

Moreover, tan(x/2) can take on any real value, so this is a complete parameterization.

This already suggests a decision procedure over expressions of sin(x) and cos(x): rewrite using the Weirstrass substitution and check equality by cross-multiplying, distributing, and canceling.

Deciding equality with multiple variables

Now let's suppose you have multiple variables, like x, y, and so on. And let's suppose we constrain the arguments to trig functions to be rational linear combinations of those variables.

Then for each variable, we can compute the common denominator for its terms. Next, we can expand sin(a x + b y) into sin(a x) and sin(b y) and similar cosine terms, using the normal angle addition rules. Next, we can put all the coefficients into that common denominator and expand sin(a x / n) to sin(x / n), and likewise for cosine, using again the standard angle addition rules. Finally, we can apply the Weirstrass (Legendre) substitution, which finally transforms us into a rational function with a single \(t_x\) variable for each initial variable.

We can now decide equality for these rational functions, again using normal polynomial steps.

Conclusion

I don't have a use case for this yet, but I was delighted to be reminded of the Legendre (Weirstrass) substitution and how useful it is for all sorts of polynomial reasoning.

Footnotes:

1

Which Wikipedia informs me was actually invented by Euler and doesn't have much to do with Weirstrass! If we didn't want to name it after Euler (reasonable) we should name it after Legendre.