RunMat
GitHub

mod — Compute modulus values with MATLAB semantics in RunMat.

C = mod(A, B) computes remainders using the MATLAB definition A - B .* floor(A./B). Sign conventions, broadcasting, and complex-value behavior follow MATLAB semantics.

Syntax

R = mod(A, B)

Inputs

NameTypeRequiredDefaultDescription
AAnyYesDividend input (numeric/logical/char/complex).
BAnyYesDivisor input (numeric/logical/char/complex).

Returns

NameTypeDescription
RNumericArrayElement-wise modulus result.

Errors

IdentifierWhenMessage
RunMat:mod:InvalidInputInputs cannot be interpreted as numeric, logical, char, or complex operands.mod: invalid input
RunMat:mod:SizeMismatchOperands are not broadcast-compatible.mod: array sizes are not compatible for broadcasting
RunMat:mod:InternalInternal tensor conversion, allocation, or provider composition failed.mod: internal error

How mod works

  • Works with MATLAB-style implicit expansion (broadcasting) between A and B.
  • Returns NaN for elements where B is zero or both arguments are non-finite in incompatible ways (Inf modulo finite, NaN inputs, etc.).
  • Logical and integer inputs are promoted to double precision; character arrays operate on their Unicode code points.
  • Complex inputs use the MATLAB definition mod(a, b) = a - b.*floor(a./b) with complex division and component-wise floor.
  • Empty arrays propagate emptiness while retaining their shapes.

Does RunMat run mod on the GPU?

When both operands are GPU tensors with the same shape, RunMat composes mod from the provider hooks elem_div, unary_floor, elem_mul, and elem_sub. This keeps the computation on the device when those hooks are implemented (the shipped WGPU backend and in-process provider expose them). For mixed residency, shape-mismatched operands, or providers that lack any of these hooks, RunMat gathers to the host, applies the CPU implementation, and returns a host-resident result.

GPU memory and residency

Usually not. When the provider exposes the elementwise hooks noted above, mod executes entirely on the GPU. Otherwise RunMat gathers transparently, ensuring MATLAB-compatible behaviour without manual intervention. Explicit gpuArray / gather calls remain available for scripts that mirror MathWorks MATLAB workflows.

Examples

Computing the modulus of positive integers

r = mod(17, 5)

Expected output:

r = 2

Modulus with negative divisors keeps the divisor's sign

values = [-7 -3 4 9];
mods   = mod(values, -4)

Expected output:

mods = [-3 -3 0 -3]

Broadcasting a scalar divisor across a matrix

A = [4.5  7.1; -2.3  0.4];
result = mod(A, 2)

Expected output:

result =
    [0.5  1.1;
     1.7  0.4]

MATLAB-compatible modulus for complex numbers

z = [3 + 4i, -2 + 5i];
div = 2 + 1i;
res = mod(z, div)

Expected output:

res =
    [0.0 + 0.0i, 0.0 + 1.0i]

Handling zeros in the divisor

warn = mod([2, 0, -2], [0, 0, 0])

Expected output:

warn = [NaN NaN NaN]

Using mod with character arrays

letters = mod('ABC', 5)

Expected output:

letters = [0 1 2]

Staying on the GPU when hooks are available

G = gpuArray(-5:5);
H = mod(G, 4);
cpuCopy = gather(H)

Expected output:

cpuCopy = [3 0 1 2 3 0 1 2 3 0 1]

Using mod with coding agents

Open a RunMat example with live inputs, then ask the agent to explain how mod changes the result.

Run a small mod example, explain the result, then change one input and compare the output.

FAQ

How is mod different from rem?

mod uses floor and keeps the sign of the divisor. rem uses fix and keeps the sign of the dividend.

What happens when the divisor is zero?

The result is NaN (or NaN + NaNi for complex inputs), matching MATLAB semantics.

Does mod support complex numbers?

Yes. Both operands can be complex; the runtime applies MATLAB's definition with complex division and component-wise floor.

Do GPU sources need identical shapes?

Yes. The device fast path currently requires both operands to share the same shape. Other cases fall back to the CPU implementation automatically.

Are empty arrays preserved?

Yes. Empty inputs return empty outputs with the same shape.

Will mod ever change integer classes?

Inputs promote to double precision internally; results are reported as double scalars or tensors, mirroring MATLAB's default numeric type.

Rounding

ceil · fix · floor · rem · round

Elementwise

abs · angle · complex · conj · double · exp · expm1 · factorial · gamma · hypot · imag · ldivide · log · log10 · log1p · 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

Signal

blackman · butter · conv · conv2 · deconv · filter · hamming · hann · sawtooth · sinc · square

Factor

chol · eig · lu · qr · svd

Solve

cond · det · inv · linsolve · norm · pinv · rank · rcond · rref

Fft

fft · fft2 · fftshift · ifft · ifft2 · ifftshift

Interpolation

interp1 · interp2 · pchip · ppval · spline

Ode

ode15s · ode23 · ode45

Open-source implementation

Unlike proprietary runtimes, every RunMat function is open-source. Read exactly how mod is executed, line by line, in Rust.

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.

Getting started · Benchmarks · Pricing

Download RunMat

Download RunMat for full performance, or use RunMat in your browser for zero setup.