atan2 — Quadrant-aware inverse tangent atan2(y, x) with MATLAB-compatible broadcasting.
theta = atan2(y, x) computes the four-quadrant inverse tangent of the point (x, y). It returns angles in radians covering the range (-pi, pi], giving robust results even when x is zero.
How does the atan2 function behave in MATLAB / RunMat?
- Inputs can be scalars, vectors, matrices, or N-D tensors of real numeric, logical, or character data. MATLAB-style implicit expansion (broadcasting) applies when shapes are compatible.
atan2treatsyas the numerator andxas the denominator:atan2(Y, X)equalsatan(Y ./ X)but keeps the correct quadrant and handles zero denominators.- Logical inputs are cast to
double, character arrays use their Unicode code points, and integer inputs are promoted todouble, mirroring MATLAB promotion rules. - Complex inputs are **not** supported; MATLAB raises an error and RunMat matches that behaviour.
atan2(0, 0)returns0.atan2(±0, -0)follows IEEE-754 semantics, matching MATLAB for signed zeros and infinities.atan2(NaN, x)oratan2(y, NaN)returnsNaN; inputs containingInfcombinations follow IEEE-754 quadrant semantics exactly like MATLAB.- The output always has double precision and the same size as the broadcasted inputs.
GPU behavior
When both operands already reside on the GPU and the active provider implements the elem_atan2 hook, RunMat executes the operation entirely on the device without reformatting buffers.
If shapes require implicit expansion or the provider lacks elem_atan2, RunMat transparently gathers both tensors to the host, computes the result with the reference CPU implementation, and continues execution.
When GPU work completes in single precision (because the provider only exposes 32-bit buffers), RunMat promotes the results to double precision whenever the data is materialised on the host so the observable behaviour still matches MATLAB.
Fusion-aware expressions (for example, sin(atan2(y, x))) can still emit a combined WGSL kernel; the fusion planner recognises atan2 as a binary elementwise primitive.
GPU residency
RunMat's planner keeps tensors on the GPU whenever profitable. Explicit gpuArray calls are optional—use them only when you need to control residency for interoperability. When elem_atan2 is unavailable, RunMat automatically gathers data to the CPU, performs the computation, and re-uploads results only when downstream consumers demand GPU residency.
Examples of using atan2 in MATLAB / RunMat
Computing the polar angle of a point
theta = atan2(4, 3)Expected output:
theta = 0.9273Determining quadrants for a vector of coordinates
Y = [-1 0 1];
X = [-1 -1 -1];
angles = atan2(Y, X)Expected output:
angles = [-2.3562 3.1416 2.3562]Broadcasting a scalar denominator across a matrix
A = [1 2 3; 4 5 6];
angles = atan2(A, 2)Expected output:
angles =
0.4636 0.7854 0.9828
1.1071 1.1903 1.2490Handling zero numerators and signed zeros
theta = atan2([0 -0], [-2 0])Expected output:
theta = [pi 0]Executing atan2 on the GPU
Gy = gpuArray([1 1; -1 -1]);
Gx = gpuArray([1 -1; 1 -1]);
angles_gpu = atan2(Gy, Gx);
angles = gather(angles_gpu)Expected output:
angles =
0.7854 2.3562
-0.7854 -2.3562Converting character data to angles
theta = atan2('A', 100)Expected output:
theta = 0.5764FAQ
What is the range of values returned by atan2?
Angles are given in radians and span the open/closed interval (-pi, pi]. Use rad2deg if you prefer degrees.
Can I supply complex inputs?
No. MATLAB raises an error for complex inputs, and so does RunMat. Convert complex data to magnitude/phase first if needed.
Does atan2 preserve the shape of the inputs?
Yes. After implicit expansion, the output shape matches the broadcasted size of Y and X.
How are logical or character inputs handled?
Logical values map to 0 and 1, and character arrays use their Unicode code point values (as doubles) before computing the angle.
What happens when x is zero?
atan2 still returns a finite result using the sign of y. For example, atan2(1, 0) returns pi/2, and atan2(-1, 0) returns -pi/2.
Are GPU and CPU results identical?
Double-precision providers match CPU results exactly. Single-precision providers can differ by routine IEEE rounding. RunMat automatically promotes to double when materialising host tensors to mirror MATLAB.
How can I compute angles in degrees?
Call rad2deg(atan2(y, x)) or multiply the result by 180/pi.
See also
atan, hypot, sin, tan, gpuArray, gather
Source & Feedback
- Source code: `crates/runmat-runtime/src/builtins/math/trigonometry/atan2.rs`
- Found a bug? Open an issue with a minimal reproduction.