#import "/common.typ": post, static, img #show: post.with( title: "atan2", date: datetime(year: 2018, month: 5, day: 13), ) $ op("atan2"): RR^2 without (0, 0) -> (-pi, pi] $ $ op("atan2")(y, x) = cases( +pi / 2, (x = 0) and (y > 0), -pi / 2, (x = 0) and (y < 0), tan^(-1)(y / x), x > 0, tan^(-1)(y / x) + pi, (x < 0) and (y >= 0), tan^(-1)(y / x) - pi, (x < 0) and (y < 0), ) $ where $tan^(-1) x$ is the principal value of the arctangent, ie. the one in the interval $(-pi, pi]$. = Properties #figure( img(static("math/atan2-plot.png")), caption: [A 3D plot of atan2(y, x).], ) - $op("atan2")(-y, x) = -op("atan2")(y, x)$ - $op("atan2")(c y, c x) = op("atan2")(y, x)$ for any $c > 0$. - Discontinuous along $(x < 0) and (y = 0)$: For any $x < 0$: - $lim_(y -> 0^-) op("atan2")(y, x) = -pi$ - $lim_(y -> 0^+) op("atan2")(y, x) = pi$ == Partial derivatives The partial derivatives, just like the function itself, are defined everywhere except at the origin. Furthermore, unlike the function, they're not discontinuous along $y = 0$ (except at the origin). $ & (partial)/(partial y) = x / (x^2 + y^2) \ & (partial)/(partial x) = -y / (x^2 + y^2) $ Interesingly, the function $tan^(-1)(y / x)$ has the same partial derivatives. = Systems of equations involving the cosine and the sine of an unknown #figure( img(static("math/polar-coords.png")), caption: [A geometric intepretation: θ = atan2(y,x).], ) Let $theta, x, y in RR$. Consider the following system of equations: $ cases( sin theta = y, cos theta = x, ) $ If $x^2 + y^2 = 1$, this system has a unique (up to a multiple of $2 pi$) solution: $ theta = op("atan2")(y, x) + 2 pi k $ for any $k in ZZ$. For simplicity k is often set to zero. Because $op("atan2")(sin theta, cos theta) = theta$ (up to a multiple of $2 pi$), atan2 can be thought of as the "inverse" of the cosine and sine of the same argument. = C's atan2 The definition at the beginning of this article is suitable for mathematical analysis. However, a more intricate definition is needed for floating-point computation, one that takes signed zeros and infinites into account. The following appears in the C standard: $ op("atan2")(y, x) = cases( op("NaN") & "if" space (y = op("NaN")) or (x = op("NaN")), plus.minus pi & "if" space (x < +0) and (y = plus.minus 0), plus.minus 0 & "if" space (x > +0) and (y = plus.minus 0), -pi / 2 & "if" space (x = plus.minus 0) and (y < -0), pi / 2 & "if" space (x = plus.minus 0) and (y > +0), plus.minus pi & "if" space (x = -0) and (y = plus.minus 0), plus.minus 0 & "if" space (x = +0) and (y = plus.minus 0), pi & "if" space (x = -infinity) and (y > +0) and (y < +infinity), -pi & "if" space (x = -infinity) and (y < -0) and (y > -infinity), +0 & "if" space (x = +infinity) and (y > +0) and (y < +infinity), -0 & "if" space (x = +infinity) and (y < -0) and (y > -infinity), plus.minus pi / 2 & "if" space (x > -infinity) and (x < +infinity) and (y = plus.minus infinity), plus.minus (3 pi) / 4 & "if" space (x = -infinity) and (y = plus.minus infinity), plus.minus pi / 4 & "if" space (x = +infinity) and (y = plus.minus infinity), tan^(-1)(y / x) & "if" space x > +0, tan^(-1)(y / x) + pi & "if" space (x < -0) and (y >= 0), tan^(-1)(y / x) - pi & "if" space (x < -0) and (y < -0), ) $ In this definition $op("atan2")(0, 0)$ is *not* undefined. = See also - #link("https://linux.die.net/man/3/atan2")[atan2(3)] - #link("https://en.wikipedia.org/wiki/Atan2")[Atan2] - #link("https://en.wikipedia.org/wiki/Argument_(complex_analysis)")[Argument (complex analysis)] - #link("https://en.wikipedia.org/wiki/Inverse_trigonometric_functions")[Inverse trigonometric functions]