# Inverse trig function implementations

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

[-π/2, π/2].

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

(-π/2, π/2).

For inverse cosine, the usual choice is to return values in the closed interval

[0, π].

## Naming conventions

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 `ArcTan`.

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,

`    atan2(-1, 1)`

returns -π/4; because the point (1, -1) is in the 4th quadrant, it returns an angle in the 4th quadrant. But

`    atan2(1, -1)`

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.

## Complex values

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,

`    math.asin(2)`

returns a domain error and

`    scipy.arcsin(2)`

returns 1.5707964 + 1.3169578i.

In Common Lisp,

`    (asin 2)`

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

`    ArcSin[2.]`

returns 1.5707964 – 1.3169578i.

## Branch cuts

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”

1. Mathematica’s ArcTan also accepts two arguments, but in reversed order: atan2(y,x) (in other languages) but ArcTan[x,y].