Programming languages differ in the names they use for inverse trig functions, and in some cases differ in their return values for the same inputs.
Choice of range
If sin(θ) = x, then θ is the inverse sine of x, right? Maybe. Depends on how you define the inverse sine. If -1 ≤ x ≤ 1, then there are infinitely many θ’s whose sine is x. So you have to make a choice.
The conventional choice is for inverse sine to return a value of θ in the closed interval
Inverse tangent uses the same choice. However, the end points aren’t possible outputs, so inverse tangent typically returns a value in the open interval
For inverse cosine, the usual choice is to return values in the closed interval
Aside from how to define inverse trig functions, there’s the matter of what to call them. The inverse of tangent, for example, can be written tan-1, arctan, or atan. You might even see arctg or atn or some other variation.
Most programming languages I’m aware of use
atan etc. Python uses
atan, but SciPy uses
arctan. Mathematica uses
Software implementations typically follow the conventions above, and will return the same value for the same inputs, as long as inputs and outputs are real numbers.
Arctangent with two arguments
Many programming languages have a function
atan2 that takes two arguments, y and x, and returns an angle whose tangent is y/x. Note that the y argument to
atan2 comes first: top-down order, numerator then denominator, not alphabetical order.
However, unlike the one-argument
atan function, the return value may not be in the interval (-π/2, π/2). Instead,
atan2 returns an angle in the same quadrant as x and y. For example,
returns -π/4; because the point (1, -1) is in the 4th quadrant, it returns an angle in the 4th quadrant. But
returns 3π/4. Here the point (-1, 1) and the angle 3π/4 are in the 2nd quadrant.
In Common Lisp, there’s no function named
atan2; you just call
atan with two arguments. Mathematica is similar: you call
ArcTan with two arguments. However, Mathematica uses the opposite convention and takes x as its first argument and y as its second.
Some software libraries support complex numbers and some do not. And among those that do support complex numbers, the return values may differ. This is because, as above, you have choices to make when extending these functions to complex inputs and outputs.
For example, in Python,
returns a domain error and
returns 1.5707964 + 1.3169578i.
In Common Lisp,
returns 1.5707964 – 1.3169578i. Both SciPy and Common Lisp return complex numbers whose sine equals 2, but they follow different conventions for what number to chose. That is, both
scipy.sin(1.5707964 - 1.3169578j) scipy.sin(1.5707964 + 1.3169578j)
in Python and
(sin #C(1.5707964 -1.3169578)) (sin #C(1.5707964 +1.3169578))
in Common Lisp both return 2, aside from rounding error.
In C99, the function
casin (complex arc sine) from <complex.h>
double complex z = casin(2);
returns 1.5707964 + 1.3169578i. The Mathematica call
returns 1.5707964 – 1.3169578i.
The Common Lisp standardization committee did a very careful job of defining math functions for complex arguments. I’ve written before about this here. You don’t need to know anything about Lisp to read that post.
The committee ultimately decided to first rigorously define the two-argument arctangent function and bootstrap everything else from there. The post above explains how.
Other programming language have made different choices and so may produce different values, as demonstrated above. I mention the Common Lisp convention because they did a great job of considering every detail, such as how to handle +0 and -0 in IEEE floating point.
One thought on “Inverse trig function implementations”
Mathematica’s ArcTan also accepts two arguments, but in reversed order: atan2(y,x) (in other languages) but ArcTan[x,y].