Skip to content

Trig & Hyp Functions

vmathmachine edited this page Jul 14, 2022 · 7 revisions

If you were looking for the inverse trigonometric/hyperbolic functions, please click here.

The 6 main trigonometric and 6 main hyperbolic functions are all implemented in this library. They're all public methods in the Complex class which do not alter their instance. They each also have a corresponding static method in the Cpx class, where the argument is in the parentheses rather than before the period.

The Hyperbolic Cosine, Sine, and Tangent (cosh, sinh, and tanh) are all defined through their circular equivalents: cosine, sine, and tangent (cos, sin, and tan). Yes, you can perform trig functions on complex numbers. It matters not that the inputs can't be represented as angles, so long as all the patterns that were preserved with real numbers carry on to imaginary numbers.

sec, csc, cot, sech, csch, and coth are all defined as the reciprocal of cos, sin, tan, cosh, sinh, and tanh respectively. That is exactly how they are defined in the code, and there's nothing else to it.

Implementation:

Complex cos()

Returns the cosine (in radians). The code first tests for 2 trivial special cases, before using the default case. In the default case, we utilize the formula cos(x+yi) = cos(x)cosh(y) - sin(x)sinh(y)i. The cosh and sinh are computed with Mafs.fsinhcosh, and the cos and sin are Mafs.cos and Mafs.sin.

As mentioned, though, there are 2 special cases. If the input is strictly real, we return Mafs.cos(re)+0i. If the input is strictly imaginary, we return Math.cosh(im)+0i.

Complex sin()

Returns the sine (in radians). The code first tests for 2 trivial special cases, before using the default case. In the default case, we utilize the formula sin(x+yi) = sin(x)cosh(y) + cos(x)sinh(y)i. The cosh and sinh are computed with Mafs.fsinhcosh, and the cos and sin are Mafs.cos and Mafs.sin.

As mentioned, though, there are 2 special cases. If the input is strictly real, we return Mafs.sin(re)+0i. If the input is strictly imaginary, we return 0+Math.sinh(im)i.

Complex tan()

Returns the tangent (in radians). The code first tests for 4 special cases, before using the default case. In the default case, we utilize the following formula: tan(x+yi) = (sin(2x)+sinh(2y)i)/(cos(2x)+cosh(2y)).

As mentioned, though, there are 4 special cases. If the input is strictly real, we return Mafs.tan(re)+0i. If the input is strictly imaginary, we return 0+Math.tanh(im)i. If the imaginary part is more than 20 or less than -20, we return 0+Mafs.sgn(im)i. And the last special case, if the input is close to an odd multiple of π/2, we compute the cotangent, then return the reciprocal. The reason for the last special case is that the denominator of the default formula underflows when the input is too close to an odd multiple of π/2, and instead of giving just a very large number (as it's supposed to), it gives ∞. The cotangent is computed via cot(x+yi) = (sin(2x)-sinh(2y)i)/(cosh(2x)-cos(2y)).

Complex cosh()

Returns the hyperbolic cosine. All the function does is copy the input, multiply by i, then return the cos.

Complex sinh()

Returns the hyperbolic sine. All the function does is copy the input, multiply by i, compute the sin, multiply by -i, and return the result.

Complex tanh()

Returns the hyperbolic tangent. All the function does is copy the input, multiply by i, compute the tan, multiply by -i, and return the result.

Complex sec()

Complex csc()

Complex cot()

Returns the secant, cosecant, and cotangent respectively (in radians). All it does is compute the cosine/sine/tangent, then return the reciprocal.

Complex sech()

Complex csch()

Complex coth()

Returns the hyperbolic secant, hyperbolic cosecant, and hyperbolic cotangent respectively. All it does is compute the hyperbolic cosine/sine/tangent, then return the reciprocal.

Background:

Due to Euler's Formula (not to be confused with Euler's Identity), we now know that angles and trigonometry are heavily tied together with complex numbers and exponentials. The formula states:

e^(Θi) = cos(Θ)+sin(Θ)i

(Where Θ is in radians)

Since nothing about this formula specifically restricts theta to being a real number, this allows us to extend trigonometric functions to all complex inputs.

The most obvious way to extend the cosine and sine is just to define them as the real and imaginary parts of e^(Θi). However, this definition sucks. It guarantees that the output can only ever be real. Not only that, but it also removes all the fancy properties that make the cosine and sine so useful. For instance, the identity cos²+sin²=1 would only be valid for real inputs.

An alternative way to define the cosine and sine is by observing that, if you apply Euler's formula to negative Θ, you get:

e^(-Θi) = cos(-Θ)+sin(-Θ)i = cos(Θ)-sin(Θ)i.

If you add together both formulas, then divide by 2, we find that (e^(Θi)+e^(-Θi))/2 = cos(θ)

Alternatively, if you subtract both formulas, then divide by 2i, we find that (e^(θi)-e^(-θi))/(2i) = sin(θ)

Mathematicians went with this definition, because with it, all the nice fancy properties of cosines and sines are preserved. Observe:

cos²(Θ)+sin²(Θ) = (e^(2Θi)+2e^0+e^(-2Θi))/4 + (e^(2Θi)-2e^0+e^(-2Θi))/(-4) = (e^(2Θi)+2+e^(-2Θi))/4 - (e^(2Θi)-2+e^(-2Θi))/4 = (e^(2Θi)+2+e^(-2Θi) -e^(2Θi)+2-e^(-2Θi))/4 = 4/4 = 1.

cos(Θ)cos(φ)-sin(Θ)sin(φ) = (e^(Θi)+e^(-Θi))(e^(φi)+e^(-φi))/4 - (e^(Θi)-e^(-Θi))(e^(φi)-e^(-φi))/(-4) = (e^(Θi)+e^(-Θi))(e^(φi)+e^(-φi))/4 + (e^(Θi)-e^(-Θi))(e^(φi)-e^(-φi))/4 = (e^(Θi)(e^(φi)+e^(-φi)) + e^(-Θi)(e^(φi)+e^(-φi)))/4 + (e^(Θi)(e^(φi)-e^(-φi)) - e^(-Θi)(e^(φi)-e^(-φi)))/4 = (e^(Θi)(2e^(φi)) + e^(-Θi)(2e^(-φi)) )/4 = (e^((Θ+φ)i) + e^(-(Θ+φ)i))/2 = cos(Θ+φ)

cos(Θ)sin(φ)+sin(Θ)cos(φ) = (e^(Θi)+e^(-Θi))(e^(φi)-e^(-φi))/(4i) + (e^(Θi)-e^(-Θi))(e^(φi)+e^(-φi))/(4i) = (e^(Θi)(e^(φi)-e^(-φi)) + e^(-Θi)(e^(φi)-e^(-φi)))/(4i) + (e^(Θi)(e^(φi)+e^(-φi)) - e^(-Θi)(e^(φi)+e^(-φi)))/(4i) = (e^(Θi)(2e^(φi)) - e^(-Θi)(2e^(-φi)) )/(4i) = (e^((Θ+φ)i) - e^(-(Θ+φ)i))/(2i) = sin(Θ+φ)

d/dθ sin(θ) = d/dθ (e^(θi)-e^(-θi))/(2i) = (ie^(θi)-(-i)e^(-θi))/(2i) = (e^(θi)+e^(-θi))/2 = cos(θ)

And so on and so forth.

As always, we also define the tangent to be the sine over cosine, which can be rewritten as (e^(Θi)-e^(-Θi))/(i(e^(Θi)+e^(-Θi))). With reciprocals, we also get the secant, cosecant, and cotangent.

In 1760, mathematicians defined another set of functions: the hyperbolic functions. These are essentially just a generalization of the original trigonometric functions, but with imaginary arguments.

cosh(x) is defined as cos(x*i)

sinh(x) is defined as sin(x*i)/i

tanh(x) is defined as tan(x*i)/i

And so on and so forth. In other words, the hyperbolic function is defined as the original function, but with the input multiplied by i. Then, we'd either multiply our answer by i, divide our answer by i, or do nothing. Which one we did really just depended on which option gave us a real output given real inputs. Alternatively, if we plug these definitions into the exponential formulas provided earlier, we find that:

cosh(x) = (e^x+e^-x)/2

sinh(x) = (e^x-e^-x)/2

tanh(x) = (e^x-e^-x)/(e^x+e^-x)

Which, you might notice, none of these formulas require any imaginary numbers. Which may or may not be useful, if you happen to have a calculator that doesn't support imaginary numbers or have any hyperbolic functions built into it.

The reason they're called hyperbolic functions is that, just as the trigonometric functions can be used to parameterize the unit circle, the hyperbolic functions can be used to parameterize the unit hyperbola.

The coordinates (cos(t), sin(t)) will always lie on the unit circle.

The coordinates (cosh(t), sinh(t)) will always lie on the unit hyperbola.

Of course, circles are far more common than hyperbolas, so it might initially seem a bit superfluous to do so. However, it's not just the shape we're concerned about. Many applications of trig functions arise from the very relation x²+y²=(some constant), which plots out a circle. Similarly, many applications of the hyperbolic functions arise from the relation x²-y²=(some constant), which plots out a hyperbola. The first identity can be satisfied not only by sine and cosine, mind you, but also by sech and tanh. Meanwhile, the second identity can be satisfied by sec and tan, csc and cot, cosh and sinh, or coth and csch.

There are also plenty of non-trig functions which satisfy the identity x²+y²=1, such as the very simple x(t,u) = (t²-u²)/(t²+u²), y(t,u) = 2tu/(t²+u²) (which is the formula most commonly used to find rational Pythagorean triples).

There's also a surprising application of the hyperbolic functions, the catenary arc. Whenever you see a telephone wire sag, the shape it draws out is known as a catenary arc. Which, we now know today, is the shape drawn out by the function y=cosh(x) (or, rather, some shifted shaled version of that graph). In fact, if you take any uniformly dense string, hold both ends in random locations, and wait long enough, it'll eventually take the shape of a catenary arc. That's because this is the only shape a string can take such that the net force on all points on the string is equal to 0 (assuming it's affected by the force of gravity), so when it eventually loses all of it's energy to heat, it must eventually take that shape. And before you get any bright ideas, yes, a straight line is also a catenary arc. If you zoom in infinitely close to a catenary shape, you'll see a straight line.

To be frank, there are many, many, many, many things that could be said about hyperbolic and trigonometric functions. Instead of spending several days listing them all, I'll just move on to something that needs to be addressed:

The Algorithms Used

If you look at my code, or even read my earlier documentation, you might notice that those fancy formulas:

cos(θ) = (e^(θi)+e^(-θi))/2

sin(θ) = (e^(θi)-e^(-θi))/(2i)

are nowhere to be seen. What gives? Why did you even show them to me if you weren't even gonna use them?

Well, first of all, I felt it gave some useful background. Rather than just waving my hands and saying "you can take cosines and sines of imaginary numbers that can't even be represented as angles," I decided it'd be better to do a full on nerd rant about why and how it even makes sense to do trigonometry on complex numbers. Second of all, that was actually the algorithm I originally used to calculate trig functions, before I realized there was a more efficient algorithm. And third of all, the explanation helps introduce the concept of hyperbolic trig functions, which are used in the new, more efficient algorithm.

You might be familiar with the relations:

cos(a+b) = cos(a)cos(b) - sin(a)sin(b)

sin(a+b) = sin(a)cos(b) + cos(a)sin(b)

Well, it just so happens that those formulas (as well as every other trig identity) also apply to non-real inputs.

This is helpful, because what if instead of a and b, we had x (a real number) and y*i (an imaginary number)?

cos(x+yi) = cos(x)cos(yi) - sin(x)sin(yi)

sin(x+yi) = sin(x)cos(yi) + cos(x)sin(yi)

If you remember the earlier identities about the relationship between cosh, cos, and i and between sinh, sin, and i, you can plug those in to get

cos(x+yi) = cos(x)cosh(y) - sin(x)sinh(y)i

sin(x+yi) = sin(x)cosh(y) + cos(x)sinh(y)i

Which is great, because right off the bat, our components are already split up for us. As long as we can calculate cos, sin, cosh, and sinh, we're set!

But wait...what about tan?

Well, tan is a bit more complicated. But luckily, still doable. And doable in a way that's a bit more efficient than just dividing sine by cosine.

tan(x+yi) = sin(x+yi)/cos(x+yi)

tan(x+yi) = (sin(x)cosh(y)+cos(x)sinh(y)i)/(cos(x)cosh(y)-sin(x)sinh(y)i)

tan(x+yi) = (sin(x)cosh(y)+cos(x)sinh(y)i)*(cos(x)cosh(y)+sin(x)sinh(y)i)/(cos²(x)cosh²(y)+sin²(x)sinh²(y))

tan(x+yi) = (cos(x)sin(x)cosh²(y) + sin²(x)cosh(y)sinh(y)i + cos²(x)cosh(y)sinh(y)i - cos(x)sin(x)sinh²(y))/(cos²(x)cosh²(y)+sin²(x)sinh²(y))

cos²(x)+sin²(x) = 1

cosh²(y)-sinh²(y) = 1

tan(x+yi) = (cos(x)sin(x) + cosh(y)sinh(y)i) / (cos²(x)cosh²(y)+sin²(x)sinh²(y))

sin²(x) = 1-cos²(x)

tan(x+yi) = (cos(x)sin(x) + cosh(y)sinh(y)i) / (cos²(x)cosh²(y)+sinh²(y)-cos²(x)sinh²(y))

tan(x+yi) = (cos(x)sin(x) + cosh(y)sinh(y)i) / (cos²(x)(cosh²(y)-sinh²(y))+sinh²(y))

tan(x+yi) = (cos(x)sin(x) + cosh(y)sinh(y)i) / (cos²(x)+sinh²(y))

tan(x+yi) = (cos(x)sin(x) + cosh(y)sinh(y)i) / (cos²(x)+cosh²(y)-1)

tan(x+yi) = (2cos(x)sin(x) + 2cosh(y)sinh(y)i) / (2cos²(x)+2cosh²(y)-2)

2cos(x)sin(x) = sin(2x)

2cosh(y)sinh(y) = sinh(2y)

2cos²(x)-1 = cos(2x)

2cosh²(y)-1 = cosh(2y)

tan(x+yi) = (sin(2x)+sinh(2y)i) / (cos(2x)+cosh(2y))

tan(x+yi) = sin(2x) / (cos(2x)+cosh(2y)) + sinh(2y)i / (cos(2x)+cosh(2y))

And, there we have it. A formula for the tangent of a complex number.

Clone this wiki locally