log1p — Accurate element-wise computation of log(1 + x) for scalars, vectors, matrices, or N-D tensors.
Y = log1p(X) evaluates log(1 + X) element-wise with high accuracy for values of X close to zero. It mirrors MATLAB semantics across scalars, vectors, matrices, logical arrays, character arrays, and complex inputs.
Syntax
Y = log1p(X)Xis a numeric array of any shape — scalars, vectors, matrices, or N-D tensors. Real and complex inputs are both supported; logical and character inputs are promoted to double before evaluation.Yhas the same shape asXand equalslog(1 + X)computed element-wise with high accuracy for small|X|. ForX = -1the result is-Inf; for realX < -1the output promotes to complex (principal branch).- Use
log1pinstead oflog(1 + x)wheneverxcan be close to zero. Forming1 + xin double precision drops bits ofx(catastrophic cancellation), solog(1 + 1e-15)is wrong by nearly 10%, whilelog1p(1e-15)is correct to the last bit.
How log1p works
- Logical inputs are promoted to double precision (
true -> 1.0,false -> 0.0) before execution. - Character arrays are interpreted as their numeric code points and return dense double tensors.
- Values equal to
-1yield-Inf, matching MATLAB's handling oflog(0). - Inputs smaller than
-1promote to complex outputs:log1p(-2)returns0 + iπ. - Complex inputs follow MATLAB's definition by computing the natural logarithm of
1 + z. - Existing GPU tensors remain on the device when the registered provider implements
unary_log1palongsidereduce_min. RunMat queries the device-side minimum to confirm the data stays within the real-valued domain; otherwise it gathers to the host, computes the exact result, and preserves residency metadata.
How RunMat runs log1p on the GPU
RunMat Accelerate keeps tensors resident on the GPU whenever the provider exposes the unary_log1p hook together with reduce_min. The runtime uses the device-side minimum to ensure that 1 + X stays non-negative; when complex outputs are required or either hook is missing, RunMat automatically gathers the tensor, computes on the CPU using double precision, and returns the result with the expected MATLAB semantics.
GPU memory and residency
G = gpuArray(linspace(-0.5, 0.5, 5));
out = log1p(G);
realResult = gather(out);Expected output:
realResult = [-0.6931 -0.2877 0 0.2231 0.4055];Examples
Protecting precision when adding tiny percentages
delta = 1e-12;
value = log1p(delta)Expected output:
value = 9.999999999995e-13Computing log-growth factors from percentage changes
rates = [-0.25 -0.10 0 0.10 0.25];
growth = log1p(rates)Expected output:
growth = [-0.2877 -0.1054 0 0.0953 0.2231]Handling the branch cut at x = -1
y = log1p(-1)Expected output:
y = -InfObtaining complex results for inputs less than -1
data = [-2 -3 -5];
result = log1p(data)Expected output:
result = [0.0000 + 3.1416i, 0.6931 + 3.1416i, 1.3863 + 3.1416i]Executing log1p on GPU arrays with automatic residency
G = gpuArray(linspace(-0.5, 0.5, 5));
out = log1p(G);
realResult = gather(out)Expected output:
realResult = [-0.6931 -0.2877 0 0.2231 0.4055]FAQ
When should I prefer log1p over log(1 + x)?⌄
Use log1p whenever x can be very close to zero. It avoids catastrophic cancellation and matches MATLAB's high-accuracy results for tiny magnitudes.
Does log1p change my tensor's shape?⌄
No. The output has the same shape as the input, subject to MATLAB broadcasting semantics.
How are logical arrays handled?⌄
Logical values convert to doubles before applying log1p, so log1p([true false]) yields a double array [log(2), 0].
What about inputs smaller than -1?⌄
Values less than -1 promote to complex results (log(1 + x) on the complex branch), matching MATLAB's behavior.
How does log1p interact with complex numbers?⌄
Complex scalars and tensors compute log(1 + z) using the principal branch, returning both real and imaginary parts just like MATLAB.
What happens when the GPU provider lacks unary_log1p?⌄
RunMat gathers the tensor to the host, computes the result in double precision, and returns it. This ensures users always see MATLAB-compatible behavior without manual residency management.
Is double precision guaranteed?⌄
Yes. RunMat stores dense numeric tensors in double precision (f64). GPU providers may choose single precision internally but convert back to double when returning data to the runtime.
Can log1p participate in fusion?⌄
Yes. The fusion planner recognizes log1p as an element-wise op. Providers that support fused kernels can materialize log(1 + x) directly in generated WGSL.
What's the inverse of log1p?⌄
— Use expm1(y), which computes exp(y) - 1 accurately for small y. Together log1p and expm1 are the numerically-stable pair for working with quantities near zero: expm1(log1p(x)) == x up to floating-point rounding.
What are typical applications of log1p?⌄
— Anywhere you evaluate log(1 + x) for small x: compounding tiny financial returns (log1p(r) ≈ r but exact), log-probabilities that bump away from 1, physics corrections where x is a perturbation, entropy and softplus gradients, and computing log(1 - p) as log1p(-p) for p near zero.
How much more accurate is log1p(x) than log(1 + x) for tiny x?⌄
— For x = 1e-15, log(1 + x) returns roughly 1.11e-16 (pure rounding noise from forming 1 + x), while log1p(x) returns 1e-15 correctly. The relative error of log(1 + x) grows without bound as x -> 0; log1p stays accurate to the last bit.
Related Math functions
Elementwise
abs · angle · complex · conj · double · exp · expm1 · factorial · gamma · hypot · imag · ldivide · log · log10 · log2 · minus · nextpow2 · plus · pow2 · power · rdivide · real · sign · single · sqrt · times
Trigonometry
acos · acosh · asin · asinh · atan · atan2 · atanh · cos · cosd · cosh · deg2rad · rad2deg · sin · sind · sinh · tan · tand · tanh
Reduction
all · any · cummax · cummin · cumprod · cumsum · cumtrapz · diff · gradient · max · mean · median · min · nnz · prod · std · sum · trapz · var
Structure
Open-source implementation
Unlike proprietary runtimes, every RunMat function is open-source. Read exactly how log1p works, line by line, in Rust.
- View log1p.rs on GitHub
- Learn how the 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 — faster, on any GPU, with no license required.
- Simulations that took hours now take minutes. RunMat automatically optimizes your math for GPU execution on Apple, Nvidia, and AMD hardware. No code changes needed.
- Start running code in seconds. Open the browser sandbox or download a single binary. No license server, no IT ticket, no setup.
- A full development environment. GPU-accelerated 2D and 3D plotting, automatic versioning on every save, and a browser IDE you can share with a link.