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.stack

This is a submodule of mir.ndslice.
Authors:
Ilya Yaroshenko
Stack!(dim, Slices) stack(size_t dim = 0, Slices...)(Slices slices);
Creates a Stack view of multiple slices.
Can be used in combination with itself, until, allocation , and Slice  assignment. until pred returns true.
Returns:
true if an element was
Parameters:
Slices slices tuple of slices and stacks. All slices and stacks must have the same dimension count.
Returns:
Examples:
Multidimensional
import mir.ndslice.allocation: slice;
import mir.ndslice.topology: iota;

// 0, 1, 2
// 3, 4, 5
auto a = iota(2, 3);
// 0, 1
// 2, 3
auto b = iota(2, 2);
// 0, 1, 2, 3, 4
auto c = iota(1, 5);

// 0, 1, 2,   0, 1
// 3, 4, 5,   2, 3
// 
// 0, 1, 2, 3, 4
// construction phase
auto s = stack(stack!1(a, b), c);

// allocation phase
auto d = s.slice;
assert(d == [
    [0, 1, 2, 0, 1],
    [3, 4, 5, 2, 3],
    [0, 1, 2, 3, 4],
    ]);

// optimal fragmentation for output/writing/buffering
auto testData = [
    [0, 1, 2], [0, 1],
    [3, 4, 5], [2, 3],
    [0, 1, 2, 3, 4],
];
size_t i;
s.forEachFragment!((fragment) {
    pragma(inline, false); //reduces template bloat
    assert(fragment == testData[i++]);
    });
assert(i == testData.length);

// lazy ndslice view
assert(s.slicedNdField == d);
Examples:
1D
import mir.ndslice.allocation: slice;
import mir.ndslice.topology: iota;

size_t i;
auto a = 3.iota;
auto b = iota([6], a.length);
auto s = stack(a, b);
assert(s.length == a.length + b.length);
// fast iteration with until
s.until!((elem){ assert(elem == i++); return false; });
// allocation with slice
assert(s.slice == s.length.iota);
// 1D or multidimensional assignment
auto d = slice!double(s.length);
d[] = s;
assert(d == s.length.iota);
d[] += s;
assert(d == iota([s.length], 0, 2));

// lazy ndslice view
assert(s.slicedNdField == s.length.iota);
enum bool isStack(T);
enum size_t stackDimension(T : Stack!(dim, Slices), size_t dim, Slices...);
struct Stack(size_t dim, Slices...) if (Slices.length > 1);
Slices _slices;
Slices and sub-stacks
const @property size_t length(size_t d = 0)();
Length primitive
const @property size_t elementsCount()();
Total elements count in the stack.
const @property size_t[N] shape()();
Shape of the stack.
const @property bool empty(size_t d = 0)();

void popFront(size_t d = 0)();

auto front(size_t d = 0)();
Multidimensional input range primitives
auto opIndex(size_t[N] indexes...);
Simplest multidimensional random access primitive
auto pad(string direction = "both", S, T, size_t N)(S s, T value, size_t[N] lengths...)
if (hasShape!S && N == (typeof(S.shape)).length);
Multidimensional padding view.
Parameters:
direction padding direction. Direction can be one of the following values: "both", "pre", and "post".
S s Slice  or ndField
T value initial value for padding
size_t[N] lengths list of lengths
Returns:
See Also:
stack examples.
Examples:
import mir.ndslice.allocation: slice;
import mir.ndslice.topology: iota;

auto pad = iota([3], 1)
    .pad(0, [2])
    .slice;

assert(pad == [0, 0,  1, 2, 3,  0, 0]);
Examples:
import mir.ndslice.allocation: slice;
import mir.ndslice.topology: iota;

auto pad = iota([2, 2], 1)
    .pad(0, [2, 1])
    .slice;

assert(pad == [
    [0,  0, 0,  0],
    [0,  0, 0,  0],

    [0,  1, 2,  0],
    [0,  3, 4,  0],
    
    [0,  0, 0,  0],
    [0,  0, 0,  0]]);
template pad(size_t[] dimensions, string[] directions) if (dimensions.length && dimensions.length == directions.length)
Pads with a constant value.
Parameters:
dimensions dimensions to pad.
directions padding directions. Direction can be one of the following values: "both", "pre", and "post".
Returns:
See Also:
stack examples.
Examples:
import mir.ndslice.allocation: slice;
import mir.ndslice.topology: iota;

auto pad = iota([2, 2], 1)
    .pad!([1], ["pre"])(0, [2])
    .slice;

assert(pad == [
    [0, 0,  1, 2],
    [0, 0,  3, 4]]);
Examples:
import mir.ndslice.allocation: slice;
import mir.ndslice.topology: iota;

auto pad = iota([2, 2], 1)
    .pad!([0, 1], ["both", "post"])(0, [2, 1])
    .slice;

assert(pad == [
    [0, 0,  0],
    [0, 0,  0],

    [1, 2,  0],
    [3, 4,  0],
    
    [0, 0,  0],
    [0, 0,  0]]);
auto pad(S, T)(S s, T value, size_t[dimensions.length] lengths...);
Parameters:
S s Slice  or ndField
T value initial value for padding
size_t[dimensions.length] lengths list of lengths
Returns:
See Also:
stack examples.
auto padWrap(string direction = "both", SliceKind kind, size_t[] packs, Iterator, size_t N)(Slice!(kind, packs, Iterator) s, size_t[N] lengths...)
if (N == packs[0]);
Pads with the wrap of the slice along the axis. The first values are used to pad the end and the end values are used to pad the beginning.
Parameters:
direction padding direction. Direction can be one of the following values: "both", "pre", and "post".
Slice!(kind, packs, Iterator) s Slice 
size_t[N] lengths list of lengths for each dimension. Each length must be less or equal to the corresponding slice length.
Returns:
See Also:
stack examples.
Examples:
import mir.ndslice.allocation: slice;
import mir.ndslice.topology: iota;

auto pad = iota([3], 1)
    .padWrap([2])
    .slice;

assert(pad == [2, 3,  1, 2, 3,  1, 2]);
Examples:
import mir.ndslice.allocation: slice;
import mir.ndslice.topology: iota;

auto pad = iota([2, 2], 1)
    .padWrap([2, 1])
    .slice;

assert(pad == [
    [2,  1, 2,  1],
    [4,  3, 4,  3],

    [2,  1, 2,  1],
    [4,  3, 4,  3],

    [2,  1, 2,  1],
    [4,  3, 4,  3]]);
template padWrap(size_t[] dimensions, string[] directions) if (dimensions.length && dimensions.length == directions.length)
Pads with the wrap of the slice along the axis. The first values are used to pad the end and the end values are used to pad the beginning.
Parameters:
dimensions dimensions to pad.
directions padding directions. Direction can be one of the following values: "both", "pre", and "post".
Returns:
See Also:
stack examples.
Examples:
import mir.ndslice.allocation: slice;
import mir.ndslice.topology: iota;

auto pad = iota([2, 3], 1)
    .padWrap!([1], ["pre"])([1])
    .slice;

assert(pad == [
    [3,  1, 2, 3],
    [6,  4, 5, 6]]);
Examples:
import mir.ndslice.allocation: slice;
import mir.ndslice.topology: iota;

auto pad = iota([2, 2], 1)
    .padWrap!([0, 1], ["both", "post"])([2, 1])
    .slice;

assert(pad == [
    [1, 2,  1],
    [3, 4,  3],

    [1, 2,  1],
    [3, 4,  3],
    
    [1, 2,  1],
    [3, 4,  3]]);
auto padWrap(SliceKind kind, size_t[] packs, Iterator)(Slice!(kind, packs, Iterator) s, size_t[dimensions.length] lengths...);
Parameters:
Slice!(kind, packs, Iterator) s Slice 
size_t[dimensions.length] lengths list of lengths for each dimension. Each length must be less or equal to the corresponding slice length.
Returns:
See Also:
stack examples.
auto padSymmetric(string direction = "both", SliceKind kind, size_t[] packs, Iterator, size_t N)(Slice!(kind, packs, Iterator) s, size_t[N] lengths...)
if (N == packs[0]);
Pads with the reflection of the slice mirrored along the edge of the slice.
Parameters:
direction padding direction. Direction can be one of the following values: "both", "pre", and "post".
Slice!(kind, packs, Iterator) s Slice 
size_t[N] lengths list of lengths for each dimension. Each length must be less or equal to the corresponding slice length.
Returns:
See Also:
stack examples.
Examples:
import mir.ndslice.allocation: slice;
import mir.ndslice.topology: iota;

auto pad = iota([3], 1)
    .padSymmetric([2])
    .slice;

assert(pad == [2, 1,  1, 2, 3,  3, 2]);
Examples:
import mir.ndslice.allocation: slice;
import mir.ndslice.topology: iota;

auto pad = iota([2, 2], 1)
    .padSymmetric([2, 1])
    .slice;

assert(pad == [
    [3,  3, 4,  4],
    [1,  1, 2,  2],

    [1,  1, 2,  2],
    [3,  3, 4,  4],

    [3,  3, 4,  4],
    [1,  1, 2,  2]]);
template padSymmetric(size_t[] dimensions, string[] directions) if (dimensions.length && dimensions.length == directions.length)
Pads with the reflection of the slice mirrored along the edge of the slice.
Parameters:
dimensions dimensions to pad.
directions padding directions. Direction can be one of the following values: "both", "pre", and "post".
Returns:
See Also:
stack examples.
Examples:
import mir.ndslice.allocation: slice;
import mir.ndslice.topology: iota;

auto pad = iota([2, 3], 1)
    .padSymmetric!([1], ["pre"])([1])
    .slice;

assert(pad == [
    [1,  1, 2, 3],
    [4,  4, 5, 6]]);
Examples:
import mir.ndslice.allocation: slice;
import mir.ndslice.topology: iota;

auto pad = iota([2, 2], 1)
    .padSymmetric!([0, 1], ["both", "post"])([2, 1])
    .slice;

assert(pad == [
    [3, 4,  4],
    [1, 2,  2],

    [1, 2,  2],
    [3, 4,  4],
    
    [3, 4,  4],
    [1, 2,  2]]);
auto padSymmetric(SliceKind kind, size_t[] packs, Iterator)(Slice!(kind, packs, Iterator) s, size_t[dimensions.length] lengths...)
if (packs.length == 1);
Parameters:
Slice!(kind, packs, Iterator) s Slice 
size_t[dimensions.length] lengths list of lengths for each dimension. Each length must be less or equal to the corresponding slice length.
Returns:
See Also:
stack examples.
auto padEdge(string direction = "both", SliceKind kind, size_t[] packs, Iterator, size_t N)(Slice!(kind, packs, Iterator) s, size_t[N] lengths...)
if (N == packs[0]);
Pads with the edge values of slice.
Parameters:
direction padding direction. Direction can be one of the following values: "both", "pre", and "post".
Slice!(kind, packs, Iterator) s Slice 
size_t[N] lengths list of lengths for each dimension.
Returns:
See Also:
stack examples.
Examples:
import mir.ndslice.allocation: slice;
import mir.ndslice.topology: iota;

auto pad = iota([3], 1)
    .padEdge([2])
    .slice;

assert(pad == [1, 1,  1, 2, 3,  3, 3]);
Examples:
import mir.ndslice.allocation: slice;
import mir.ndslice.topology: iota;

auto pad = iota([2, 2], 1)
    .padEdge([2, 1])
    .slice;

assert(pad == [
    [1,  1, 2,  2],
    [1,  1, 2,  2],

    [1,  1, 2,  2],
    [3,  3, 4,  4],

    [3,  3, 4,  4],
    [3,  3, 4,  4]]);
template padEdge(size_t[] dimensions, string[] directions) if (dimensions.length && dimensions.length == directions.length)
Pads with the edge values of slice.
Parameters:
dimensions dimensions to pad.
directions padding directions. Direction can be one of the following values: "both", "pre", and "post".
Returns:
See Also:
stack examples.
Examples:
import mir.ndslice.allocation: slice;
import mir.ndslice.topology: iota;

auto pad = iota([2, 3], 1)
    .padEdge!([0], ["pre"])([2])
    .slice;

assert(pad == [
    [1, 2, 3],
    [1, 2, 3],
    
    [1, 2, 3],
    [4, 5, 6]]);
Examples:
import mir.ndslice.allocation: slice;
import mir.ndslice.topology: iota;

auto pad = iota([2, 2], 1)
    .padEdge!([0, 1], ["both", "post"])([2, 1])
    .slice;

assert(pad == [
    [1, 2,  2],
    [1, 2,  2],

    [1, 2,  2],
    [3, 4,  4],

    [3, 4,  4],
    [3, 4,  4]]);
auto padEdge(SliceKind kind, size_t[] packs, Iterator)(Slice!(kind, packs, Iterator) s, size_t[dimensions.length] lengths...);
Parameters:
Slice!(kind, packs, Iterator) s Slice 
size_t[dimensions.length] lengths list of lengths for each dimension.
Returns:
See Also:
stack examples.
template forEachFragment(alias pred)
Iterates 1D fragments in Slice  or Stack in optimal for buffering way.
See Also:
stack examples.
void forEachFragment(SliceKind kind, size_t[] packs, Iterator)(Slice!(kind, packs, Iterator) sl);
Specialization for slices
Parameters:
Slice!(kind, packs, Iterator) sl Slice 
void forEachFragment(size_t dim, Slices...)(Stack!(dim, Slices) st);
Specialization for stacks
Parameters:
Stack!(dim, Slices) st Stack
template until(alias pred)
Iterates elements in Slice  or Stack until pred returns true.
Returns:
false if pred returned false for all elements and true otherwise.
See Also:
stack examples.
bool until(SliceKind kind, size_t[] packs, Iterator)(Slice!(kind, packs, Iterator) sl);
Specialization for slices
Parameters:
Slice!(kind, packs, Iterator) sl Slice 
bool until(size_t dim, Slices...)(Stack!(dim, Slices) st);
Specialization for stacks
Parameters:
Stack!(dim, Slices) st Stack