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 of the same type as the type of the argument.

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.

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.
Authors:
Ilya Yaroshenko
template swapped(size_t dimensionA, size_t dimensionB)

Slice!(kind, packs, Iterator) swapped(SliceKind kind, size_t[] packs, Iterator)(Slice!(kind, packs, Iterator) slice, size_t dimensionA, size_t dimensionB)
if (kind == Universal || kind == Canonical);

Slice!(Universal, [2], Iterator) swapped(Iterator)(Slice!(Universal, [2], Iterator) slice);
Swaps two dimensions.
Parameters:
Slice!(kind, packs, Iterator) slice input slice
size_t dimensionA first dimension
size_t dimensionB second dimension
Returns:
n-dimensional slice of the same type
See Also:
Examples:
Template
import mir.ndslice.slice;
import mir.ndslice.topology : iota, canonical, universal;

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

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

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

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

Slice!(kind, packs, Iterator) rotated(SliceKind kind, size_t[] packs, Iterator)(Slice!(kind, packs, Iterator) slice, size_t dimensionA, size_t dimensionB, sizediff_t k = 1)
if (kind == Universal || kind == Canonical);

Slice!(Universal, [2], Iterator) rotated(Iterator)(Slice!(Universal, [2], Iterator) 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!(kind, packs, Iterator) 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 of the same type
Examples:
import mir.ndslice.slice;
import mir.ndslice.topology : iota, universal;
auto slice = iota(2, 3).universal;

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);
Slice!(kind, packs, Iterator) rotated(SliceKind kind, size_t[] packs, Iterator)(Slice!(kind, packs, Iterator) slice, sizediff_t k = 1)
if (kind == Universal || kind == Canonical);
Slice!(kind, packs, Iterator) everted(size_t[] packs, SliceKind kind, Iterator)(Slice!(kind, packs, Iterator) slice)
if (kind == Universal || kind == Canonical && packs.length > 1);
Reverses the order of dimensions.
Parameters:
Slice!(kind, packs, Iterator) slice input slice
Returns:
n-dimensional slice of the same type
See Also:
Examples:
import mir.ndslice.slice;
import mir.ndslice.topology : iota, universal;
assert(iota(3, 4, 5)
    .universal
    .everted
    .shape == cast(size_t[3])[5, 4, 3]);
template transposed(Dimensions...) if (Dimensions.length)

Slice!(kind, packs, Iterator) transposed(SliceKind kind, size_t[] packs, Iterator, size_t M)(Slice!(kind, packs, Iterator) slice, size_t[M] dimensions...)
if (kind == Universal || kind == Canonical);

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

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

assert(iota(3, 4, 5, 6, 7)
    .universal
    .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, canonical, universal;

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

assert(iota(3, 4, 5, 6, 7)
    .universal
    .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, canonical, universal;

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

assert(iota(3, 4, 5, 6, 7)
    .universal
    .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, universal;
assert(iota(3, 4)
    .universal
    .transposed
    .shape == cast(size_t[2])[4, 3]);
@trusted Slice!(kind, packs, Iterator) allReversed(SliceKind kind, size_t[] packs, Iterator)(Slice!(kind, packs, Iterator) slice)
if (kind == Universal || kind == Canonical && packs.length > 1);
Reverses the direction of iteration for all dimensions.
Parameters:
Slice!(kind, packs, Iterator) slice input slice
Returns:
n-dimensional slice of the same type
Examples:
import mir.ndslice.slice;
import mir.ndslice.topology : iota, retro, universal;
assert(iota(4, 5).universal.allReversed == iota(4, 5).retro);
template reversed(Dimensions...) if (Dimensions.length)

@trusted Slice!(kind, packs, Iterator) reversed(SliceKind kind, size_t[] packs, Iterator, size_t M)(Slice!(kind, packs, Iterator) slice, size_t[M] dimensions...)
if (kind == Universal || kind == Canonical);
Reverses the direction of iteration for selected dimensions.
Parameters:
Slice!(kind, packs, Iterator) slice input slice
Dimensions indexes of dimensions to reverse order of iteration
size_t[M] dimensions indexes of dimensions to reverse order of iteration
Returns:
n-dimensional slice of the same type
Examples:
import mir.ndslice.topology: iota, universal;
auto slice = iota([2, 2], 1).universal;
assert(slice                    == [[1, 2], [3, 4]]);

// 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]]);
template strided(Dimensions...) if (Dimensions.length)

Slice!(kind, packs, Iterator) strided(SliceKind kind, size_t[] packs, Iterator)(Slice!(kind, packs, Iterator) slice, size_t dimension, ptrdiff_t factor);
Multiplies the stride of the selected dimension by a factor.
Parameters:
Dimensions indexes 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 of the same type
Examples:
import mir.ndslice.topology: iota, universal;
auto slice = iota(3, 4).universal;

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!(kind, packs, Iterator) dropToHypercube(SliceKind kind, size_t[] packs, Iterator)(Slice!(kind, packs, Iterator) slice)
if (kind == Canonical || kind == Universal);
Returns maximal multidimensional cube.
Parameters:
Slice!(kind, packs, Iterator) slice input slice
Returns:
n-dimensional slice of the same type
Examples:
import mir.ndslice.topology : iota, canonical, universal;

assert(iota(5, 3, 6, 7)
    .canonical
    .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]);