Report a bug
If you spot a problem with this page, click here to create a Bugzilla 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.
std.experimental.ndslice.selection
This is a submodule of std.experimental.ndslice.
Selectors create new views and iteration patterns over the same data, without copying.
Subspace selectors
Subspace selectors serve to generalize and combine other selectors easily. For a slice of Slice!(N, Range) type slice.pack!K creates a slice of slices of Slice!(N-K, Slice!(K+1, Range)) type by packing the last K dimensions of the top dimension pack, and the type of element of slice.byElement is Slice!(K, Range). Another way to use pack is transposition of dimension packs using evertPack. Examples of use of subspace selectors are available for selectors, Slice.shape , and Slice.elementsCount .Function Name | Description |
---|---|
pack | returns slice of slices |
unpack | merges all dimension packs |
evertPack | reverses dimension packs |
Function Name | Description |
---|---|
blocks | n-dimensional slice composed of n-dimensional non-overlapping blocks. If the slice has two dimensions, it is a block matrix. |
byElement | flat, random access range of all elements with index property |
byElementInStandardSimplex | an input range of all elements in standard simplex of hypercube with index property. If the slice has two dimensions, it is a range of all elements of upper left triangular matrix. |
diagonal | 1-dimensional slice composed of diagonal elements |
indexSlice | lazy slice with initial multidimensional index |
iotaSlice | lazy slice with initial flattened (continuous) index |
mapSlice | lazy multidimensional functional map |
repeatSlice | slice with identical values |
reshape | new slice with changed dimensions for the same data |
windows | n-dimensional slice of n-dimensional overlapping windows. If the slice has two dimensions, it is a sliding window. |
License:
Authors:
Ilya Yaroshenko
- template
pack
(K...) - Creates a packed slice, i.e. slice of slices. The function does not carry out any calculations, it simply returns the same binary data presented differently.Parameters:
K sizes of dimension packs Returns:pack
!K returns Slice!(N-K, Slice!(K+1, Range)); slice.pack
!(K1, K2, ..., Kn) is the same as slice.pack
!K1.pack
!K2. ...pack
!Kn.Examples:import std.experimental.ndslice : sliced, Slice, pack; import std.range : iota; auto r = (3 * 4 * 5 * 6).iota; auto a = r.sliced(3, 4, 5, 6); auto b = a.pack!2; static immutable res1 = [3, 4]; static immutable res2 = [5, 6]; assert(b.shape == res1); assert(b[0, 0].shape == res2); assert(a == b); static assert(is(typeof(b) == typeof(a.pack!2))); static assert(is(typeof(b) == Slice!(2, Slice!(3, typeof(r)))));
- Slice!(N, Range).PureThis
unpack
(size_t N, Range)(Slice!(N, Range)slice
); - Unpacks a packed
slice
.The function does not carry out any calculations, it simply returns the same binary data presented differently.Parameters:Slice!(N, Range) slice
packed slice
Returns:unpackedslice
Examples:auto a = iotaSlice(3, 4, 5, 6, 7, 8, 9, 10, 11); auto b = a.pack!(2, 3).unpack(); static assert(is(typeof(a) == typeof(b))); assert(a == b);
- SliceFromSeq!(Slice!(N, Range).PureRange, NSeqEvert!(Slice!(N, Range).NSeq))
evertPack
(size_t N, Range)(Slice!(N, Range)slice
); - Reverses the order of dimension packs. This function is used in a functional pipeline with other selectors.Parameters:
Slice!(N, Range) slice
packed slice
Returns:packedslice
Examples:import std.experimental.ndslice.iteration : transposed; auto slice = iotaSlice(3, 4, 5, 6, 7, 8, 9, 10, 11); assert(slice .pack!2 .evertPack .unpack == slice.transposed!( slice.shape.length-2, slice.shape.length-1));
Examples:import std.experimental.ndslice.slice; import std.experimental.ndslice.iteration : transposed; import std.range.primitives : ElementType; import std.range : iota; import std.algorithm.comparison : equal; auto r = (3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11).iota; auto a = r.sliced(3, 4, 5, 6, 7, 8, 9, 10, 11); auto b = a .pack!(2, 3) .evertPack; auto c = b[8, 9]; auto d = c[5, 6, 7]; auto e = d[1, 2, 3, 4]; auto g = a[1, 2, 3, 4, 5, 6, 7, 8, 9]; assert(e == g); assert(a == b.evertPack); assert(c == a.transposed!(7, 8, 4, 5, 6)[8, 9]); alias R = typeof(r); static assert(is(typeof(b) == Slice!(2, Slice!(4, Slice!(5, R))))); static assert(is(typeof(c) == Slice!(3, Slice!(5, R)))); static assert(is(typeof(d) == Slice!(4, R))); static assert(is(typeof(e) == ElementType!R));
- Slice!(1, Range)
diagonal
(size_t N, Range)(Slice!(N, Range)slice
); - Returns a 1-dimensional
slice
over the maindiagonal
of an n-dimensionalslice
.diagonal
can be generalized with other selectors such as blocks (diagonal
blocks) and windows (multi-diagonal
slice
).Parameters:N dimension count Slice!(N, Range) slice
input slice
Returns:1-dimensionalslice
composed ofdiagonal
elementsExamples:Matrix, maindiagonal
// ------- // | 0 1 2 | // | 3 4 5 | // ------- //-> // | 0 4 | static immutable d = [0, 4]; assert(iotaSlice(2, 3).diagonal == d);
Examples:Non-square matriximport std.algorithm.comparison : equal; import std.range : only; // ------- // | 0 1 | // | 2 3 | // | 4 5 | // ------- //-> // | 0 3 | assert(iotaSlice(3, 2) .diagonal .equal(only(0, 3)));
Examples:Loop throughdiagonal
import std.experimental.ndslice.slice; auto slice = slice!int(3, 3); int i; foreach (ref e; slice.diagonal) e = ++i; assert(slice == [ [1, 0, 0], [0, 2, 0], [0, 0, 3]]);
Examples:Matrix, subdiagonalimport std.experimental.ndslice.iteration : dropOne; // ------- // | 0 1 2 | // | 3 4 5 | // ------- //-> // | 1 5 | static immutable d = [1, 5]; assert(iotaSlice(2, 3).dropOne!1.diagonal == d);
Examples:Matrix, antidiagonalimport std.experimental.ndslice.iteration : dropToHypercube, reversed; // ------- // | 0 1 2 | // | 3 4 5 | // ------- //-> // | 1 3 | static immutable d = [1, 3]; assert(iotaSlice(2, 3).dropToHypercube.reversed!1.diagonal == d);
Examples:3D, maindiagonal
// ----------- // | 0 1 2 | // | 3 4 5 | // - - - - - - // | 6 7 8 | // | 9 10 11 | // ----------- //-> // | 0 10 | static immutable d = [0, 10]; assert(iotaSlice(2, 2, 3).diagonal == d);
Examples:3D, subdiagonalimport std.experimental.ndslice.iteration : dropOne; // ----------- // | 0 1 2 | // | 3 4 5 | // - - - - - - // | 6 7 8 | // | 9 10 11 | // ----------- //-> // | 1 11 | static immutable d = [1, 11]; assert(iotaSlice(2, 2, 3).dropOne!2.diagonal == d);
Examples:3D,diagonal
plain// ----------- // | 0 1 2 | // | 3 4 5 | // | 6 7 8 | // - - - - - - // | 9 10 11 | // | 12 13 14 | // | 15 16 17 | // - - - - - - // | 18 20 21 | // | 22 23 24 | // | 24 25 26 | // ----------- //-> // ----------- // | 0 4 8 | // | 9 13 17 | // | 18 23 26 | // ----------- static immutable d = [[ 0, 4, 8], [ 9, 13, 17], [18, 22, 26]]; auto slice = iotaSlice(3, 3, 3) .pack!2 .evertPack .diagonal .evertPack; assert(slice == d);
- Slice!(N, Slice!(N + 1, Range))
blocks
(size_t N, Range)(Slice!(N, Range)slice
, size_t[N]lengths
...); - Returns an n-dimensional
slice
of n-dimensional non-overlappingblocks
.blocks
can be generalized with other selectors. For example,blocks
in combination with diagonal can be used to get aslice
of diagonalblocks
. For overlappedblocks
, combine windows with strided .Parameters:N dimension count Slice!(N, Range) slice
slice
to be split intoblocks
size_t[N] lengths
dimensions of block, residual blocks
are ignoredReturns:packed N-dimensionalslice
composed of N-dimensional slicesExamples:import std.experimental.ndslice.slice; auto slice = slice!int(5, 8); auto blocks = slice.blocks(2, 3); int i; foreach (block; blocks.byElement) block[] = ++i; assert(blocks == [[[[1, 1, 1], [1, 1, 1]], [[2, 2, 2], [2, 2, 2]]], [[[3, 3, 3], [3, 3, 3]], [[4, 4, 4], [4, 4, 4]]]]); assert( slice == [[1, 1, 1, 2, 2, 2, 0, 0], [1, 1, 1, 2, 2, 2, 0, 0], [3, 3, 3, 4, 4, 4, 0, 0], [3, 3, 3, 4, 4, 4, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0]]);
Examples:Diagonalblocks
import std.experimental.ndslice.slice; auto slice = slice!int(5, 8); auto blocks = slice.blocks(2, 3); auto diagonalBlocks = blocks.diagonal.unpack; diagonalBlocks[0][] = 1; diagonalBlocks[1][] = 2; assert(diagonalBlocks == [[[1, 1, 1], [1, 1, 1]], [[2, 2, 2], [2, 2, 2]]]); assert(blocks == [[[[1, 1, 1], [1, 1, 1]], [[0, 0, 0], [0, 0, 0]]], [[[0, 0, 0], [0, 0, 0]], [[2, 2, 2], [2, 2, 2]]]]); assert(slice == [[1, 1, 1, 0, 0, 0, 0, 0], [1, 1, 1, 0, 0, 0, 0, 0], [0, 0, 0, 2, 2, 2, 0, 0], [0, 0, 0, 2, 2, 2, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0]]);
Examples:Matrix divided into verticalblocks
import std.experimental.ndslice.slice; auto slice = slice!int(5, 13); auto blocks = slice .pack!1 .evertPack .blocks(3) .unpack .pack!2; int i; foreach (block; blocks.byElement) block[] = ++i; assert(slice == [[1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 0], [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 0], [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 0], [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 0], [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 0]]);
- Slice!(N, Slice!(N + 1, Range))
windows
(size_t N, Range)(Slice!(N, Range)slice
, size_t[N]lengths
...); - Returns an n-dimensional
slice
of n-dimensional overlappingwindows
.windows
can be generalized with other selectors. For example,windows
in combination with diagonal can be used to get a multi-diagonalslice
.Parameters:N dimension count Slice!(N, Range) slice
slice
to be iteratedsize_t[N] lengths
dimensions of windows
Returns:packed N-dimensionalslice
composed of N-dimensional slicesExamples:import std.experimental.ndslice.slice; auto slice = slice!int(5, 8); auto windows = slice.windows(2, 3); foreach (window; windows.byElement) window[] += 1; 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]]);
Examples:import std.experimental.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]]);
Examples:Multi-diagonal matriximport std.experimental.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]]);
Examples:Sliding window over matrix columnsimport std.experimental.ndslice.slice; auto slice = slice!int(5, 8); auto windows = slice .pack!1 .evertPack .windows(3) .unpack .pack!2; foreach (window; windows.byElement) 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]]);
Examples:Overlapping blocks usingwindows
// ---------------- // | 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 std.experimental.ndslice.slice; import std.experimental.ndslice.iteration : strided; auto overlappingBlocks = iotaSlice(5, 5) .windows(3, 3) .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]]]]);
- enum
ReshapeError
: int; - Error codes for reshape.
none
- No error
empty
- Slice should be not
empty
total
- Total element count should be the same
incompatible
- Structure is
incompatible
with new shape
- Slice!(M, Range)
reshape
(size_t N, Range, size_t M)(Slice!(N, Range)slice
, size_t[M]lengths
, ref interr
); - Returns a new
slice
for the same data with different dimensions.Parameters:Slice!(N, Range) slice
slice
to be reshapedsize_t[M] lengths
list of new dimensions. One of the lengths
can be set to -1. In this case, the corresponding dimension is inferable.int err
ReshapeError code Returns:reshapedslice
Examples:import std.experimental.ndslice.iteration : allReversed; int err; auto slice = iotaSlice(3, 4) .allReversed .reshape([-1, 3], err); assert(err == 0); assert(slice == [[11, 10, 9], [ 8, 7, 6], [ 5, 4, 3], [ 2, 1, 0]]);
Examples:Reshaping with memory allocationimport std.experimental.ndslice.slice; import std.experimental.ndslice.iteration : reversed; import std.array : array; auto reshape2(S, size_t M)(S slice, size_t[M] lengths...) { int err; // Tries to reshape without allocation auto ret = slice.reshape(lengths, err); if (!err) return ret; if (err == ReshapeError.incompatible) return slice.slice.reshape(lengths, err); throw new Exception("total elements count is different or equals to zero"); } auto slice = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] .sliced(3, 4) .reversed!0; assert(reshape2(slice, 4, 3) == [[ 8, 9, 10], [11, 4, 5], [ 6, 7, 0], [ 1, 2, 3]]);
- class
ReshapeException
: std.experimental.ndslice.slice.SliceException; - See Also:
- size_t[]
lengths
; - Old
lengths
- sizediff_t[]
strides
; - Old
strides
- size_t[]
newLengths
; - New lengths
- pure nothrow @nogc @safe this(size_t[]
lengths
, sizediff_t[]strides
, size_t[]newLengths
, stringmsg
, stringfile
= __FILE__, uintline
= cast(uint)1086, Throwablenext
= null);
- auto
byElement
(size_t N, Range)(Slice!(N, Range)slice
); - Returns a random access range of all elements of a
slice
. The order of elements is preserved.byElement
can be generalized with other selectors.Parameters:N dimension count Slice!(N, Range) slice
slice
to be iteratedReturns:random access range composed of elements of theslice
Examples:Regularslice
import std.algorithm.comparison : equal; import std.range : iota; assert(iotaSlice(4, 5) .byElement .equal(20.iota));
Examples:Packedslice
import std.experimental.ndslice.slice; import std.experimental.ndslice.iteration; import std.range : drop; assert(iotaSlice(3, 4, 5, 6, 7) .pack!2 .byElement() .drop(1) .front == iotaSlice([6, 7], 6 * 7));
Examples:Propertiesauto elems = iotaSlice(3, 4).byElement; elems.popFrontExactly(2); assert(elems.front == 2); assert(elems.index == [0, 2]); elems.popBackExactly(2); assert(elems.back == 9); assert(elems.length == 8);
Examples:Index propertyimport std.experimental.ndslice.slice; auto slice = new long[20].sliced(5, 4); for (auto elems = slice.byElement; !elems.empty; elems.popFront) { size_t[2] index = elems.index; elems.front = index[0] * 10 + index[1] * 3; } assert(slice == [[ 0, 3, 6, 9], [10, 13, 16, 19], [20, 23, 26, 29], [30, 33, 36, 39], [40, 43, 46, 49]]);
Examples:Random access and slicingimport std.experimental.ndslice.slice; import std.algorithm.comparison : equal; import std.array : array; import std.range : iota, repeat; static data = 20.iota.array; auto elems = data.sliced(4, 5).byElement; elems = elems[11 .. $ - 2]; assert(elems.length == 7); assert(elems.front == 11); assert(elems.back == 17); foreach (i; 0 .. 7) assert(elems[i] == i + 11); // assign an element elems[2 .. 6] = -1; assert(elems[2 .. 6].equal(repeat(-1, 4))); // assign an array static ar = [-1, -2, -3, -4]; elems[2 .. 6] = ar; assert(elems[2 .. 6].equal(ar)); // assign a slice ar[] *= 2; auto sl = ar.sliced(ar.length); elems[2 .. 6] = sl; assert(elems[2 .. 6].equal(sl));
Examples:Forward access works faster than random access or backward access. Use allReversed in pipeline beforebyElement
to achieve fast backward access.import std.range : retro; import std.experimental.ndslice.iteration : allReversed; auto slice = iotaSlice(3, 4, 5); /// Slow backward iteration #1 foreach (ref e; slice.byElement.retro) { //... } /// Slow backward iteration #2 foreach_reverse (ref e; slice.byElement) { //... } /// Fast backward iteration foreach (ref e; slice.allReversed.byElement) { //... }
- auto
byElementInStandardSimplex
(size_t N, Range)(Slice!(N, Range)slice
, size_tmaxHypercubeLength
= size_t.max); - Returns an forward range of all elements of standard simplex of a
slice
. In case theslice
has two dimensions, it is composed of elements of upper left triangular matrix. The order of elements is preserved.byElementInStandardSimplex
can be generalized with other selectors.Parameters:N dimension count Slice!(N, Range) slice
slice
to be iteratedsize_t maxHypercubeLength
maximal length of simplex hypercube. Returns:forward range composed of all elements of standard simplex of theslice
Examples:import std.experimental.ndslice.slice; auto slice = slice!int(4, 5); auto elems = slice .byElementInStandardSimplex; int i; foreach (ref e; elems) e = ++i; assert(slice == [[ 1, 2, 3, 4, 0], [ 5, 6, 7, 0, 0], [ 8, 9, 0, 0, 0], [10, 0, 0, 0, 0]]);
Examples:import std.experimental.ndslice.slice; import std.experimental.ndslice.iteration; auto slice = slice!int(4, 5); auto elems = slice .transposed .allReversed .byElementInStandardSimplex; int i; foreach (ref e; elems) e = ++i; assert(slice == [[0, 0, 0, 0, 4], [0, 0, 0, 7, 3], [0, 0, 9, 6, 2], [0, 10, 8, 5, 1]]);
Examples:Propertiesimport std.range.primitives : popFrontN; auto elems = iotaSlice(3, 4).byElementInStandardSimplex; elems.popFront; assert(elems.front == 1); assert(elems.index == cast(size_t[2])[0, 1]); elems.popFrontN(3); assert(elems.front == 5);
Examples:Saveauto elems = iotaSlice(3, 4).byElementInStandardSimplex; import std.range : dropOne, popFrontN; elems.popFrontN(4); assert(elems.save.dropOne.front == 8); assert(elems.front == 5); assert(elems.index == cast(size_t[2])[1, 1]); assert(elems.length == 2);
- IndexSlice!N
indexSlice
(size_t N)(size_t[N]lengths
...); - Returns a slice, the elements of which are equal to the initial multidimensional index value. This is multidimensional analog of std.range.iota. For a flattened (continuous) index, see iotaSlice.Parameters:
N dimension count size_t[N] lengths
list of dimension lengths
Returns:N-dimensional slice composed of indexesSee Also:Examples:auto slice = indexSlice(2, 3); static immutable array = [[[0, 0], [0, 1], [0, 2]], [[1, 0], [1, 1], [1, 2]]]; assert(slice == array); static assert(is(IndexSlice!2 : Slice!(2, Range), Range)); static assert(is(DeepElementType!(IndexSlice!2) == size_t[2]));
Examples:auto im = indexSlice(7, 9); assert(im[2, 1] == [2, 1]); //slicing works correctly auto cm = im[1 .. $, 4 .. $]; assert(cm[2, 1] == [3, 5]);
- template
IndexSlice
(size_t N) if (N) - Slice composed of indexes.See Also:
- IotaSlice!N
iotaSlice
(size_t N)(size_t[N]lengths
...);
IotaSlice!NiotaSlice
(size_t N)(size_t[N]lengths
, size_tshift
);
IotaSlice!NiotaSlice
(size_t N)(size_t[N]lengths
, size_tshift
, size_tstep
); - Returns a slice, the elements of which are equal to the initial flattened index value. For a multidimensional index, see indexSlice.Parameters:
N dimension count size_t[N] lengths
list of dimension lengths
size_t shift
value of the first element in a slice (optional) size_t step
value of the step
between elements (optional)Returns:N-dimensional slice composed of indexesSee Also:Examples:auto slice = iotaSlice(2, 3); static immutable array = [[0, 1, 2], [3, 4, 5]]; assert(slice == array); import std.range.primitives : isRandomAccessRange; static assert(isRandomAccessRange!(IotaSlice!2)); static assert(is(IotaSlice!2 : Slice!(2, Range), Range)); static assert(is(DeepElementType!(IotaSlice!2) == size_t));
Examples:auto im = iotaSlice([10, 5], 100); assert(im[2, 1] == 111); // 100 + 2 * 5 + 1 //slicing works correctly auto cm = im[1 .. $, 3 .. $]; assert(cm[2, 1] == 119); // 119 = 100 + (1 + 2) * 5 + (3 + 1)
Examples:iotaSlice
withstep
auto sl = iotaSlice([2, 3], 10, 10); assert(sl == [[10, 20, 30], [40, 50, 60]]);
- template
IotaSlice
(size_t N) if (N) - Slice composed of flattened indexes.See Also:
- RepeatSlice!(M, T)
repeatSlice
(T, size_t M)(Tvalue
, size_t[M]lengths
...)
if (!is(T : Slice!(N, Range), size_t N, Range));
Slice!(M, Slice!(N + 1, Range))repeatSlice
(size_t N, Range, size_t M)(Slice!(N, Range)slice
, size_t[M]lengths
...); - Returns a
slice
with identical elements. RepeatSlice stores only singlevalue
.Parameters:size_t[M] lengths
list of dimension lengths
Returns:n-dimensionalslice
composed of identical values, where n is dimension count.See Also:Examples:auto sl = iotaSlice(3) .repeatSlice(4); assert(sl == [[0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2]]);
Examples:import std.experimental.ndslice.iteration : transposed; auto sl = iotaSlice(3) .repeatSlice(4) .unpack .transposed; assert(sl == [[0, 0, 0, 0], [1, 1, 1, 1], [2, 2, 2, 2]]);
Examples:import std.experimental.ndslice.slice : slice; auto sl = iotaSlice([3], 6).slice; auto slC = sl.repeatSlice(2, 3); sl[1] = 4; assert(slC == [[[6, 4, 8], [6, 4, 8], [6, 4, 8]], [[6, 4, 8], [6, 4, 8], [6, 4, 8]]]);
Examples:auto sl = repeatSlice(4.0, 2, 3); assert(sl == [[4.0, 4.0, 4.0], [4.0, 4.0, 4.0]]); static assert(is(DeepElementType!(typeof(sl)) == double)); sl[1, 1] = 3; assert(sl == [[3.0, 3.0, 3.0], [3.0, 3.0, 3.0]]);
- template
RepeatSlice
(size_t N, T) if (N) - Slice composed of identical values.
- template
mapSlice
(fun...) if (fun.length) - Implements the homonym function (also known as transform) present in many languages of functional flavor. The call
mapSlice
!(fun)(tensor) returns a tensor of which elements are obtained by applying fun for all elements in tensor. The original tensors are not changed. Evaluation is done lazily.Note: transposed and pack can be used to specify dimensions.
Parameters:fun One or more functions. Slice!(N, Range) tensor An input tensor. Returns:a tensor with each fun applied to all the elements. If there is more than one fun, the element type will be Tuple containing one element for each fun.Examples:import std.experimental.ndslice.selection : iotaSlice; auto s = iotaSlice(2, 3).mapSlice!(a => a * 3); assert(s == [[ 0, 3, 6], [ 9, 12, 15]]);
Examples:Packed tensors.import std.experimental.ndslice.selection : iotaSlice, windows; // iotaSlice windows mapSlice sums ( ndFold!"a + b" ) // -------------- // ------- | --- --- | ------ // | 0 1 2 | => || 0 1 || 1 2 || => | 8 12 | // | 3 4 5 | || 3 4 || 4 5 || ------ // ------- | --- --- | // -------------- auto s = iotaSlice(2, 3) .windows(2, 2) .mapSlice!((a) { size_t s; foreach (r; a) foreach (e; r) s += e; return s; }); assert(s == [[8, 12]]);
Examples:Zipped tensorsimport std.experimental.ndslice.slice : assumeSameStructure; import std.experimental.ndslice.selection : iotaSlice; // 0 1 2 // 3 4 5 auto sl1 = iotaSlice(2, 3); // 1 2 3 // 4 5 6 auto sl2 = iotaSlice([2, 3], 1); // tensors must have the same strides assert(sl1.structure == sl2.structure); auto zip = assumeSameStructure!("a", "b")(sl1, sl2); auto lazySum = zip.mapSlice!(z => z.a + z.b); assert(lazySum == [[ 1, 3, 5], [ 7, 9, 11]]);
Examples:Multiple functions can be passed tomapSlice
. In that case, the element type ofmapSlice
is a tuple containing one element for each function.import std.experimental.ndslice.selection : iotaSlice; auto s = iotaSlice(2, 3).mapSlice!("a + a", "a * a"); auto sums = [[0, 2, 4], [6, 8, 10]]; auto products = [[0, 1, 4], [9, 16, 25]]; foreach (i; 0..s.length!0) foreach (j; 0..s.length!1) { auto values = s[i, j]; assert(values[0] == sums[i][j]); assert(values[1] == products[i][j]); }
Examples:You may aliasmapSlice
with some function(s) to a symbol and use it separately:import std.conv : to; import std.experimental.ndslice.selection : iotaSlice; alias stringize = mapSlice!(to!string); assert(stringize(iotaSlice(2, 3)) == [["0", "1", "2"], ["3", "4", "5"]]);
- auto
mapSlice
(size_t N, Range)(Slice!(N, Range)tensor
);
Copyright © 1999-2017 by the D Language Foundation | Page generated by
Ddoc on (no date time)