View all functions

CategoryMath: Trigonometry
GPUYes

What does the atanh function do in MATLAB / RunMat?

Y = atanh(X) evaluates the inverse hyperbolic tangent of every element in X. Real inputs inside the open interval (-1, 1) remain real. Values with |x| > 1 (including ±Inf) automatically promote to complex results that match MATLAB's principal branch.

How does the atanh function behave in MATLAB / RunMat?

  • Accepts scalars, vectors, matrices, and N-D tensors using MATLAB broadcasting semantics.
  • Logical values are promoted to double precision (true → 1, false → 0) before evaluation. The results follow MATLAB's rules for infinities at the endpoints (atanh(1) = Inf, atanh(-1) = -Inf).
  • Real values with magnitude greater than 1 return complex numbers whose imaginary part is ±π/2. The runtime automatically promotes the entire tensor to Value::ComplexTensor so downstream consumers see the MATLAB-compatible complex result.
  • Complex inputs are evaluated with MATLAB's definition atanh(z) = 0.5 * log((1 + z) / (1 - z)), including correct handling of branch cuts, NaNs, and infinities.
  • Character arrays are treated as their numeric code points and converted to doubles before the inverse hyperbolic tangent is applied.
  • Empty arrays return empty outputs with matching shape and type.

atanh Function GPU Execution Behaviour

RunMat Accelerate keeps tensors on the GPU when:

  1. A provider is registered and implements the unary_atanh hook.
  2. Every element satisfies |x| ≤ 1 (allowing the endpoints for the ±Inf behaviour).

The runtime first calls the provider's reduce_min/reduce_max hooks to prove that the entire operand stays within the real domain [-1, 1]. If those hooks are missing, return an error, or detect a value outside the domain, RunMat gathers the tensor to the host, performs the computation with the CPU reference implementation, and returns MATLAB-accurate complex results. Users do not need to micromanage residency with gpuArray/gather; the runtime transparently falls back only when necessary.

Examples of using the atanh function in MATLAB / RunMat

Inverse hyperbolic tangent of a real scalar

y = atanh(0.5);

Expected output:

y = 0.5493

Applying atanh element-wise to a vector

x = linspace(-0.9, 0.9, 5);
y = atanh(x);

Expected output:

y = [-1.4722  -0.4847   0    0.4847   1.4722]

Dealing with values near ±1 in atanh

A = [0.99  1.0  -1.0; 0.0  0.5  -0.5];
B = atanh(A);

Expected output:

B =
    2.6467        Inf       -Inf
         0    0.5493    -0.5493

Producing complex outputs for |x| > 1

values = [2 -3];
result = atanh(values);

Expected output:

result =
   0.5493 + 1.5708i  -0.3466 + 1.5708i

Computing atanh for complex numbers

Z = [1 + 2i, -0.5 + 0.75i];
W = atanh(Z);

Expected output:

W =
   0.1733 + 1.1781i  -0.3104 + 0.7232i

Running atanh on GPU arrays

G = gpuArray(linspace(-0.8, 0.8, 4));
gpuResult = atanh(G);
hostResult = gather(gpuResult);

Expected output:

hostResult = [-1.0986  -0.2733   0.2733   1.0986]

GPU residency in RunMat (Do I need gpuArray?)

You usually do not need to call gpuArray manually. The auto-offload planner keeps tensors on the GPU whenever the provider exposes a working unary_atanh hook and every element satisfies |x| ≤ 1. If any element requires complex promotion or the provider lacks native support, RunMat automatically gathers to the host and still returns MATLAB-compatible results. Manual gpuArray / gather remains available for workflows that demand explicit residency control.

FAQ

When does atanh return complex numbers?

Whenever an element has magnitude strictly greater than 1, including ±Inf, MATLAB defines the result as complex with an imaginary component of ±π/2. RunMat mirrors that behaviour exactly.

How are the endpoints ±1 handled?

atanh(1) returns positive infinity and atanh(-1) returns negative infinity, matching MATLAB. These values still count as real outputs, so the GPU path can handle them without falling back.

What happens with NaN inputs?

NaNs propagate through the computation. If the GPU provider supports unary_atanh, the operation can remain on the device; otherwise the runtime falls back to the host and returns the same NaN results.

Does the GPU path differ in precision from the CPU path?

Both paths evaluate the inverse hyperbolic tangent in the provider's precision (f32 or f64). Small rounding differences may occur but stay within MATLAB's tolerance requirements.

Can complex inputs stay on the GPU?

Not yet. GPU tensor handles represent real buffers. When complex outputs are required (either because the input is complex or a real value exceeds the domain), RunMat promotes the result to Value::Complex/Value::ComplexTensor on the host so the semantics match MATLAB.

Will atanh participate in fusion and autodiff?

Yes. The builtin registers element-wise fusion metadata so the planner can inline it into fused WGSL kernels, and the same metadata feeds future autodiff tooling.

Are logical and integer inputs supported?

Yes. They are promoted to doubles before evaluation. Outputs follow MATLAB's double or complex-double conventions depending on the values.

What if my provider does not implement unary_atanh?

RunMat automatically gathers the data, evaluates atanh on the CPU, and returns correct results. Consider enabling the in-process provider for development or the WGPU provider for production to keep the operation on the GPU.

See Also

tanh, asinh, acosh, atan, gpuArray, gather

Source & Feedback