So numpy has some convenience functions for combining several arrays into one, e.g. hstack and vstack. I'm wondering if there's something similar but for stacking the component arrays diagonally?

Say I have N arrays of shape (n_i, m_i), and I want to combine them into a single array of size (sum_{1,N}n_i, sum_{1,N}m_i) such that the component arrays form blocks on the diagonal of the result array.

And yes, I know how to solve it manually, e.g. with the approach described in How to "embed" a small numpy array into a predefined block of a large numpy array? . Just wondering if there's an easier way.

Ah, How can I transform blocks into a blockdiagonal matrix (NumPy) mentions that scipy.linalg.block_diag() is the solution, except that the version of scipy installed on my workstation is so old it doesn't have it. Any other ideas?

It does seem `block_diag`

does exactly what you want. So if for some reason you can't update scipy, then here is the source from `v0.8.0`

if you wish to simply define it!

```
import numpy as npdef block_diag(*arrs):"""Create a block diagonal matrix from the provided arrays.Given the inputs `A`, `B` and `C`, the output will have thesearrays arranged on the diagonal::[[A, 0, 0],[0, B, 0],[0, 0, C]]If all the input arrays are square, the output is known as ablock diagonal matrix.Parameters----------A, B, C, ... : array-like, up to 2DInput arrays. A 1D array or array-like sequence with length n istreated as a 2D array with shape (1,n).Returns-------D : ndarrayArray with `A`, `B`, `C`, ... on the diagonal. `D` has thesame dtype as `A`.References----------.. [1] Wikipedia, "Block matrix",http://en.wikipedia.org/wiki/Block_diagonal_matrixExamples-------->>> A = [[1, 0],... [0, 1]]>>> B = [[3, 4, 5],... [6, 7, 8]]>>> C = [[7]]>>> print(block_diag(A, B, C))[[1 0 0 0 0 0][0 1 0 0 0 0][0 0 3 4 5 0][0 0 6 7 8 0][0 0 0 0 0 7]]>>> block_diag(1.0, [2, 3], [[4, 5], [6, 7]])array([[ 1., 0., 0., 0., 0.],[ 0., 2., 3., 0., 0.],[ 0., 0., 0., 4., 5.],[ 0., 0., 0., 6., 7.]])"""if arrs == ():arrs = ([],)arrs = [np.atleast_2d(a) for a in arrs]bad_args = [k for k in range(len(arrs)) if arrs[k].ndim > 2]if bad_args:raise ValueError("arguments in the following positions have dimension ""greater than 2: %s" % bad_args) shapes = np.array([a.shape for a in arrs])out = np.zeros(np.sum(shapes, axis=0), dtype=arrs[0].dtype)r, c = 0, 0for i, (rr, cc) in enumerate(shapes):out[r:r + rr, c:c + cc] = arrs[i]r += rrc += ccreturn out
```