View all functions

CategoryMath: Rounding
GPUYes

What does the mod function do in MATLAB / RunMat?

C = mod(A, B) returns the modulus after division such that C has the same sign as B and satisfies A = B.*Q + C with Q = floor(A./B). The definition holds for scalars, vectors, matrices, higher-dimensional tensors, and complex numbers.

How does the mod function behave in MATLAB / RunMat?

  • 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.

mod Function GPU Execution Behaviour

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.

Examples of using the mod function in MATLAB / RunMat

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];

GPU residency in RunMat (Do I need gpuArray?)

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.

FAQ

  1. 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.
  2. What happens when the divisor is zero? The result is NaN (or NaN + NaNi for complex inputs), matching MATLAB semantics.
  3. Does mod support complex numbers? Yes. Both operands can be complex; the runtime applies MATLAB's definition with complex division and component-wise floor.
  4. 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.
  5. Are empty arrays preserved? Yes. Empty inputs return empty outputs with the same shape.
  6. 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.

See Also

rem, floor, fix, gpuArray, gather

Source & Feedback