{
"title": "cell2mat",
"category": "cells/core",
"keywords": [
"cell2mat",
"cell arrays",
"matrix conversion",
"block concatenation",
"gpu fallback"
],
"summary": "Convert the contents of a MATLAB cell array into a dense numeric, logical, complex, or character matrix.",
"references": [],
"gpu_support": {
"elementwise": false,
"reduction": false,
"precisions": [
"f32",
"f64"
],
"broadcasting": "none",
"notes": "cell2mat executes on the host. GPU-resident tensors inside the cell array are gathered before concatenation."
},
"fusion": {
"elementwise": false,
"reduction": false,
"max_inputs": 1,
"constants": "inline"
},
"requires_feature": null,
"tested": {
"unit": "builtins::cells::core::cell2mat::tests",
"integration": "builtins::cells::core::cell2mat::tests::cell2mat_gpu_cells_are_gathered"
},
"description": "`cell2mat(C)` concatenates the numeric, logical, complex, or character arrays stored in the cell array `C` into a single dense MATLAB array. The cell array must form a rectangular block structure: all cells in the same row share the same number of rows, all cells in the same column share the same number of columns, and higher-dimensional extents agree everywhere.",
"behaviors": [
"Works for cell arrays whose elements are **numeric**, **logical**, **complex**, or **character** arrays (including scalars and empties). Mixed types are rejected.",
"RunMat currently represents cell arrays as 2-D grids. The first dimension tiles rows, the second tiles columns, and any higher dimensions inside each element must agree exactly across all cells.",
"Empty cells contribute zero extent in their tiling dimension while preserving type information.",
"The output array uses column-major layout for numeric, logical, and complex data, and matches MATLAB character array semantics for text.",
"Calling `cell2mat` on an empty cell array returns the empty double matrix `0×0`."
],
"examples": [
{
"description": "Converting a 2-by-2 cell array of scalars into a matrix",
"input": "C = {1, 2; 3, 4};\nA = cell2mat(C)",
"output": "A =\n 1 2\n 3 4"
},
{
"description": "Concatenating blocks of different column widths",
"input": "C = {[1 2], [3 4 5]; [6 7], [8 9 10]};\nA = cell2mat(C)",
"output": "A =\n 1 2 3 4 5\n 6 7 8 9 10"
},
{
"description": "Converting logical cell contents into a logical matrix",
"input": "C = {true(2,1), false(2,1)};\nM = cell2mat(C)",
"output": "M =\n 2×2 logical array\n 1 0\n 1 0"
},
{
"description": "Handling complex-valued blocks",
"input": "C = {1+2i, [3+4i 5+6i]};\nZ = cell2mat(C)",
"output": "Z =\n 1.0000 + 2.0000i 3.0000 + 4.0000i 5.0000 + 6.0000i"
},
{
"description": "Producing character matrices from cell arrays of character rows",
"input": "C = {'foo', 'bar'; 'baz', 'qux'};\nS = cell2mat(C)",
"output": "S =\n 'foobar'\n 'bazqux'"
},
{
"description": "Tiling higher-dimensional numeric blocks",
"input": "C = {ones(2,2,3), 2*ones(2,1,3)};\nX = cell2mat(C);\nsize(X)",
"output": "ans =\n 2 3 3"
},
{
"description": "Working with empty cells",
"input": "C = {[], []; [], []};\nA = cell2mat(C);\nsize(A)",
"output": "ans =\n 0 0"
},
{
"description": "Gathering GPU tensors stored inside cells",
"input": "G = gpuArray(ones(4,1));\nC = {G, 2*G};\nH = cell2mat(C); % gathered back to host automatically\nclassUnderlying(H)",
"output": "ans =\n 'double'"
}
],
"faqs": [
{
"question": "What element types does `cell2mat` support?",
"answer": "Numeric doubles (scalars or arrays), complex doubles, logical values, and character arrays. Mixed types are not allowed; every populated cell must have the same fundamental type."
},
{
"question": "Can I convert a cell array that contains structs or strings?",
"answer": "No. `cell2mat` requires array-like contents. Use specialised functions such as `string` or `char` converters for string data, or bespoke logic for structs and tables."
},
{
"question": "Do the cell contents need identical shapes?",
"answer": "Cells in the same row must share the same number of rows. Cells in the same column must share the same number of columns. Any higher dimensions must agree across all cells. Violations produce a descriptive error that mirrors MATLAB's behaviour."
},
{
"question": "What happens with empty cells?",
"answer": "Empty cells contribute zero extent along their tiling dimension. For example, if every element in a row is empty, the resulting matrix has zero rows for that block. Completely empty cell arrays produce the `0×0` empty double matrix."
},
{
"question": "Does `cell2mat` return GPU arrays when inputs are gpuArray elements?",
"answer": "Not yet. RunMat gathers GPU elements to the host before concatenating. Future releases may introduce GPU-resident cell storage, at which point providers can supply dedicated kernels."
}
],
"links": [
{
"label": "cell",
"url": "./cell"
},
{
"label": "mat2cell",
"url": "./mat2cell"
},
{
"label": "cellfun",
"url": "./cellfun"
},
{
"label": "cellstr",
"url": "./cellstr"
}
],
"source": {
"label": "`crates/runmat-runtime/src/builtins/cells/core/cell2mat.rs`",
"url": "https://github.com/runmat-org/runmat/blob/main/crates/runmat-runtime/src/builtins/cells/core/cell2mat.rs"
},
"gpu_residency": "You usually do NOT need to call `gpuArray` before `cell2mat`. The builtin always gathers GPU-resident elements to the host so it can stitch the resulting matrix in CPU memory. Explicitly wrapping each cell in `gpuArray` is harmless, but there is no residency benefit because the final result is a standard CPU array.",
"gpu_behavior": [
"`cell2mat` is inherently a host operation because MATLAB cell arrays live on the CPU heap. If a cell element is a GPU tensor (`gpuArray`) RunMat gathers it to host memory before concatenating. Providers do **not** need to implement bespoke kernels: the builtin terminates GPU fusion groups, materialises the inputs on the host, and returns a host-resident array."
]
}