{
"title": "transpose",
"category": "math/linalg/ops",
"keywords": [
"transpose",
"swap rows and columns",
"non-conjugate transpose",
"gpu"
],
"summary": "Swap the first two dimensions of arrays without taking the complex conjugate.",
"references": [
"https://www.mathworks.com/help/matlab/ref/transpose.html"
],
"gpu_support": {
"elementwise": false,
"reduction": false,
"precisions": [
"f32",
"f64"
],
"broadcasting": "none",
"notes": "Prefers the provider transpose hook; falls back to gather→transpose→upload when unavailable."
},
"fusion": {
"elementwise": false,
"reduction": false,
"max_inputs": 1,
"constants": "inline"
},
"requires_feature": null,
"tested": {
"unit": "builtins::math::linalg::ops::transpose::tests",
"integration": "builtins::math::linalg::ops::transpose::tests::transpose_gpu_roundtrip",
"gpu": "builtins::math::linalg::ops::transpose::tests::transpose_wgpu_matches_cpu"
},
"description": "`B = transpose(A)` flips the first two dimensions of `A` without conjugating complex values. It is equivalent to the MATLAB syntax `A.'` and leaves higher dimensions untouched.",
"behaviors": [
"Works for scalars, vectors, matrices, and N-D arrays; only the first two axes are swapped.",
"Complex values are **not** conjugated. Use `ctranspose`/`A'` for conjugate transpose.",
"Logical, string, character, and cell arrays preserve their types and metadata.",
"Vectors become column or row matrices as needed (e.g., `size(transpose(1:3)) == [3 1]`).",
"Empty and singleton dimensions follow MATLAB's column-major semantics."
],
"examples": [
{
"description": "Transposing a numeric matrix to swap rows and columns",
"input": "A = [1 2 3; 4 5 6];\nB = transpose(A)",
"output": "B =\n 1 4\n 2 5\n 3 6"
},
{
"description": "Turning a row vector into a column vector",
"input": "row = 1:4;\ncol = transpose(row);\nsize(col)",
"output": "ans = [4 1]"
},
{
"description": "Preserving imaginary parts when transposing complex matrices",
"input": "Z = [1+2i 3-4i];\nZT = transpose(Z)",
"output": "ZT =\n 1.0000 + 2.0000i\n 3.0000 - 4.0000i"
},
{
"description": "Transposing logical masks while keeping logical type",
"input": "mask = logical([1 0 1; 0 1 0]);\nmaskT = transpose(mask);\nclass(maskT)",
"output": "ans = 'logical'"
},
{
"description": "Transposing character arrays to flip rows and columns of text",
"input": "C = ['r' 'u' 'n'; 'm' 'a' 't'];\nCT = transpose(C)",
"output": "CT =\n 'rm'\n 'ua'\n 'nt'"
},
{
"description": "Transposing gpuArray data without leaving the device",
"input": "G = gpuArray(rand(1024, 32));\nGT = transpose(G);\nisgpuarray(GT)",
"output": "ans = logical 1"
}
],
"faqs": [
{
"question": "Does `transpose` conjugate complex numbers?",
"answer": "No. Use `ctranspose` or the `'` operator for conjugate transpose."
},
{
"question": "What happens for tensors with more than two dimensions?",
"answer": "Only the first two axes are swapped; higher dimensions remain in-place."
},
{
"question": "Do empty matrices stay empty after transposition?",
"answer": "Yes. MATLAB's empty-dimension rules are preserved exactly."
},
{
"question": "Is the result a copy or a view?",
"answer": "It is a new array. Neither the input nor the output share storage."
},
{
"question": "Can I transpose cell arrays?",
"answer": "Yes—RunMat mirrors MATLAB by rearranging each cell handle into the new layout."
},
{
"question": "Are logical arrays still logical after transpose?",
"answer": "Absolutely. The data stay in compact logical storage."
},
{
"question": "How does `transpose` interact with the fusion planner?",
"answer": "Fusion treats transposes as pipeline boundaries, so kernels before and after the transpose can still fuse independently."
},
{
"question": "What if my provider lacks a transpose kernel?",
"answer": "RunMat transparently gathers, transposes on the host, and re-uploads while logging a warning."
},
{
"question": "Does `transpose` change sparse matrices?",
"answer": "Sparse support is planned; current releases operate on dense arrays."
},
{
"question": "Can I compose `transpose` with `permute`?",
"answer": "Yes—`transpose` is equivalent to `permute(A, [2 1 3 ...])`."
}
],
"links": [
{
"label": "ctranspose",
"url": "./ctranspose"
},
{
"label": "permute",
"url": "./permute"
},
{
"label": "mtimes",
"url": "./mtimes"
},
{
"label": "gpuArray",
"url": "./gpuarray"
},
{
"label": "gather",
"url": "./gather"
},
{
"label": "dot",
"url": "./dot"
},
{
"label": "mldivide",
"url": "./mldivide"
},
{
"label": "mpower",
"url": "./mpower"
},
{
"label": "mrdivide",
"url": "./mrdivide"
},
{
"label": "trace",
"url": "./trace"
}
],
"source": {
"label": "`crates/runmat-runtime/src/builtins/math/linalg/ops/transpose.rs`",
"url": "https://github.com/runmat-org/runmat/blob/main/crates/runmat-runtime/src/builtins/math/linalg/ops/transpose.rs"
},
"gpu_residency": "No additional residency management is required. If the planner keeps your data on the GPU, `transpose` will honour that residency and either invoke a provider kernel or, in the worst case, perform a gather/transpose/upload round-trip automatically.",
"gpu_behavior": [
"When a gpuArray is provided, RunMat first asks the active Accel provider for a dedicated transpose kernel. The WGPU backend ships such a kernel today; other providers may supply their own implementation. If the hook is missing, RunMat gathers the data to the host, performs the transpose once, and re-uploads it so downstream GPU work continues without residency churn."
]
}