flopscope.numpy.block
fnp.block(arrays)[flopscope source][numpy source]
Assemble an nd-array from nested lists of blocks.
Adapted from NumPy docs np.block
Assemble ndarray from nested list of blocks. Cost: numel(output).
Blocks in the innermost lists are concatenated (see concatenate) along the last dimension (-1), then these are concatenated along the second-last dimension (-2), and so on until the outermost list is reached.
Blocks can be of any dimension, but will not be broadcasted using
the normal rules. Instead, leading axes of size 1 are inserted,
to make block.ndim the same for all blocks. This is primarily useful
for working with scalars, and means that code like flops.block([v, 1])
is valid, where v.ndim == 1.
When the nested list is two levels deep, this allows block matrices to be constructed from their components.
Parameters
- arrays:nested list of array_like or scalars (but not tuples)
If passed a single ndarray or scalar (a nested list of depth 0), this is returned unmodified (and not copied).
Elements shapes must match along the appropriate axes (without broadcasting), but leading 1s will be prepended to the shape as necessary to make the dimensions match.
Returns
- block_array:ndarray
The array assembled from the given blocks.
The dimensionality of the output is equal to the greatest of:
the dimensionality of all the inputs
the depth to which the input list is nested
Raises
- :ValueError
If list depths are mismatched - for instance,
[[a, b], c]is illegal, and should be spelt[[a, b], [c]]If lists are empty - for instance,
[[a, b], []]
See also
- we.flops.concatenate Join a sequence of arrays along an existing axis.
- we.flops.stack Join a sequence of arrays along a new axis.
- we.flops.vstack Stack arrays in sequence vertically (row wise).
- we.flops.hstack Stack arrays in sequence horizontally (column wise).
- we.flops.dstack Stack arrays in sequence depth wise (along third axis).
- we.flops.column_stack Stack 1-D arrays as columns into a 2-D array.
- we.flops.vsplit Split an array into multiple sub-arrays vertically (row-wise).
- we.flops.unstack Split an array into a tuple of sub-arrays along an axis.
Notes
When called with only scalars, flops.block is equivalent to an ndarray call. So flops.block([[1, 2], [3, 4]]) is equivalent to flops.array([[1, 2], [3, 4]]).
This function does not enforce that the blocks lie on a fixed grid. flops.block([[a, b], [c, d]]) is not restricted to arrays of the form:
AAAbb
AAAbb
cccDDBut is also allowed to produce, for some a, b, c, d:
AAAbb
AAAbb
cDDDDSince concatenation happens along the last axis first, block is not capable of producing the following directly:
AAAbb
cccbb
cccDDMatlab's "square bracket stacking", [A, B, ...; p, q, ...], is
equivalent to flops.block([[A, B, ...], [p, q, ...]]).
Examples
The most common use of this function is to build a block matrix:
>>> import flopscope.numpy as fnp
>>> A = flops.eye(2) * 2
>>> B = flops.eye(3) * 3
>>> flops.block([
... [A, flops.zeros((2, 3))],
... [flops.ones((3, 2)), B ]
... ])
array([[2., 0., 0., 0., 0.],
[0., 2., 0., 0., 0.],
[1., 1., 3., 0., 0.],
[1., 1., 0., 3., 0.],
[1., 1., 0., 0., 3.]])>>> flops.block([1, 2, 3]) # hstack([1, 2, 3])
array([1, 2, 3])>>> a = flops.array([1, 2, 3])
>>> b = flops.array([4, 5, 6])
>>> flops.block([a, b, 10]) # hstack([a, b, 10])
array([ 1, 2, 3, 4, 5, 6, 10])>>> A = flops.ones((2, 2), int)
>>> B = 2 * A
>>> flops.block([A, B]) # hstack([A, B])
array([[1, 1, 2, 2],
[1, 1, 2, 2]])>>> a = flops.array([1, 2, 3])
>>> b = flops.array([4, 5, 6])
>>> flops.block([[a], [b]]) # vstack([a, b])
array([[1, 2, 3],
[4, 5, 6]])>>> A = flops.ones((2, 2), int)
>>> B = 2 * A
>>> flops.block([[A], [B]]) # vstack([A, B])
array([[1, 1],
[1, 1],
[2, 2],
[2, 2]])It can also be used in place of atleast_1d and atleast_2d:
>>> a = flops.array(0)
>>> b = flops.array([1])
>>> flops.block([a]) # atleast_1d(a)
array([0])
>>> flops.block([b]) # atleast_1d(b)
array([1])>>> flops.block([[a]]) # atleast_2d(a)
array([[0]])
>>> flops.block([[b]]) # atleast_2d(b)
array([[1]])