conv2 — Compute two-dimensional convolution in MATLAB and RunMat.
conv2 performs two-dimensional linear convolution. The default returns full convolution size, while 'same' and 'valid' modes select alternate regions; these shape rules match MATLAB and RunMat, including separable conv2(hcol, hrow, A) form.
Syntax
C = conv2(A, B)
C = conv2(A, B, shape)
C = conv2(hcol, hrow, A)
C = conv2(hcol, hrow, A, shape)Inputs
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
A | Any | Yes | — | First matrix input. |
B | Any | Yes | — | Second matrix input. |
shape | StringScalar | No | "full" | Output shape: "full", "same", or "valid". |
hcol | Any | Yes | — | Column vector kernel component. |
hrow | Any | Yes | — | Row vector kernel component. |
A | Any | Yes | — | Input matrix. |
Returns
| Name | Type | Description |
|---|---|---|
C | NumericArray | 2-D convolution result. |
Errors
| Identifier | When | Message |
|---|---|---|
RunMat:conv2:ArgCount | More than four input arguments are provided. | conv2: expected at most four input arguments |
RunMat:conv2:ShapeInvalid | Shape argument is not one of full/same/valid. | conv2: shape argument must be the string 'full', 'same', or 'valid' |
RunMat:conv2:InvalidInput | An operand is not numeric/logical scalar/vector/matrix compatible. | conv2: unsupported input type |
RunMat:conv2:VectorRequired | Separable hcol/hrow inputs are not vectors. | conv2: vector input required |
RunMat:conv2:MatrixRequired | Input matrix has non-singleton dimensions beyond 2-D. | conv2: input must be 2-D |
RunMat:conv2:Conversion | Input conversion from logical/gpu tensor into host matrix domain fails. | conv2: input conversion failed |
RunMat:conv2:GatherFailed | GPU input cannot be gathered for host fallback normalization. | conv2: failed to gather GPU input |
RunMat:conv2:BuildOutput | Output tensor allocation fails. | conv2: failed to build tensor |
RunMat:conv2:BuildComplexOutput | Output complex tensor allocation fails. | conv2: failed to build complex tensor |
How conv2 works
conv2(A, B)returns the full 2-D convolution ofAandB.conv2(A, B, 'same')slices the central part of the full convolution so the output matches the shape ofA.- For even-sized kernels with
'same', alignment follows MATLAB's top-left convention in each even dimension. conv2(A, B, 'valid')returns only those points whereBoverlapsAcompletely.conv2(hcol, hrow, A)is syntactic sugar forconv2(hcol(:) * hrow(:)', A).- Scalars are treated as
1×1matrices and preserve the orientation of the other input. - Empty inputs follow MATLAB’s rules:
conv2([], X)andconv2(X, [])return empty matrices (or zero-sized slices for'same'). - Logical inputs are promoted to double precision before computation; complex inputs preserve their imaginary part throughout the convolution.
Does RunMat run conv2 on the GPU?
RunMat Accelerate keeps tensors on the GPU when the active provider implements a conv2d hook (the in-process provider uses the host implementation and returns a GPU handle; the WGPU backend will adopt a native kernel). When the hook is unavailable, RunMat gathers GPU inputs to the host, performs the convolution on the CPU, and returns a host tensor. Documentation and the GPU metadata make this fallback explicit so providers can add native implementations without changing this builtin.
Examples
Smoothing an image patch with a 3×3 averaging kernel
A = [1 2 3; 4 5 6; 7 8 9];
h = ones(3) / 9;
smoothed = conv2(A, h, 'same')Expected output:
smoothed =
1.3333 2.3333 1.7778
3.0000 5.0000 3.6667
2.6667 4.3333 3.1111Computing the full convolution of two small kernels
K1 = [1 2; 3 4];
K2 = [1 1; 1 1];
C = conv2(K1, K2)Expected output:
C =
1 3 2
4 10 6
3 7 4Extracting the same-sized result to preserve dimensions
edge = conv2([1 2 3; 4 5 6; 7 8 9], [1 0 -1; 1 0 -1; 1 0 -1], 'same')Expected output:
edge =
-7 -4 7
-15 -6 15
-13 -4 13Valid convolution for sliding-window statistics
block = magic(4);
kernel = ones(2);
valid = conv2(block, kernel, 'valid')Expected output:
valid =
34 26 34
32 34 36
34 42 34Using the separable form with column and row vectors
hcol = [1; 2; 1];
hrow = [1 0 -1];
A = [3 4 5; 6 7 8; 9 10 11];
gx = conv2(hcol, hrow, A, 'same')Expected output:
gx =
27 -6 -27
28 -8 -28
15 -6 -15Convolving gpuArray inputs with transparent fallbacks
G = gpuArray(rand(128, 128));
H = gpuArray([1 2 1; 0 0 0; -1 -2 -1]);
gx = conv2(G, H, 'same');
result = gather(gx)How RunMat validates conv2
conv2 uses an in-repo implementation for both the direct (conv2(A, B)) and separable (conv2(u, v, A)) forms. The module-level tests cover 'full', 'same', and 'valid' shapes against reference outputs. The GPU path currently defers to the CPU implementation via the in-process provider and returns a GPU handle; a native WGPU conv2d kernel is tracked as follow-up.
- Implementation: crates/runmat-runtime/src/builtins/math/signal/conv2.rs
- Parity test: conv2 unit tests
- Tolerance: 1e-9 (f64), 1e-3 (f32)
See Correctness & Trust for the full methodology and coverage table.
Using conv2 with coding agents
Open a RunMat example with live inputs, then ask the agent to explain how conv2 changes the result.
Run a small conv2 example, explain the result, then change one input and compare the output.
FAQ
Does conv2 support the three MATLAB shape modes?⌄
Yes. Pass 'full', 'same', or 'valid' as the final argument and RunMat will mirror MATLAB’s output sizes and edge handling precisely.
How do I use the separable form?⌄
Call conv2(hcol, hrow, A) (optionally with a shape argument). RunMat converts the vectors into an outer-product kernel internally so it behaves exactly like MATLAB.
What happens if one input is empty?⌄
An empty input produces an empty output (or a zero-sized slice for 'same'). This follows MATLAB’s behaviour and avoids surprising dimension growth.
Do logical inputs work?⌄
Yes. Logical arrays are promoted to double precision before convolution so the result is numeric.
Will the result stay on the GPU?⌄
If the active provider exposes the conv2d hook the result stays device-resident. Otherwise RunMat falls back to the CPU path and returns a host tensor; this fallback is documented so providers can add native kernels without breaking compatibility.
What does conv2 actually compute?⌄
— Two-dimensional convolution. For every output pixel, conv2 flips the kernel B across both axes and sums the element-wise product of B with the corresponding neighbourhood of A. If you want correlation (no flip), use filter2 instead.
When is the separable form conv2(u, v, A) faster than conv2(A, B)?⌄
— Whenever the kernel is rank-1, i.e. B = u * v' for a column vector u and a row vector v. The separable form runs a 1-D column pass followed by a 1-D row pass, costing roughly O(n*(m+k)) operations instead of O(n*m*k) for the full 2-D kernel — a dramatic win for Gaussians, box filters, and Sobel components.
Should I use conv2, filter2, or imfilter?⌄
— Use conv2 for true convolution (the kernel is flipped); use filter2 for correlation with the same kernel (no flip); use imfilter when you need the Image Processing Toolbox's extended boundary handling ('replicate', 'symmetric', 'circular'). All three produce the same result when the kernel is symmetric.
Related Math functions
Signal
blackman · butter · buttord · conv · deconv · downsample · envelope · filter · filtfilt · fir1 · freqz · gauspuls · hamming · hann · hilbert · periodogram · pulstran · pwelch · rectpuls · sawtooth · sinc · spectrogram · square · tripuls · unwrap · upsample · zplane
Elementwise
abs · angle · complex · conj · double · exp · expm1 · factorial · gamma · heaviside · 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
Structure
Open-source implementation
Unlike proprietary runtimes, every RunMat function is open-source. Read exactly how conv2 is executed, line by line, in Rust.
- View the source for conv2 in Rust on GitHub
- Learn how the RunMat runtime works
- Found a bug? Open an issue with a minimal reproduction.
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.