{
"title": "mat2cell",
"category": "cells/core",
"keywords": [
"mat2cell",
"cell array",
"partition",
"submatrix",
"block slicing",
"gpu fallback"
],
"summary": "Split arrays into cell-array blocks using MATLAB-compatible dimension partitions.",
"references": [],
"gpu_support": {
"elementwise": false,
"reduction": false,
"precisions": [],
"broadcasting": "none",
"notes": "The builtin gathers gpuArray inputs back to the host because providers do not yet expose block-splitting hooks."
},
"fusion": {
"elementwise": false,
"reduction": false,
"max_inputs": 0,
"constants": "inline"
},
"requires_feature": null,
"tested": {
"unit": "builtins::cells::core::mat2cell::tests",
"integration": "builtins::cells::core::mat2cell::tests::mat2cell_gpu_falls_back_to_host"
},
"description": "`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.",
"behaviors": [
"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."
],
"examples": [
{
"description": "Splitting a matrix into four quadrants",
"input": "A = reshape(1:16, 4, 4);\nC = mat2cell(A, [2 2], [1 3])",
"output": "size(C) % => [2 2]\ndouble(C{2,2}) % => [7 11 15; 8 12 16]"
},
{
"description": "Splitting a column vector with only row sizes",
"input": "v = (1:6)';\nblocks = mat2cell(v, [2 1 3])",
"output": "cellfun(@numel, blocks) % => [2; 1; 3]\nblocks{3} % => [4; 5; 6]"
},
{
"description": "Partitioning a 3-D tensor",
"input": "T = reshape(1:24, [3 4 2]);\nC = mat2cell(T, [1 2], [2 2], [1 1])",
"output": "size(C) % => [2 2 2]\ndouble(C{2,1,2}(:,:,1)) % => [14 17; 15 18]"
},
{
"description": "Using zero-sized blocks",
"input": "E = zeros(3, 2);\nC = mat2cell(E, [0 3], [1 1]);\ncellfun(@size, C, 'UniformOutput', false)",
"output": "ans{1,1} = [0 1]\nans{1,2} = [0 1]\nans{2,1} = [3 1]\nans{2,2} = [3 1]"
},
{
"description": "Splitting a character matrix into rows",
"input": "names = ['foo '; 'bar '; 'baz '];\nC = mat2cell(names, [1 2], size(names, 2))",
"output": "C{1,1} % => 'foo '\nC{2,1} % => ['bar '; 'baz ']"
},
{
"description": "Working with logical arrays",
"input": "mask = logical([1 0 1; 0 1 0]);\ncells = mat2cell(mask, 2, [1 1 1])",
"output": "cells{1,2} % => logical column vector [0; 1]\nclass(cells{1,2}) % => 'logical'"
}
],
"faqs": [
{
"question": "Do the partition vectors have to sum exactly to the dimension size?",
"answer": "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."
},
{
"question": "What happens if I omit trailing dimension vectors?",
"answer": "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."
},
{
"question": "Are zero-sized blocks allowed?",
"answer": "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."
},
{
"question": "What element types are supported?",
"answer": "Numeric, complex, logical, string, and character arrays are supported today. Struct arrays, object arrays, and cell arrays will gain support in a future update."
},
{
"question": "Does `mat2cell` copy the data?",
"answer": "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."
},
{
"question": "What does mat2cell do in MATLAB?",
"answer": "`mat2cell(X, rowSizes, colSizes)` divides matrix `X` into a cell array of sub-matrices. The partition vectors specify the row and column sizes of each block, and must sum to the dimension sizes of `X`."
},
{
"question": "How is mat2cell different from num2cell?",
"answer": "`num2cell` splits a matrix into individual scalar cells (one element per cell), while `mat2cell` splits into sub-matrices of specified sizes. Use `mat2cell` when you need contiguous blocks."
},
{
"question": "Can I use mat2cell on 3-D arrays?",
"answer": "Yes. Provide partition vectors for each dimension: `mat2cell(X, rowSizes, colSizes, pageSizes)`. Omitted trailing dimensions are treated as a single partition equal to the full size."
},
{
"question": "How do I convert a cell array back to a matrix?",
"answer": "Use `cell2mat(C)` to concatenate the cells back into a single matrix. Each cell must contain a numeric array, and the sizes must be consistent along concatenation dimensions."
}
],
"links": [
{
"label": "cell",
"url": "./cell"
},
{
"label": "cell2mat",
"url": "./cell2mat"
},
{
"label": "gpuArray",
"url": "./gpuarray"
},
{
"label": "gather",
"url": "./gather"
},
{
"label": "cellfun",
"url": "./cellfun"
},
{
"label": "cellstr",
"url": "./cellstr"
}
],
"source": {
"label": "`crates/runmat-runtime/src/builtins/cells/core/mat2cell.rs`",
"url": "https://github.com/runmat-org/runmat/blob/main/crates/runmat-runtime/src/builtins/cells/core/mat2cell.rs"
},
"gpu_residency": "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.",
"gpu_behavior": [
"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."
]
}