# Block-diagonal matrix from columns

Inspired by Copied from this question at Stack Overflow.

Given a matrix `A`, create a matrix `B` such that the columns of `A` are arranged in a block-diagonal fashion. For example, given

``````1 2 3
4 5 6
``````

the output would be

``````1 0 0
4 0 0
0 2 0
0 5 0
0 0 3
0 0 6
``````

### Rules

Input and output may be in the form of 2D arrays, nested arrays, or strings with different separators for rows and columns.

Numbers in the input (matrix `A`) will be positive integers.

Unary format is allowed, as long as zeros in the output are displayed in some reasonable way. For example, the above result could be displayed using quotation marks to enclose each number:

``````'1' '' ''
'1111' '' ''
'' '11' ''
'' '11111' ''
'' '' '111'
'' '' '111111'
``````

### Test cases

Input, output:

``````1 2 3
4 5 6

1 0 0
4 0 0
0 2 0
0 5 0
0 0 3
0 0 6

10 20

10  0
0 20

10
20

10
20

1   2   3
10  20  30
100 200 300

1   0   0
10   0   0
100   0   0
0   2   0
0  20   0
0 200   0
0   0   3
0   0  30
0   0 300

2  4
6  8
10 10

2  0
6  0
10  0
0  4
0  8
0 12
``````
-
Will all the numbers in A be different? – Adám Feb 25 at 1:46
@Nᴮᶻ No, they can be equal – Luis Mendo Feb 25 at 9:57

# MATL, 6 bytes

``````"@N\$Yd
``````

Works in current version (13.0.0) of the language/compiler.

Input has the following form, with semicolon as row separator, and commas or spaces as column separators within each row:

``````[1, 2, 3; 4, 5, 6]
``````

Try it online!

### Explanation

``````"         % implicitly input 2D array and loop over its columns
@       %   push column
N\$Yd    %   build block-diagonal matrix from all stack contents. Stack contents are
%   a single column in the first iteration, or a partially built 2D array
%   and a new column in all other iterations
% end loop
% implicit display
``````

### Worked example

Consider the input `[1 2 3; 4 5 6]`. The for loop beginning with `"` takes each column of the input. Within each iteration, `@` pushes the current column onto the stack. So in the first iteration it pushes `[1; 4]`. `N\$` specifies that all the stack contents will be used as inputs of the following function, `Yd`.

This function (corresponding to MATLAB's `blkdiag`) "diagonally concatenates" its inputs to produce a block diagonal matrix (2D array). So in the first iteration `Yd` it takes one input and produces an output equal to that input, `[1; 4]`, which is left on the stack.

In the second iteration the second column of the input, `[2; 5]`, is pushed. Now `Yd` takes two 2×1 inputs, namely `[1; 4]` and `[2; 5]`, and produces the 4×2 array `[1 0; 4 0; 0 2; 0 5]`.

In the third iteration `Yd` takes the latter 4×2 array and the third column of the input, `[3; 6]`, and produces the final result `[1 0 0; 4 0 0; 0 2 0; 0 5 0; 0 0 3; 0 0 6]`.

-

## ES6, 65 bytes

``````a=>[].concat(...a[0].map((_,i)=>a.map(b=>b.map((c,j)=>i-j?0:c))))
``````

Takes as input and returns as output an array of arrays.

-
@WashingtonGuedes The inner map returns a copy of the original 2D array with all but one column zeroed out. These copies then need to be concatenated, rather than just being elements of an outer 3D array. – Neil Feb 23 at 16:48

# Mathematica, 40 39 Bytes

Credit to @Seeq for `Infix`ing `Flatten`.

``````Transpose[DiagonalMatrix/@#]~Flatten~1&
``````

Input is a list of row vectors delimited by `{}` brackets. So the initial example is represented by

``````{{1,2,3},{4,5,6}}
``````

Generate an array of `DiagonalMatrix` where each one has diagonal elements from the rows of the input (3-D array). `Transpose` so the `Flatten` operation removes the correct bracket pairs to give the desired matrix (now 2-D array).

-
Wouldn't `DiagonalMatrix/@#` work? And, by extension, `Transpose[DiagonalMatrix/@#]~Flatten~1&` – Seeq Feb 23 at 20:28
Good catch, I intended to fix that after rolling it up. Didn't think to use the `Infix` `Flatten` though. +1. – IPoiler Feb 23 at 21:49

# Pyth, 17

``````s.em.>+dm0thQkbCQ
``````

Try it online or run the Test Suite.

You can add a leading `j` to help visualize the 2D array.

-

# Jelly, 13 bytes

``````ZLR’×L0ẋ;"Zz0
``````

Try it online!

### How it works

``````ZLR’×L0ẋ;"Zz0  Main link. Input: M (matrix)

Z              Transpose M.
L             Get the length of the result. This yields the number of M's columns.
R            Range; for m columns, yield [1, ..., m].
’           Decrement to yield [0, ..., m-1].
×L         Multiply each by the length (number of rows) of M.
This yields [0, n, ..., n(m-1)], where n is the number of rows.
0ẋ       Push a list of lists of zeroes.
First element is [], last is n(m-1) zeroes.
;"Z    Prepend the kth vector of zeroes to the kth column of M.
z0  Zip, filling the non-rectangular 2D array with zeroes.
``````
-

# Mathematica, 111 bytes

``````Join@@@ReplacePart[Table[0,#2/#3]~Table~#3~Table~#3,Table[{n,n}->#[[n]],{n,#3}]]&[Length@#,Length@Flatten@#,#]&
``````
-
What's the input syntax? This throws `Table` and `Part` errors when using standard MMA matrix notation and results in an array of mixed dimensions. – IPoiler Feb 23 at 18:41

## Ruby, 817876 62 bytes

``````->a{i=-1;a[0].flat_map{i+=1;a.map{|b|x=b.map{0};x[i]=b[i];x}}}
``````

sigh Manually keeping track of the index is shorter than `with_index`.

``````->a{
i=-1;            # index of the flat_map
a[0]             # duplicate all rows as many times as necessary
.flat_map{       # we're wrapping each "group" of original rows with yet another
#  array, so we need to flat_map to get rid of those
i+=1;            # increment the index of the current subarray
a.map{|b|        # for each sub-subarray (these are the rows)...
x=b.map{0};      # zero everything out
x[i]=b[i];       # replace the desired elements
x}}}             # finally, return the modified array
``````
-

# R, 41 bytes

``````pryr::f(Matrix::.bdiag(plyr::alply(a,2)))
``````

Assumes `pryr`, `Matrix` and `plyr` packages are installed.

This creates a function that takes a 2D array (a) and returns a "sparseMatrix" where (where 0's are represented as `.`)

``````(a=matrix(1:6,ncol=3))
#      [,1] [,2] [,3]
# [1,]    1    3    5
# [2,]    2    4    6
pryr::f(Matrix::.bdiag(plyr::alply(a,2)))(a)
# 6 x 3 sparse Matrix of class "dgTMatrix"
#
# [1,] 1 . .
# [2,] 2 . .
# [3,] . 3 .
# [4,] . 4 .
# [5,] . . 5
# [6,] . . 6
``````

Explanation:

`plyr::alply(a,2)` each column of `a` and returns combines these results in a list

`Matrix::.bdiag(lst)` creates a block diagonal matrix from a list of matrices

`pryr::f` is a shorthand way to create a function.

A fully base `R` solution in 59 bytes (using the logic of @PieCot's Matlab answer):

``````function(a){l=dim(a);diag(l[2])%x%matrix(1,nrow=l[1])*c(a)}
``````
-

## MATLAB, 69 68 bytes

``````   function h=d(a)
[r,c]=size(a);h=repmat(a,c,1).*kron(eye(c),~~(1:r)')
``````

One byte was shaved off: thanks to Luis Mendo :)

-
You can save 1 byte replacing `ones(r,1)` by `~~(1:r)'` – Luis Mendo Feb 23 at 22:22