atanh — Element-wise inverse hyperbolic tangent in MATLAB and RunMat, with complex promotion for |x| > 1.
Y = atanh(X) evaluates the inverse hyperbolic tangent of each element in X. Real inputs in (-1, 1) remain real, while values with |x| > 1 promote to complex outputs, consistent with MATLAB and RunMat principal-branch behavior.
Syntax
Y = atanh(X)Inputs
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
X | Any | Yes | — | Single/double real or complex input; integer, logical, and character forms are RunMat-only extensions. |
Returns
| Name | Type | Description |
|---|---|---|
Y | Any | Element-wise inverse hyperbolic tangent result. |
Errors
| Identifier | When | Message |
|---|---|---|
RunMat:atanh:InvalidInput | Input cannot be interpreted as supported numeric/char/complex data. | atanh: invalid input |
RunMat:atanh:Internal | Internal gather/reduction/conversion/allocation/provider flow failed. | atanh: internal error |
RunMat:atanh:TooManyOutputs | More than one output is requested. | atanh: too many output arguments |
How atanh works
- Accepts scalars, vectors, matrices, and N-D tensors using MATLAB broadcasting semantics.
- The documented table and timetable overloads are not yet implemented in RunMat.
- Documented single inputs preserve native single or complex-single storage; double inputs preserve double or complex-double storage.
- Real values with magnitude greater than
1return complex numbers whose imaginary part is±π/2. The runtime automatically promotes the entire tensor toValue::ComplexTensorso 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. - Typed-integer, logical, and character inputs are RunMat-only extensions. They enter an explicit double computation boundary and preserve input shape.
- Empty arrays return empty outputs with matching shape and type.
Does RunMat run atanh on the GPU?
RunMat Accelerate keeps tensors on the GPU when a provider implements unary_atanh and the extremum reductions prove that every element lies in [-1, 1]. Missing floating hooks use an owner-preserving gather fallback. Real resident input that requires complex promotion is rejected in MATLAB-compatible modes and is an explicit RunMat-only extension that restores the complex result to the owning provider.
GPU memory and residency
The auto-offload planner keeps documented floating inputs on the GPU whenever the provider exposes unary_atanh and every element satisfies |x| ≤ 1. Unsupported hooks use owner-preserving fallback. RunMat mode also permits real resident input that requires complex promotion and restores the complex result to the same provider.
Examples
Inverse hyperbolic tangent of a real scalar
y = atanh(0.5)Expected output:
y = 0.5493Applying 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.5493Producing complex outputs for |x| > 1
values = [2 -3];
result = atanh(values)Expected output:
result =
0.5493 + 1.5708i -0.3466 + 1.5708iComputing atanh for complex numbers
Z = [1 + 2i, -0.5 + 0.75i];
W = atanh(Z)Expected output:
W =
0.1733 + 1.1781i -0.3104 + 0.7232iRunning 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]Using atanh with coding agents
Open a RunMat example with live inputs, then ask the agent to explain how atanh changes the result.
Run a small atanh example, explain the result, then change one input and compare the output.
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?⌄
The public GPU contract requires potentially complex results to start from explicitly complex input. RunMat mode additionally supports real resident input that needs complex promotion, gathering and re-uploading the complex result to the same provider.
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?⌄
They are outside the documented single/double data domain. RunMat mode retains logical and all-eight-class integer inputs as explicit extensions and converts them to double at the inverse-hyperbolic-tangent computation boundary.
What if my provider does not implement unary_atanh?⌄
RunMat gathers the data, evaluates atanh on the CPU, and restores the result to the input handle's owning provider.
Related Math functions
Trigonometry
acos · acosh · asin · asinh · atan · atan2 · cos · cosd · cosh · cospi · deg2rad · pol2cart · rad2deg · sin · sind · sinh · sinpi · tan · tand · tanh
Elementwise
abs · angle · bsxfun · complex · conj · double · erf · erfcinv · exp · expm1 · factorial · flintmax · gamma · gammaln · heaviside · hypot · idivide · imag · intmax · intmin · ldivide · log · log10 · log1p · log2 · minus · nextpow2 · plus · pow2 · power · rdivide · real · realmax · realmin · realsqrt · rescale · sign · single · sqrt · swapbytes · times · typecast · uint16 · uint32 · uint8
Reduction
all · any · bounds · cummax · cummin · cumprod · cumsum · cumtrapz · diff · gradient · max · maxk · mean · median · min · mink · movmax · movmean · movmedian · movmin · movprod · movstd · movsum · movvar · nnz · prod · rms · std · sum · trapz · var
Structure
bandwidth · isdiag · ishermitian · issymmetric · istril · istriu · symrcm
Signal
blackman · butter · buttord · cheb2ord · conv · conv2 · deconv · downsample · envelope · filter · filtfilt · fir1 · freqz · gauspuls · hamming · hann · hilbert · periodogram · pulstran · pwelch · rectpuls · resample · sawtooth · sinc · spectrogram · square · tripuls · unwrap · upsample · zplane
Optim
coneprog · fminbnd · fminunc · fsolve · fzero · integral · linprog · lsqcurvefit · lsqnonlin · optimoptions · optimset · quad · secondordercone
Ops
cross · ctranspose · dot · mldivide · mpower · mrdivide · mtimes · pagemtimes · pagetranspose · trace · transpose
Open-source implementation
Unlike proprietary runtimes, every RunMat function is open-source. Read exactly how atanh is executed, line by line, in Rust.
- View the source for atanh in Rust on GitHub
- Learn how the RunMat runtime works
- Found a bug? Open an issue with a minimal reproduction.
About RunMat
RunMat is an open-source runtime that executes MATLAB-syntax code blazing on any GPU. It is licensed under the Apache 2.0 license.
- RunMat automatically optimizes your math for GPU execution on Apple, Nvidia, and AMD hardware. No code changes needed. Simulations that took hours now take minutes.
- Start running code in seconds. RunMat runs in the browser, on the desktop, or from the CLI. No license server, no IT ticket.