mygrad.sliding_window_view#

mygrad.sliding_window_view(arr, window_shape, step, dilation=None)[source]#

Create a sliding window view over the trailing dimensions of an array. No copy is made unless the input array is not contiguous in memory.

The window is applied only to valid regions of arr, but is applied greedily.

See Notes section for details.

Parameters:
arrnumpy.ndarray, shape=(…, [x, (…), z])

C-contiguous array over which sliding view-window is applied along the trailing dimensions [x, ..., z], as determined by the length of window_shape.

If arr is not C-contiguous, it will be replaced by numpy.ascontiguousarray(arr)

window_shapeSequence[int]

Specifies the shape of the view-window: [Wx, (...), Wz]. The length of window_shape determines the length of [x, (...) , z].

stepUnion[int, Sequence[int]]

The step sized used along the [x, (...), z] dimensions: [Sx, (...), Sz]. If a single integer is specified, a uniform step size is used.

dilationOptional[Union[int, Sequence[int]]]

The dilation factor used along the [x, (...), z] directions: [Dx, (...), Dz]. If no value is specified, a dilation factor of 1 is used along each direction. Dilation specifies the step size used when filling the window’s elements

Returns:
numpy.ndarray

A contiguous view of arr, of shape ([X, (...), Z], ..., [Wx, (...), Wz]), where [X, ..., Z] is the shape of the grid on which the window was applied. See Notes sections for more details.

Raises:
ValueError, TypeError

Invalid step-size, window shape, or dilation

Notes

Window placement:

Given a dimension of size x, with a window of size W along this dimension, applied with stride S and dilation D, the window will be applied:

X = (x - (W - 1) * D + 1) // S + 1

number of times along that dimension.

Interpreting output:

In general, given an array arr of shape (…, x, (…), z), and:

out = sliding_window_view(arr, window_shape=[Wx, (...), Wz], step=[Sx, (...), Sz])

then indexing out with [ix, (...), iz] produces the following view of x:

out[ix, (...), iz] ==
    x[..., ix*Sx:(ix*Sx + Wx*Dx):Dx, (...), iz*Sz:(iz*Sz + Wz*Dz):Dz]

For example, suppose arr is an array of shape-(10, 12, 6). Specifying sliding window of shape (3, 3) with step size (2, 2), dilation (2, 1) will create the view:

[[arr[:,  0:6:2, 0:3], arr[:,   0:6:3, 3:6]]
 [arr[:, 6:12:2, 0:3], arr[:, 6:12:12, 3:6]]]

producing a view of shape (2, 2, 10, 3, 3) in total.

Examples

>>> import numpy as np
>>> x = np.arange(36).reshape(6, 6)
>>> x
array([[ 0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11],
       [12, 13, 14, 15, 16, 17],
       [18, 19, 20, 21, 22, 23],
       [24, 25, 26, 27, 28, 29],
       [30, 31, 32, 33, 34, 35]])

Apply an 3x2 window with step-sizes of (2, 2). This results in the window being placed twice along axis-0 and three times along axis-1.

>>> y = sliding_window_view(x, step=(2, 2), window_shape=(3, 2))
>>> y.shape
(2, 3, 3, 2)

window applied at (0, 0)

>>> y[0, 0]
array([[ 0,  1],
       [ 6,  7],
       [12, 13]])

window applied at (2, 0)

>>> y[1, 0]
array([[12, 13],
       [18, 19],
       [24, 25]])

window applied at (0, 2)

>>> y[0, 1]
array([[ 2,  3],
       [ 8,  9],
       [14, 15]])

verify that an element in this window-view is correct

>>> i, j = np.random.randint(0, 2, size=2)
>>> wx, wy = (2, 2)
>>> sx, sy = (2, 2)
>>> np.all(y[i, j] == x[..., i*sx:(i*sx + wx), j*sy:(j*sy + wy)])
True