windows

Returns an n-dimensional slice of n-dimensional overlapping windows. windows can be generalized with other selectors. For example, windows in combination with diagonal can be used to get a multi-diagonal slice.

@optmath
Slice!(SliceIterator!(Iterator, N, N == 1 ? kind : min(kind, Canonical)), N, Universal)
windows
(
Iterator
size_t N
SliceKind kind
)
(
Slice!(Iterator, N, kind) slice
,
size_t[N] rlengths...
)

Parameters

N

dimension count

slice Slice!(Iterator, N, kind)

slice to be iterated

rlengths size_t[N]

dimensions of windows

Return Value

Type: Slice!(SliceIterator!(Iterator, N, N == 1 ? kind : min(kind, Canonical)), N, Universal)

packed N-dimensional slice composed of N-dimensional slices

Examples

import mir.ndslice.allocation;
import mir.ndslice.slice;
auto slice = slice!int(5, 8);
auto windows = slice.windows(2, 3);

int i;
foreach (windowsRaw; windows)
    foreach (window; windowsRaw)
        ++window[];

assert(slice ==
    [[1,  2,  3, 3, 3, 3,  2,  1],

     [2,  4,  6, 6, 6, 6,  4,  2],
     [2,  4,  6, 6, 6, 6,  4,  2],
     [2,  4,  6, 6, 6, 6,  4,  2],

     [1,  2,  3, 3, 3, 3,  2,  1]]);
import mir.ndslice.allocation;
import mir.ndslice.slice;
auto slice = slice!int(5, 8);
auto windows = slice.windows(2, 3);
windows[1, 2][] = 1;
windows[1, 2][0, 1] += 1;
windows.unpack[1, 2, 0, 1] += 1;

assert(slice ==
    [[0, 0,  0, 0, 0,  0, 0, 0],

     [0, 0,  1, 3, 1,  0, 0, 0],
     [0, 0,  1, 1, 1,  0, 0, 0],

     [0, 0,  0, 0, 0,  0, 0, 0],
     [0, 0,  0, 0, 0,  0, 0, 0]]);

Multi-diagonal matrix

import mir.ndslice.allocation;
import mir.ndslice.slice;
auto slice = slice!int(8, 8);
auto windows = slice.windows(3, 3);

auto multidiagonal = windows
    .diagonal
    .unpack;
foreach (window; multidiagonal)
    window[] += 1;

assert(slice ==
    [[ 1, 1, 1,  0, 0, 0, 0, 0],
     [ 1, 2, 2, 1,  0, 0, 0, 0],
     [ 1, 2, 3, 2, 1,  0, 0, 0],
     [0,  1, 2, 3, 2, 1,  0, 0],
     [0, 0,  1, 2, 3, 2, 1,  0],
     [0, 0, 0,  1, 2, 3, 2, 1],
     [0, 0, 0, 0,  1, 2, 2, 1],
     [0, 0, 0, 0, 0,  1, 1, 1]]);

Sliding window over matrix columns

import mir.ndslice.allocation;
import mir.ndslice.slice;
auto slice = slice!int(5, 8);
auto windows = slice
    .pack!1
    .evertPack
    .windows(3)
    .unpack;

foreach (window; windows)
    window[] += 1;

assert(slice ==
    [[1,  2,  3, 3, 3, 3,  2,  1],
     [1,  2,  3, 3, 3, 3,  2,  1],
     [1,  2,  3, 3, 3, 3,  2,  1],
     [1,  2,  3, 3, 3, 3,  2,  1],
     [1,  2,  3, 3, 3, 3,  2,  1]]);

Overlapping blocks using windows

//  ----------------
// |  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 |
//  ----------------
//->
//  ---------------------
// |  0  1  2 |  2  3  4 |
// |  5  6  7 |  7  8  9 |
// | 10 11 12 | 12 13 14 |
// | - - - - - - - - - - |
// | 10 11 13 | 12 13 14 |
// | 15 16 17 | 17 18 19 |
// | 20 21 22 | 22 23 24 |
//  ---------------------

import mir.ndslice.slice;
import mir.ndslice.dynamic : strided;

auto overlappingBlocks = iota(5, 5)
    .windows(3, 3)
    .universal
    .strided!(0, 1)(2, 2);

assert(overlappingBlocks ==
        [[[[ 0,  1,  2], [ 5,  6,  7], [10, 11, 12]],
          [[ 2,  3,  4], [ 7,  8,  9], [12, 13, 14]]],
         [[[10, 11, 12], [15, 16, 17], [20, 21, 22]],
          [[12, 13, 14], [17, 18, 19], [22, 23, 24]]]]);

Meta