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
AandB. - Returns
NaNfor elements whereBis zero or both arguments are non-finite in incompatible ways (Infmodulo finite,NaNinputs, 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-wisefloor. - 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
- How is
moddifferent fromrem?modusesfloorand keeps the sign of the divisor.remusesfixand keeps the sign of the dividend. - What happens when the divisor is zero? The result is
NaN(orNaN + NaNifor complex inputs), matching MATLAB semantics. - Does
modsupport complex numbers? Yes. Both operands can be complex; the runtime applies MATLAB's definition with complex division and component-wisefloor. - 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
modever 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
- Source:
crates/runmat-runtime/src/builtins/math/rounding/mod.rs - Found a bug or behavioural difference? Open an issue with a minimal repro.