RunMat
GitHub

diff — Forward finite differences of scalars, vectors, matrices, or N-D tensors.

diff(X) computes forward finite differences along the first dimension of X whose size exceeds 1. For vectors, this is simply the difference between adjacent elements. Higher-order differences are obtained by repeating this process.

How diff works in RunMat

  • diff(X) walks along the first non-singleton dimension. Column vectors therefore differentiate down the rows, while row vectors operate across columns.
  • diff(X, N) computes the Nth forward difference. N = 0 returns X unchanged. Each order reduces the length of the working dimension by one, so the output length becomes max(len - N, 0).
  • diff(X, N, dim) lets you choose the dimension explicitly. Passing [] for N or dim keeps the defaults, and dimensions larger than ndims(X) behave like length-1 axes (so any positive order yields an empty result).
  • Real, logical, and character inputs promote to double precision tensors before differencing. Complex inputs retain their complex type, with forward differences applied to both the real and imaginary parts independently.
  • Empty slices propagate: if the selected dimension has length 0 or 1, the corresponding axis in the output has length 0.

How diff runs on the GPU

When the operand already resides on the GPU, RunMat asks the active acceleration provider for a finite-difference kernel via diff_dim. The WGPU backend implements this hook, so forward differences execute entirely on the device and the result stays resident on the GPU. Providers that have not wired diff_dim yet transparently gather the data, run the CPU implementation, and hand the result back to the planner so subsequent kernels can re-promote it when beneficial.

GPU memory and residency

Manual gpuArray promotion is optional. RunMat keeps tensors on the GPU when providers implement the relevant hooks and the planner predicts a benefit. With the WGPU backend registered, diff executes fully on the GPU and returns a device-resident tensor. When the hook is missing, RunMat gathers transparently, computes on the CPU, and keeps residency metadata consistent so fused expressions can re-promote values when profitable.

Examples

Computing first differences of a vector

v = [3 4 9 15];
d1 = diff(v)

Expected output:

d1 = [1 5 6]

Taking second-order differences

v = [1 4 9 16 25];
d2 = diff(v, 2)

Expected output:

d2 = [2 2 2]

Selecting the working dimension explicitly

A = [1 2 3; 4 5 6];
rowDiff = diff(A, 1, 2)

Expected output:

rowDiff =
     1     1
     1     1

Running diff on GPU arrays

G = gpuArray([1 4 9 16]);
gDiff = diff(G);
result = gather(gDiff)

Expected output:

result = [3 5 7]

N exceeding the dimension length returns an empty array

v = (1:3)';
emptyResult = diff(v, 5)

Expected output:

emptyResult =
  0×1 empty double column vector

Applying diff to character data

codes = diff('ACEG')

Expected output:

codes = [2 2 2]

FAQ

Does diff change the size of the input?

diff reduces the length along the working dimension by N. All other dimensions are preserved. If the working dimension is shorter than N, the result is empty. With the WGPU backend the empty result remains GPU-resident.

How are higher-order differences computed?

RunMat applies the first-order forward difference repeatedly. This mirrors MATLAB’s definition and produces the same numerical results.

Can I pass [] for the order or dimension arguments?

Yes. An empty array keeps the default value (N = 1, first non-singleton dimension).

Does diff support complex numbers?

Yes. Differences are taken on the real and imaginary parts independently, and the result remains complex unless it becomes empty.

What happens for character or logical inputs?

Characters and logical values are promoted to double precision differences, matching MATLAB.

Will the GPU path produce the same results as the CPU path?

Yes. When a provider lacks a finite-difference kernel, RunMat gathers the data and computes on the CPU to preserve MATLAB semantics exactly. Otherwise, the WGPU backend produces identical results on the GPU.

What does diff do in MATLAB?

diff(X) computes differences between adjacent elements. For a vector, it returns X(2:end) - X(1:end-1), producing an output one element shorter than the input.

How do I compute second differences with diff?

Use diff(X, 2) to compute the second-order difference, equivalent to diff(diff(X)). The output is two elements shorter than the input.

How do I compute differences along columns vs rows?

Use diff(X, 1, 1) for differences along columns (default for matrices) and diff(X, 1, 2) for differences along rows. The third argument specifies the dimension.

Can I use diff to compute numerical derivatives?

Yes. For evenly spaced data with step h, the numerical derivative is approximately diff(y) / h. For non-uniform spacing, use diff(y) ./ diff(x).

Does diff support GPU acceleration in RunMat?

Yes. diff runs on GPU arrays in RunMat. The GPU path produces the same results as the CPU path for both real and complex inputs.

These functions work well alongside diff. Each page has runnable examples you can try in the browser.

cumsum, sum, cumprod, gpuArray, gather, all, any, cummax, cummin, max, mean, median, min, nnz, prod, std, var

Open-source implementation

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

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.

Getting started · Benchmarks · Pricing

Try RunMat — free, no sign-up

Start running MATLAB code immediately in your browser.