What does the mat2cell function do in MATLAB / RunMat?
mat2cell partitions an array along each dimension according to vectors of block sizes and returns
those blocks inside a cell array. The result preserves the element type of the input, and each cell
contains a contiguous slice of the original data.
How does the mat2cell function behave in MATLAB / RunMat?
- Supply one size vector per dimension you want to split. Their elements must be non-negative integers that sum to the corresponding dimension of the input array.
- If you omit trailing size vectors, RunMat assumes the remaining dimensions stay intact
(
size(A, dim)). - Zero-sized blocks are allowed and produce empty matrices (or empty arrays of the input type).
- N-dimensional inputs are supported; the output cell array has one dimension per supplied size vector.
- Inputs can be numeric, complex, logical, string, or character arrays. Struct, object, and cell arrays are not yet supported.
mat2cell Function GPU Execution Behaviour
When the input is a gpuArray, RunMat gathers it back to the host before performing the partition,
and the resulting cells contain host tensors. This matches MATLAB semantics except for the
residency—providers do not yet offer on-device block-splitting hooks. Once such hooks become
available, RunMat can keep results on the GPU with no user code changes.
Examples of using the mat2cell function in MATLAB / RunMat
Splitting a matrix into four quadrants
A = reshape(1:16, 4, 4);
C = mat2cell(A, [2 2], [1 3]);
Expected output:
size(C) % => [2 2]
double(C{2,2}) % => [7 11 15; 8 12 16]
Splitting a column vector with only row sizes
v = (1:6)';
blocks = mat2cell(v, [2 1 3]);
Expected output:
cellfun(@numel, blocks) % => [2; 1; 3]
blocks{3} % => [4; 5; 6]
Partitioning a 3-D tensor
T = reshape(1:24, [3 4 2]);
C = mat2cell(T, [1 2], [2 2], [1 1]);
Expected output:
size(C) % => [2 2 2]
double(C{2,1,2}(:,:,1)) % => [14 17; 15 18]
Using zero-sized blocks
E = zeros(3, 2);
C = mat2cell(E, [0 3], [1 1]);
cellfun(@size, C, 'UniformOutput', false)
Expected output:
ans{1,1} = [0 1]
ans{1,2} = [0 1]
ans{2,1} = [3 1]
ans{2,2} = [3 1]
Splitting a character matrix into rows
names = ['foo '; 'bar '; 'baz '];
C = mat2cell(names, [1 2], size(names, 2));
Expected output:
C{1,1} % => 'foo '
C{2,1} % => ['bar '; 'baz ']
Working with logical arrays
mask = logical([1 0 1; 0 1 0]);
cells = mat2cell(mask, 2, [1 1 1]);
Expected output:
cells{1,2} % => logical column vector [0; 1]
class(cells{1,2}) % => 'logical'
GPU residency in RunMat (Do I need gpuArray?)
The current implementation gathers GPU inputs to the host, produces host cell arrays, and returns
CPU-resident tensors inside each cell. Explicit gpuArray calls are not required; once GPU providers
offer block-splitting hooks, mat2cell will keep results on the device automatically.
FAQ
Do the partition vectors have to sum exactly to the dimension size?
Yes. Each size vector must consist of non-negative integers whose sum matches the corresponding dimension of the input array. RunMat raises an error when the sums differ.
What happens if I omit trailing dimension vectors?
RunMat mirrors MATLAB: omitted trailing vectors are treated as a single block that covers the entire
dimension (size(A, dim)), so many common 2-D use cases only need two vectors.
Are zero-sized blocks allowed?
Yes. A zero entry in a partition vector produces an empty array in the corresponding cell. This is useful when you need placeholders that preserve grid structure.
What element types are supported?
Numeric, complex, logical, string, and character arrays are supported today. Struct arrays, object arrays, and cell arrays will gain support in a future update.
Does mat2cell copy the data?
Yes. Each cell receives its own copy of the underlying block so that you can modify the cell contents without affecting other cells or the original array.
See Also
cell, cell2mat, num2cell, gpuArray, gather
Source & Feedback
- The full source code for the implementation of the
mat2cellfunction is available at:crates/runmat-runtime/src/builtins/cells/core/mat2cell.rs - Found a bug or behavioural difference? Please open an issue with details and a minimal repro.