Skip to content

Trig & Hyp Functions

vmathmachine edited this page Apr 11, 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.

Cosine, Sine, and Tangent (cos, sin, and tan) are all defined through their hyperbolic equivalents: cosh, sinh, and tanh. This will likely change soon, however, due to the former being used more often than the latter.

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

Implementation:

Complex cosh()

Returns the hyperbolic cosine. The code first tests for 2 trivial special cases, before using the default case. In the default case, we utilize the formula cosh(x+yi) = cosh(x)cos(y) + sinh(x)sin(y)i. The cosh and sinh are computed with 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 Math.cosh(re)+0i. If the input is strictly imaginary, we return Mafs.cos(im)+0i.

Complex sinh()

Returns the hyperbolic sine. The code first tests for 2 trivial special cases, before using the default case. In the default case, we utilize the formula sinh(x+yi) = sinh(x)cos(y) + cosh(x)sin(y)i. The cosh and sinh are computed with 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 Math.sinh(re)+0i. If the input is strictly imaginary, we return 0+Mafs.sin(im)i.

Complex tanh()

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

As mentioned, though, there are 3 special cases. If the input is strictly real, we return Math.tanh(re)+0i. If the input is strictly imaginary, we return 0+Mafs.tan(im)i. Finally, if the real part is more than 20 or less than -20, we return Mafs.sgn(re)+0i.

It should be noted, however, there is another special case, and it has yet to be implemented. It occurs when the input's real part is close to (but not equal to) 0, and the imaginary part is close to or equal to an odd multiple of π/2. In this case, the input is supposed to be some large number inversely proportional to how far we are from 0+N*πi/2, but instead, it just gives ∞.

Complex cos()

Returns the cosine (in radians). All the function does is copy the input, multiply by i, then return the cosh.

Complex sin()

Returns the sine (in radians). All the function does is copy the input, multiply by i, compute the sinh, multiply by -i, and return the result.

Complex tan()

Returns the tangent (in radians). All the function does is copy the input, multiply by i, compute the tanh, 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.

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 these, such as the very simple (x²-y²)/(x²+y²), 2xy/(x²+y²) (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).

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

(NOTE: as of right now, trig functions are actually defined in terms of their hyperbolic counterparts. I originally did it that way because, back when they were all defined in terms of exponentials, it was just easier that way. However, as I struggle to come up with a good explanation for why trig functions should be defined in terms of hyperbolics, instead of just vice versa, I realize that, due to one being used more often than the other, it might be best to swap them around. At least for the normal trig functions. For the inverses, though, it still makes sense that way).

Clone this wiki locally