RunMat
GitHub

rem — Compute MATLAB remainder values using A - B .* fix(A ./ B) across real or complex arrays.

C = rem(A, B) returns the remainder after division with the quotient rounded toward zero: C = A - B .* fix(A ./ B). Results follow MATLAB sign and edge-case rules across scalar, vector, matrix, and N-D inputs.

Syntax

R = rem(A, B)

Inputs

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

Returns

NameTypeDescription
RNumericArrayElement-wise remainder result.

Errors

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

How rem works

  • Supports scalars, vectors, matrices, and higher-dimensional tensors with MATLAB-style implicit expansion (broadcasting).
  • Returns NaN when the divisor is zero or when the dividend is non-finite while the divisor is finite.
  • Infinite divisors leave finite dividends unchanged (because the quotient is zero).
  • Logical and integer inputs promote to double precision; character arrays operate on their Unicode code points.
  • Complex inputs follow MATLAB semantics: rem(z, w) = z - w .* fix(z ./ w) with fix applied component-wise to the complex quotient.
  • Empty inputs propagate emptiness while preserving shape.

Does RunMat run rem on the GPU?

When both operands are GPU tensors with identical shapes and the active provider exposes elem_div, unary_fix, elem_mul, and elem_sub, RunMat evaluates rem fully on the device by chaining those kernels. Intermediate buffers stay device-side, fusion-aware planners can inline the sequence, and the final remainder handle remains on the GPU for downstream work. If residency is mixed, shapes differ, or any hook is unavailable, RunMat automatically gathers to the host, executes the MATLAB-compatible fallback, and returns a CPU tensor while preserving observable semantics.

GPU memory and residency

Typically no. The native auto-offload planner keeps tensors on the GPU whenever the provider implements the chained kernels described above or when rem participates in a larger fused expression. If any hook is missing—or when inputs start on the host—RunMat gathers automatically, executes the CPU fallback, and returns the result. You can still call gpuArray and gather explicitly for compatibility with MathWorks MATLAB scripts or to control residency manually.

Examples

Remainder of positive integers

r = rem(17, 5)

Expected output:

r = 2

Remainder keeps dividend sign for negatives

values = [-7 -3 4 9];
remainders = rem(values, 4)

Expected output:

remainders = [-3 -3 0 1]

Remainder with a negative divisor

r = rem(7, -4)

Expected output:

r = 3

Applying remainder across arrays with broadcasting

A = [4.5 7.1; -2.3 0.4];
B = rem(A, 2)

Expected output:

B = [0.5 1.1;
     -0.3 0.4]

Complex remainders follow fix-based quotient

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

Expected output:

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

Keeping rem on the GPU when kernels are available

G = gpuArray(-5:5);
H = rem(G, 4);
hostCopy = gather(H)

Expected output:

hostCopy = [-1 0 -3 -2 -1 0 1 2 3 0 1]

Using rem with coding agents

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

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

FAQ

How is rem different from mod?

rem rounds the quotient with fix, so the remainder inherits the dividend's sign. mod rounds with floor, which ties the remainder to the divisor's sign. Both functions share broadcasting rules, but they differ whenever negative values are involved.

What happens when the divisor is zero?

MATLAB defines rem(A, 0) as NaN (and NaN + NaNi for complex operands). RunMat mirrors this behaviour so error handling and edge cases match scripts written for MATLAB.

Does rem support infinite inputs?

Yes. When B is infinite and A is finite, the quotient truncates to zero and the result is exactly A. If the dividend is infinite while the divisor is finite, the remainder is NaN, preserving MATLAB's rules for indeterminate operations.

Can rem operate on complex numbers?

Absolutely. Both operands may be complex; RunMat computes rem(z, w) as z - w .* fix(z ./ w), applying fix to the real and imaginary components independently so the result matches MATLAB's complex arithmetic.

Does rem change integer or logical inputs?

Internally, inputs promote to double precision before the remainder is computed. The result is returned as doubles, aligning with MATLAB's numeric tower while still supporting logical, integer, and character array arguments.

Will rem stay on the GPU?

It stays on-device when the provider implements elem_div, unary_fix, elem_mul, and elem_sub; fusion-aware planners can keep intermediates resident for downstream kernels. Otherwise the runtime gathers the operands, executes the CPU fallback, and returns a host tensor so correctness is unaffected.

What does rem do in MATLAB?

rem(a, b) returns the remainder after dividing a by b. The result has the same sign as the dividend a. For example, rem(7, 3) returns 1 and rem(-7, 3) returns -1.

What is the difference between rem and mod in MATLAB?

Both compute remainders, but rem preserves the sign of the dividend while mod preserves the sign of the divisor. rem(-7, 3) returns -1, but mod(-7, 3) returns 2.

Does rem support GPU arrays in RunMat?

Yes. rem runs on the GPU with elementwise fusion support, allowing it to be combined with other operations for efficient computation.

Rounding

ceil · fix · floor · mod · 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 rem 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.