diag — Create diagonal matrices or extract diagonals in MATLAB and RunMat.

diag either constructs a diagonal matrix from a vector or extracts a diagonal from a matrix. Offset handling and supported input classes follow MATLAB semantics.

Syntax

B = diag(A)
B = diag(A, k)
B = diag(A, sz)
B = diag(A, k, sz)
B = diag(A, "vector")
B = diag(A, class)
B = diag(A, "like", prototype)
B = diag(A, args...)

Inputs

NameTypeRequiredDefaultDescription
AAnyYesInput scalar, vector, or matrix.
kNumericScalarYesDiagonal offset index.
szSizeArgYesOutput matrix size override as [m n] or scalar n.
optionStringScalarYes"vector"Vector extraction option ('vector').
classStringScalarYesOutput class override ('logical' or 'double').
likeStringScalarYes"like"Literal option name ('like').
prototypeLikePrototypeYesPrototype value controlling output class/residency.
argsAnyVariadicOptional offset/size/options parsed by diag argument grammar.

Returns

NameTypeDescription
BAnyDiagonal matrix or diagonal vector extracted from the input.

Errors

IdentifierWhenMessage
RunMat:diag:InvalidInputInput type, option grammar, size override, or output conversion is invalid.diag: invalid input argument
RunMat:diag:InvalidOffsetDiagonal offset is not a finite integer scalar.diag: invalid diagonal offset

How diag works

  • diag(v) with a vector v returns a square matrix whose main diagonal is v.
  • diag(v, k) places v on the k-th diagonal: super-diagonals for k > 0, sub-diagonals for k < 0. The output size grows by abs(k).
  • diag(A) with a matrix A returns a column vector containing the main diagonal of A.
  • diag(A, k) extracts the k-th diagonal. When the requested diagonal does not exist, an empty column vector is returned.
  • diag(v, 'vector') always returns a column vector copy of v, even when v is already a vector.
  • diag(v, [m n]) creates an explicit rectangular size. You can combine it with offsets (e.g. diag(v, k, [m n])) when you need a wider diagonal band.
  • diag(___, 'logical') converts the result to a logical array. diag(___, 'double') forces a double-precision result when inputs are logical.
  • diag(___, 'like', prototype) matches the numeric flavour and residency of prototype (including GPU handles).
  • Logical inputs stay logical; complex inputs stay complex; character arrays preserve padding with spaces off the diagonal.
  • Higher-dimensional inputs are accepted when trailing dimensions are singleton—only the leading 2-D slice participates in the diagonal operation.

Does RunMat run diag on the GPU?

When a real or logical input lives on the GPU, RunMat calls the acceleration provider's diag_from_vector, diag_from_vector_sized, diag_extract, or metadata-only reshape hook as appropriate. That covers native vector-to-matrix placement, explicit rectangular size overrides, 'vector' mode, matrix diagonal extraction, and empty out-of-bounds diagonals without gathering. Providers that do not expose these hooks fall back to a host result. Complex, character, and conversion-heavy template forms also use the host path so MATLAB-compatible class conversion semantics remain intact.

GPU memory and residency

You usually do NOT need to call gpuArray yourself in RunMat (unlike MATLAB).

In RunMat, the auto-offload planner keeps residency on the GPU when expressions make use of GPU providers. For diag, real and logical GPU inputs stay resident when the active provider exposes the required diagonal hooks. If those hooks are missing, or if the requested class semantics require host conversion, the builtin gathers once and returns the host result unless a GPU 'like' prototype explicitly requests device residency.

To preserve backwards compatibility with MathWorks MATLAB, and for when you want to explicitly bootstrap GPU residency, you can call gpuArray to move data to the GPU. That mirrors MATLAB's behaviour while still allowing RunMat's planner to decide whether the GPU offers an advantage for the surrounding computation.

Since MathWorks MATLAB does not have a fusion planner, and they kept their parallel execution toolbox separate from the core language, as their toolbox is a separate commercial product, MathWorks MATLAB users need to call gpuArray to move data to the GPU manually whereas RunMat users can rely on the fusion planner to keep data on the GPU automatically.

Examples

Creating a diagonal matrix from a vector

v = [4 5 6];
D = diag(v)

Expected output:

D =
     4     0     0
     0     5     0
     0     0     6

Placing a vector on an upper diagonal

v = [1 2 3];
U = diag(v, 1)

Expected output:

U =
     0     1     0     0
     0     0     2     0
     0     0     0     3
     0     0     0     0

Extracting a subdiagonal as a column vector

A = [1 2 3; 4 5 6; 7 8 9];
d = diag(A, -1)

Expected output:

d =
     4
     8

Building a diagonal matrix from a logical mask

mask = logical([1 0 1 0]);
M = diag(mask)

Expected output:

M =
     1     0     0     0
     0     0     0     0
     0     0     1     0
     0     0     0     0

Keeping diagonal results on the GPU

G = gpuArray([2; 4; 8]);
D = diag(G);
firstTwo = gather(D(1:2, 1:2))

Expected output:

firstTwo =
     2     0
     0     4

Returning a vector without creating a matrix

v = [10 20 30];
d = diag(v, 'vector')

Expected output:

d =
    10
    20
    30

Creating a rectangular diagonal matrix with sz

v = [1 2];
R = diag(v, [2 4])

Expected output:

R =
     1     0     0     0
     0     2     0     0

Matching residency and type with 'like'

G = gpuArray([1 3 5]');
D = diag([1 2 3], 'like', G)

Using diag with coding agents

Open a RunMat example with live inputs, then ask the agent to explain how diag changes the result.

Run a small diag example, explain the result, then change one input and compare the output.

FAQ

Does diag always return a square matrix?

Only when the input is a vector and you do not request otherwise. Use 'vector' to keep the result as a column vector, or pass a size vector (e.g. diag(v, [m n])) to create rectangular matrices.

What happens if I request a diagonal outside the matrix bounds?

You receive an empty column vector (size 0 × 0), matching MATLAB's behaviour.

Can I use diag with logical or character arrays?

Yes. Logical inputs produce logical outputs, and character inputs produce padded character arrays with spaces away from the diagonal.

Does diag support complex numbers?

Complex inputs are supported. The output keeps the real and imaginary parts intact.

How do offsets work with vectors?

diag(v, k) grows the matrix by abs(k) and shifts the diagonal up (k > 0) or down (k < 0).

Can I place a diagonal inside a non-square matrix?

Yes. Pass an explicit size vector such as diag(v, [m n]), and optionally combine it with an offset via diag(v, k, [m n]).

What if the vector is empty?

diag([]) returns a 0 × 0 matrix. diag([], k) returns a square matrix of size abs(k) filled with zeros.

Do GPU results stay on the device?

Yes. Real and logical gpuArray inputs use provider hooks for vector placement, explicit rectangular sizes, 'vector' mode, and matrix diagonal extraction. Complex, character, and conversion-heavy template forms use the host fallback.

Is the offset argument required to be an integer?

Yes. Non-integer or non-finite offsets raise an error.

Does diag modify the original input?

No. It always returns a new array, leaving the input unchanged.

How do I match another array's type or residency?

Use the 'like' syntax: diag(v, 'like', prototype). Logical, complex, and GPU prototypes are respected even when the computation falls back to the CPU path.

Is single precision supported?

Not yet. Requesting 'single' currently raises an error. Use 'like' with an appropriate prototype once single-precision support lands.

Creation

colon · eye · false · fill · full · inf · linspace · logspace · magic · meshgrid · nan · nchoosek · ndgrid · nonzeros · ones · peaks · perms · rand · randi · randn · randperm · range · sparse · spdiags · speye · spones · sprand · true · zeros

Indexing

find · ind2sub · sub2ind

Introspection

iscolumn · isempty · ismatrix · isrow · isscalar · isvector · length · ndims · numel · size

Open-source implementation

Unlike proprietary runtimes, every RunMat function is open-source. Read exactly how diag is executed, line by line, in Rust.

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.

Getting started · Benchmarks · Pricing

Download RunMat

Download RunMat for full performance, or use RunMat in your browser for zero setup.