Report a bug
If you spot a problem with this page, click here to create a GitHub issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using a local clone.

mir.ndslice.dynamic

This is a submodule of mir.ndslice.
Operators only change strides and lengths of a slice. The range of a slice remains unmodified. All operators return slice as the type of the argument, maybe except slice kind.

Transpose operators

Function Name Description
transposed Permutes dimensions.
iota(3, 4, 5, 6, 7).transposed!(4, 0, 1).shape returns [7, 3, 4, 5, 6].
swapped Swaps dimensions
iota(3, 4, 5).swapped!(1, 2).shape returns [3, 5, 4].
everted Reverses the order of dimensions
iota(3, 4, 5).everted.shape returns [5, 4, 3].
See also evertPack .

Iteration operators

Function Name Description
strided Multiplies the stride of a selected dimension by a factor.
iota(13, 40).strided!(0, 1)(2, 5).shape equals to [7, 8].
reversed Reverses the direction of iteration for selected dimensions.
slice.reversed!0 returns the slice with reversed direction of iteration for top level dimension.
allReversed Reverses the direction of iteration for all dimensions.
iota(4, 5).allReversed equals to 20.iota.retro.sliced(4, 5).

Other operators

Function Name Description
rotated Rotates two selected dimensions by k*90 degrees.
iota(2, 3).rotated equals to [[2, 5], [1, 4], [0, 3]].
dropToHypercube Returns maximal multidimensional cube of a slice.
normalizeStructure Reverses iteration order for dimensions with negative strides, they become not negative; and sorts dimensions according to the strides, dimensions with larger strides are going first.

Bifacial operators

Some operators are bifacial, i.e. they have two versions: one with template parameters, and another one with function parameters. Versions with template parameters are preferable because they allow compile time checks and can be optimized better.
Function Name Variadic Template Function
swapped No slice.swapped!(2, 3) slice.swapped(2, 3)
rotated No slice.rotated!(2, 3)(-1) slice.rotated(2, 3, -1)
strided Yes/No slice.strided!(1, 2)(20, 40) slice.strided(1, 20).strided(2, 40)
transposed Yes slice.transposed!(1, 4, 3) slice.transposed(1, 4, 3)
reversed Yes slice.reversed!(0, 2) slice.reversed(0, 2)
Bifacial interface of drop, dropBack dropExactly, and dropBackExactly is identical to that of strided.
Bifacial interface of dropOne and dropBackOne is identical to that of reversed.
License:
Authors:
Ilya Yaroshenko
bool normalizeStructure(Iterator, size_t N, SliceKind kind)(ref Slice!(Iterator, N, kind) slice);
Reverses iteration order for dimensions with negative strides, they become not negative; and sorts dimensions according to the strides, dimensions with larger strides are going first.
Parameters:
Slice!(Iterator, N, kind) slice a slice to normalize dimension
Returns:
true if the slice can be safely casted to Contiguous  kind using assumeContiguous  and false otherwise.
Examples:
import mir.ndslice.topology: iota;

auto g = iota(2, 3); //contiguous
auto c = g.reversed!0; //canonical
auto u = g.transposed.allReversed; //universal

assert(g.normalizeStructure);
assert(c.normalizeStructure);
assert(u.normalizeStructure);

assert(c == g);
assert(u == g);

c.popFront!1;
u.popFront!1;

assert(!c.normalizeStructure);
assert(!u.normalizeStructure);
template swapped(size_t dimensionA, size_t dimensionB)

auto swapped(Iterator, size_t N, SliceKind kind)(Slice!(Iterator, N, kind) _slice, size_t dimensionA, size_t dimensionB);

Slice!(Iterator, 2, Universal) swapped(Iterator, SliceKind kind)(Slice!(Iterator, 2, kind) slice);
Swaps two dimensions.
Parameters:
Slice!(Iterator, 2, kind) slice input slice
size_t dimensionA first dimension
size_t dimensionB second dimension
Returns:
n-dimensional slice
See Also:
Examples:
Template
import mir.ndslice.slice;
import mir.ndslice.topology: iota;

assert(iota(3, 4, 5, 6)
    .swapped!(2, 1)
    .shape == cast(size_t[4])[3, 5, 4, 6]);

assert(iota(3, 4, 5, 6)
    .swapped!(3, 1)
    .shape == cast(size_t[4])[3, 6, 5, 4]);
Examples:
Function
import mir.ndslice.slice;
import mir.ndslice.topology: iota;

assert(iota(3, 4, 5, 6)
    .swapped(1, 2)
    .shape == cast(size_t[4])[3, 5, 4, 6]);

assert(iota(3, 4, 5, 6)
    .swapped(1, 3)
    .shape == cast(size_t[4])[3, 6, 5, 4]);
Examples:
2D
import mir.ndslice.slice;
import mir.ndslice.topology: iota;
assert(iota(3, 4)
    .swapped
    .shape == cast(size_t[2])[4, 3]);
auto swapped(Iterator, size_t N, SliceKind kind)(Slice!(Iterator, N, kind) _slice);
template rotated(size_t dimensionA, size_t dimensionB)

auto rotated(Iterator, size_t N, SliceKind kind)(Slice!(Iterator, N, kind) _slice, size_t dimensionA, size_t dimensionB, sizediff_t k = 1);

Slice!(Iterator, 2, Universal) rotated(Iterator, SliceKind kind)(Slice!(Iterator, 2, kind) slice, sizediff_t k = 1);
Rotates two selected dimensions by k*90 degrees. The order of dimensions is important. If the slice has two dimensions, the default direction is counterclockwise.
Parameters:
Slice!(Iterator, 2, kind) slice input slice
size_t dimensionA first dimension
size_t dimensionB second dimension
sizediff_t k rotation counter, can be negative
Returns:
n-dimensional slice
Examples:
import mir.ndslice.slice;
import mir.ndslice.topology: iota;
auto slice = iota(2, 3);

auto a = [[0, 1, 2],
          [3, 4, 5]];

auto b = [[2, 5],
          [1, 4],
          [0, 3]];

auto c = [[5, 4, 3],
          [2, 1, 0]];

auto d = [[3, 0],
          [4, 1],
          [5, 2]];

assert(slice.rotated       ( 4) == a);
assert(slice.rotated!(0, 1)(-4) == a);
assert(slice.rotated (1, 0,  8) == a);

assert(slice.rotated            == b);
assert(slice.rotated!(0, 1)(-3) == b);
assert(slice.rotated (1, 0,  3) == b);

assert(slice.rotated       ( 6) == c);
assert(slice.rotated!(0, 1)( 2) == c);
assert(slice.rotated (0, 1, -2) == c);

assert(slice.rotated       ( 7) == d);
assert(slice.rotated!(0, 1)( 3) == d);
assert(slice.rotated (1, 0,   ) == d);
auto rotated(Iterator, size_t N, SliceKind kind)(Slice!(Iterator, N, kind) _slice, sizediff_t k = 1);
auto everted(Iterator, size_t N, SliceKind kind)(Slice!(Iterator, N, kind) _slice);
Reverses the order of dimensions.
Parameters:
Slice!(Iterator, N, kind) _slice input slice
Returns:
n-dimensional slice
See Also:
Examples:
import mir.ndslice.slice;
import mir.ndslice.topology: iota;
assert(iota(3, 4, 5)
    .everted
    .shape == cast(size_t[3])[5, 4, 3]);
template transposed(Dimensions...) if (Dimensions.length)

auto transposed(Iterator, size_t N, SliceKind kind, size_t M)(Slice!(Iterator, N, kind) _slice, size_t[M] dimensions...);

Slice!(Iterator, 2, Universal) transposed(Iterator, SliceKind kind)(Slice!(Iterator, 2, kind) slice);
N-dimensional transpose operator. Brings selected dimensions to the first position.
Parameters:
Slice!(Iterator, 2, kind) slice input slice
Dimensions indices of dimensions to be brought to the first position
size_t[M] dimensions indices of dimensions to be brought to the first position
Returns:
n-dimensional slice
See Also:
Examples:
Template
import mir.ndslice.slice;
import mir.ndslice.topology: iota;

assert(iota(3, 4, 5, 6, 7)
    .transposed!(3, 1, 0)
    .shape == cast(size_t[5])[6, 4, 3, 5, 7]);

assert(iota(3, 4, 5, 6, 7)
    .transposed!(4, 1, 0)
    .shape == cast(size_t[5])[7, 4, 3, 5, 6]);
Examples:
Function
import mir.ndslice.slice;
import mir.ndslice.topology: iota;

assert(iota(3, 4, 5, 6, 7)
    .transposed(3, 1, 0)
    .shape == cast(size_t[5])[6, 4, 3, 5, 7]);

assert(iota(3, 4, 5, 6, 7)
    .transposed(4, 1, 0)
    .shape == cast(size_t[5])[7, 4, 3, 5, 6]);
Examples:
Single-argument function
import mir.ndslice.slice;
import mir.ndslice.topology: iota;

assert(iota(3, 4, 5, 6, 7)
    .transposed(3)
    .shape == cast(size_t[5])[6, 3, 4, 5, 7]);

assert(iota(3, 4, 5, 6, 7)
    .transposed(4)
    .shape == cast(size_t[5])[7, 3, 4, 5, 6]);
Examples:
2-dimensional transpose
import mir.ndslice.slice;
import mir.ndslice.topology: iota;
assert(iota(3, 4)
    .transposed
    .shape == cast(size_t[2])[4, 3]);
auto transposed(Iterator, size_t N, SliceKind kind)(Slice!(Iterator, N, kind) _slice);
Slice!(Iterator, N, Universal) allReversed(Iterator, size_t N, SliceKind kind)(Slice!(Iterator, N, kind) _slice);
Reverses the direction of iteration for all dimensions.
Parameters:
Slice!(Iterator, N, kind) _slice input slice
Returns:
n-dimensional slice
Examples:
import mir.ndslice.slice;
import mir.ndslice.topology: iota, retro;
assert(iota(4, 5).allReversed == iota(4, 5).retro);
template reversed(Dimensions...) if (Dimensions.length)

@trusted Slice!(Iterator, N, Universal) reversed(Iterator, size_t N, SliceKind kind, size_t M)(Slice!(Iterator, N, kind) _slice, size_t[M] dimensions...)
if (M);

auto reversed(Iterator, size_t N, SliceKind kind)(Slice!(Iterator, N, kind) slice);
Reverses the direction of iteration for selected dimensions.
Parameters:
Slice!(Iterator, N, kind) _slice input slice
Dimensions indices of dimensions to reverse order of iteration
size_t[M] dimensions indices of dimensions to reverse order of iteration
Returns:
n-dimensional slice
Examples:
import mir.ndslice.topology: iota;

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

// Default
assert(slice.reversed           == [[3, 4], [1, 2]]);

// Template
assert(slice.reversed! 0        == [[3, 4], [1, 2]]);
assert(slice.reversed! 1        == [[2, 1], [4, 3]]);
assert(slice.reversed!(0, 1)    == [[4, 3], [2, 1]]);
assert(slice.reversed!(1, 0)    == [[4, 3], [2, 1]]);
assert(slice.reversed!(1, 1)    == [[1, 2], [3, 4]]);
assert(slice.reversed!(0, 0, 0) == [[3, 4], [1, 2]]);

// Function
assert(slice.reversed (0)       == [[3, 4], [1, 2]]);
assert(slice.reversed (1)       == [[2, 1], [4, 3]]);
assert(slice.reversed (0, 1)    == [[4, 3], [2, 1]]);
assert(slice.reversed (1, 0)    == [[4, 3], [2, 1]]);
assert(slice.reversed (1, 1)    == [[1, 2], [3, 4]]);
assert(slice.reversed (0, 0, 0) == [[3, 4], [1, 2]]);
Examples:
import mir.ndslice.topology: iota, canonical;
auto slice = iota([2, 2], 1).canonical;
assert(slice                    == [[1, 2], [3, 4]]);

// Template
assert(slice.reversed! 0        == [[3, 4], [1, 2]]);
assert(slice.reversed!(0, 0, 0) == [[3, 4], [1, 2]]);

// Function
assert(slice.reversed (0)       == [[3, 4], [1, 2]]);
assert(slice.reversed (0, 0, 0) == [[3, 4], [1, 2]]);
@trusted auto reversed(Iterator, size_t N, SliceKind kind)(Slice!(Iterator, N, kind) _slice);
auto strided(Iterator, size_t N, SliceKind kind)(Slice!(Iterator, N, kind) slice, ptrdiff_t factor);

template strided(Dimensions...) if (Dimensions.length)

Slice!(Iterator, N, Universal) strided(Iterator, size_t N, SliceKind kind)(Slice!(Iterator, N, kind) _slice, size_t dimension, ptrdiff_t factor);
Multiplies the stride of the selected dimension by a factor.
Parameters:
Dimensions indices of dimensions to be strided
size_t dimension indexe of a dimension to be strided
ptrdiff_t factor step extension factors
Returns:
n-dimensional slice
Examples:
import mir.ndslice.topology: iota;
// 0  1   2  3
// 4  5   6  7
// 8  9  10 11
assert(iota(3, 4).strided(2) == [[0, 2], [8, 10]]);
Examples:
import mir.ndslice.topology: iota;
auto slice = iota(3, 4);

assert(slice
    == [[0,1,2,3], [4,5,6,7], [8,9,10,11]]);

// Template
assert(slice.strided!0(2)
    == [[0,1,2,3],            [8,9,10,11]]);

assert(slice.strided!1(3)
    == [[0,    3], [4,    7], [8,     11]]);

assert(slice.strided!(0, 1)(2, 3)
    == [[0,    3],            [8,     11]]);

// Function
assert(slice.strided(0, 2)
    == [[0,1,2,3],            [8,9,10,11]]);

assert(slice.strided(1, 3)
    == [[0,    3], [4,    7], [8,     11]]);

assert(slice.strided(0, 2).strided(1, 3)
    == [[0,    3],            [8,     11]]);
Examples:
import mir.ndslice.topology: iota, universal;
static assert(iota(13, 40).universal.strided!(0, 1)(2, 5).shape == [7, 8]);
static assert(iota(93).universal.strided!(0, 0)(7, 3).shape == [5]);
Examples:
import mir.ndslice.topology: iota, canonical;
auto slice = iota(3, 4).canonical;

assert(slice
    == [[0,1,2,3], [4,5,6,7], [8,9,10,11]]);

// Template
assert(slice.strided!0(2)
    == [[0,1,2,3],            [8,9,10,11]]);

// Function
assert(slice.strided(0, 2)
    == [[0,1,2,3],            [8,9,10,11]]);
Slice!(Iterator, N, kind) dropToHypercube(Iterator, size_t N, SliceKind kind)(Slice!(Iterator, N, kind) slice)
if (kind == Canonical || kind == Universal || N == 1);

Slice!(Iterator, N, Canonical) dropToHypercube(Iterator, size_t N)(Slice!(Iterator, N) slice)
if (N > 1);
Returns maximal multidimensional cube.
Parameters:
Slice!(Iterator, N, kind) slice input slice
Returns:
n-dimensional slice
Examples:
import mir.ndslice.topology: iota, canonical, universal;

assert(iota(5, 3, 6, 7)
    .dropToHypercube
    .shape == cast(size_t[4])[3, 3, 3, 3]);

assert(iota(5, 3, 6, 7)
    .universal
    .dropToHypercube
    .shape == cast(size_t[4])[3, 3, 3, 3]);

assert(4.iota.dropToHypercube == 4.iota);