mir_slice

Presents an n-dimensional view over a range.

Definitions

In order to change data in a slice using overloaded operators such as =, +=, ++, a syntactic structure of type <slice to change>[<index and interval sequence...>] must be used. It is worth noting that just like for regular arrays, operations a = b and a[] = b have different meanings. In the first case, after the operation is carried out, a simply points at the same data as b does, and the data which a previously pointed at remains unmodified. Here, а and b must be of the same type. In the second case, a points at the same data as before, but the data itself will be changed. In this instance, the number of dimensions of b may be less than the number of dimensions of а; and b can be a Slice, a regular multidimensional array, or simply a value (e.g. a number).

In the following table you will find the definitions you might come across in comments on operator overloading.

$(STD `2..$-3`, `0..4`)

$(STD `3`, `$-1`)

$(STD `[3]`, `[0..$]`, `[3, 3]`, `[0..$,0..3]`, `[0..$,2]`)

$(STD `[2,3,1]`)

$(STD `[]`, `[3..$,0..3,0..$-1]`, `[2,0..$,1]`)

$(STD `[anNdslice]`, `[$.iota, anNdsliceForCartesian1, $.iota]`)

Operator OverloadingExamples at N == 3
An interval is a part of a sequence of type i .. j.
An index is a part of a sequence of type i.
A partially defined slice is a sequence composed of intervals and indices with an overall length strictly less than N.
A fully defined index is a sequence composed only of indices with an overall length equal to N.
A fully defined slice is an empty sequence or a sequence composed of indices and at least one interval with an overall length equal to N.
An indexed slice is syntax sugar for indexed and cartesian.
  1. struct mir_slice(Iterator_, size_t N_ = 1, SliceKind kind_ = Contiguous, Labels_...)
    struct mir_slice (
    Iterator_
    size_t N_ = 1
    SliceKind kind_ = Contiguous
    Labels_...
    ) if (
    0 < N_ &&
    N_ < 255
    &&
    !(
    kind_ == Canonical &&
    N_ == 1
    )
    &&
    Labels_.length <= N_
    &&
    isIterator!Iterator_
    ) {}
  2. alias Slice = mir_slice

Alias This

toConst

ditto

Public Imports

mir.rc.array
public import mir.rc.array : mir_rci;

Members

Aliases

DeepElement
alias DeepElement = typeof(Iterator.init[size_t.init])

Data element type

Iterator
alias Iterator = Iterator_

Data iterator type

Labels
alias Labels = Labels_

Label Iterators types

This
alias This = Slice!(Iterator, N, kind)

This type

_Structure
alias _Structure = AliasSeq!(size_t[N], ptrdiff_t[S])
_Structure
alias _Structure = AliasSeq!(size_t[N])
_lengths
alias _lengths = _structure[0]
_lengths
alias _lengths = _structure[0]
_strides
alias _strides = _structure[1]
first
alias first = front
Undocumented in source.
last
alias last = back
Undocumented in source.
opDollar
alias opDollar = length
Undocumented in source.
popBackAll
alias popBackAll = popBack
Undocumented in source.
popFrontAll
alias popFrontAll = popFront
Undocumented in source.
ptr
alias ptr = iterator

ptr alias is available only if the slice kind is Contiguous contiguous and the .Slice.iterator is a pointers.

serdeKeysProxy
alias serdeKeysProxy = DeepElement

Enums

PureIndexLength
eponymoustemplate PureIndexLength(Slices...)
Undocumented in source.
isFullPureSlice
eponymoustemplate isFullPureSlice(Slices...)
Undocumented in source.
isIndexedSlice
eponymoustemplate isIndexedSlice(Slices...)
Undocumented in source.
isPureSlice
eponymoustemplate isPureSlice(Slices...)
Undocumented in source.

Functions

_stride
sizediff_t _stride()

Multidimensional stride property.

accessFlat
auto ref accessFlat(size_t index)

Provides access to a slice as if it were flattened.

anyEmpty
bool anyEmpty()
back
Element!dimension back()

Multidimensional input range primitive.

back
Element!dimension back()
Undocumented in source. Be warned that the author may not have intended to support it.
back
auto ref back(T value)

Multidimensional input range primitive.

backIndex
sizediff_t backIndex()
Undocumented in source. Be warned that the author may not have intended to support it.
backward
auto ref backward(size_t[N] index)

Convenience function for backward indexing.

dup
Slice!(immutable(DeepElement)*, N) dup()

Duplicates slice.

dup
Slice!(Unqual!DeepElement*, N) dup()

Duplicates slice.

elementCount
size_t elementCount()
empty
bool empty()

Multidimensional input range primitive.

field
auto field()

Field (array) data.

first
auto ref first()
auto ref first(T value)

Accesses the first deep element of the slice.

front
auto ref front(T value)
auto ref front()
Element!dimension front()
auto front()

Multidimensional input range primitive.

idup
Slice!(immutable(DeepElement)*, N) idup()

Duplicates slice.

idup
Slice!(immutable(DeepElement)*, N) idup()

Duplicates slice.

indexStride
size_t indexStride(size_t[I] _indices)
Undocumented in source. Be warned that the author may not have intended to support it.
iterator
auto iterator()

Iterator

label
Slice!(Labels[d]) label()
void label(Slice!(Labels[d]) rhs)
Slice!(LightConstOf!(Labels[d])) label()
Slice!(LightImmutableOf!(Labels[d])) label()

Label for the dimensions 'd'. By default returns the row label.

last
auto ref last()
auto ref last(T value)

Accesses the last deep element of the slice.

lastIndex
ptrdiff_t lastIndex()
Undocumented in source. Be warned that the author may not have intended to support it.
length
size_t length()

Multidimensional length property.

lightConst
Slice!(LightConstOf!Iterator, N, kind, staticMap!(LightConstOf, Labels)) lightConst()
Slice!(LightImmutableOf!Iterator, N, kind, staticMap!(LightImmutableOf, Labels)) lightConst()
lightImmutable
Slice!(LightImmutableOf!Iterator, N, kind, staticMap!(LightImmutableOf, Labels)) lightImmutable()
lightScope
auto lightScope()
opBinary
auto opBinary(Slice!(RIterator, RN, rkind) rhs)

Element-wise operator overloading for slices.

opBinary
auto opBinary(T value)
opBinaryRight
auto opBinaryRight(T value)

Element-wise operator overloading for scalars.

opEquals
bool opEquals(Slice!(IteratorR, N, rkind) rslice)
bool opEquals(const(T)[] arr)

Select the last n elements for the dimension.

opIndex
auto ref opIndex(Indexes indices)

opIndex overload for const slice

opIndex
auto ref opIndex(Indexes indices)

opIndex overload for immutable slice

opIndex
auto opIndex(Slices slices)

$(BOLD Indexed slice.)

opIndex
auto opIndex(Slices slices)

$(BOLD Partially or fully defined slice.)

opIndex
auto opIndex(size_t[I] _indices)

$(BOLD Partially defined index)

opIndex
auto opIndex(size_t[I] _indices)

$(BOLD Partially defined index)

opIndex
auto ref opIndex(size_t[N] _indices)

$(BOLD Fully defined index)

opIndex
auto ref opIndex(size_t[N] _indices)

$(BOLD Fully defined index)

opIndexAssign
auto ref opIndexAssign(DeepElement value, size_t[N] _indices)

Assignment of a value (e.g. a number) to a fully defined index.

opIndexAssign
auto ref opIndexAssign(T value, size_t[N] _indices)

Assignment of a value (e.g. a number) to a fully defined index.

opIndexAssign
void opIndexAssign(DeepElement value, Slices slices)
Undocumented in source. Be warned that the author may not have intended to support it.
opIndexAssign
void opIndexAssign(T value, Slices slices)

Assignment of a value (e.g. a number) to a fully defined slice.

opIndexAssign
void opIndexAssign(T concatenation, Slices slices)
opIndexAssign
void opIndexAssign(T[] value, Slices slices)

Assignment of a regular multidimensional array to a fully defined slice.

opIndexAssign
void opIndexAssign(Slice!(RIterator, RN, rkind) value, Slices slices)

Assignment of a value of Slice type to a fully defined slice.

opIndexOpAssign
void opIndexOpAssign(T concatenation, Slices slices)
opIndexOpAssign
void opIndexOpAssign(T value, Slices slices)

Op Assignment op= of a value (e.g. a number) to a fully defined slice.

opIndexOpAssign
void opIndexOpAssign(T[] value, Slices slices)

Op Assignment op= of a regular multidimensional array to a fully defined slice.

opIndexOpAssign
void opIndexOpAssign(Slice!(RIterator, RN, rkind) value, Slices slices)

Op Assignment op= of a value of Slice type to a fully defined slice.

opIndexOpAssign
auto ref opIndexOpAssign(T value, size_t[N] _indices)

Op Assignment op= of a value (e.g. a number) to a fully defined index.

opIndexOpAssignImplArray
void opIndexOpAssignImplArray(T[] value)
Undocumented in source. Be warned that the author may not have intended to support it.
opIndexUnary
auto ref opIndexUnary(size_t[N] _indices)

Increment ++ and Decrement -- operators for a fully defined index.

opIndexUnary
void opIndexUnary(Slices slices)

Increment ++ and Decrement -- operators for a fully defined slice.

opSlice
Slice!(IotaIterator!size_t) opSlice(size_t i, size_t j)

Slice!(IotaIterator!size_t) is the basic type for [a .. b] syntax for all ndslice based code.

opUnary
auto opUnary()

Element-wise binary operator overloading.

popBack
void popBack()

Multidimensional input range primitive.

popBackAll
void popBackAll()

Peforms popBackAll for all dimensions

popBackExactly
void popBackExactly(size_t n)
popBackN
void popBackN(size_t n)
popFront
void popFront()

Multidimensional input range primitive.

popFrontAll
void popFrontAll()

Peforms popFrontAll for all dimensions

popFrontExactly
void popFrontExactly(size_t n)
popFrontN
void popFrontN(size_t n)

Multidimensional input range primitive.

ptr
auto ptr()
Undocumented in source. Be warned that the author may not have intended to support it.
save
auto save()

Save primitive.

select
auto select(size_t begin, size_t end)

Slice selected dimension.

selectBack
auto selectBack(size_t n)

Select the last n elements for the dimension.

selectFront
auto selectFront(size_t n)

Select the first n elements for the dimension.

shape
size_t[N] shape()
strides
ptrdiff_t[N] strides()
structure
Structure!N structure()
toConst
auto toConst()

Cast to const and immutable slices in case of underlying range is a pointer.

toImmutable
auto toImmutable()

Cast to const and immutable slices in case of underlying range is a pointer.

values
auto values()

Strips label off the DataFrame

values
auto values()

Strips label off the DataFrame

Manifest constants

doUnittest
enum doUnittest;
Undocumented in source.
hasAccessByRef
enum hasAccessByRef;
Undocumented in source.

Templates

Element
template Element(size_t dimension)

Variables

L
enum size_t L;

Labels count.

N
enum size_t N;

Dimensions count

S
enum size_t S;

Strides count

_iterator
Iterator _iterator;

Data Iterator

_labels
Labels _labels;

Labels iterators

_strides
enum ptrdiff_t[S] _strides;
_structure
_Structure _structure;
_structure
_Structure _structure;
kind
enum SliceKind kind;

SliceKind

Examples

Slicing, indexing, and arithmetic operations.

import mir.ndslice.allocation;
import mir.ndslice.dynamic : transposed;
import mir.ndslice.topology : iota, universal;
auto tensor = iota(3, 4, 5).slice;

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

assert( tensor[0..$, 0..$, 4] == tensor.universal.transposed!2[4]);
assert(&tensor[0..$, 0..$, 4][1, 2] is &tensor[1, 2, 4]);

tensor[1, 2, 3]++; //`opIndex` returns value by reference.
--tensor[1, 2, 3]; //`opUnary`

++tensor[];
tensor[] -= 1;

// `opIndexAssing` accepts only fully defined indices and slices.
// Use an additional empty slice `[]`.
static assert(!__traits(compiles, tensor[0 .. 2] *= 2));

tensor[0 .. 2][] *= 2;          //OK, empty slice
tensor[0 .. 2, 3, 0..$] /= 2; //OK, 3 index or slice positions are defined.

//fully defined index may be replaced by a static array
size_t[3] index = [1, 2, 3];
assert(tensor[index] == tensor[1, 2, 3]);

Operations with rvalue slices.

import mir.ndslice.allocation;
import mir.ndslice.topology: universal;
import mir.ndslice.dynamic: transposed, everted;

auto tensor = slice!int(3, 4, 5).universal;
auto matrix = slice!int(3, 4).universal;
auto vector = slice!int(3);

foreach (i; 0..3)
    vector[i] = i;

// fills matrix columns
matrix.transposed[] = vector;

// fills tensor with vector
// transposed tensor shape is (4, 5, 3)
//            vector shape is (      3)
tensor.transposed!(1, 2)[] = vector;

// transposed tensor shape is (5, 3, 4)
//            matrix shape is (   3, 4)
tensor.transposed!2[] += matrix;

// transposed tensor shape is (5, 4, 3)
// transposed matrix shape is (   4, 3)
tensor.everted[] ^= matrix.transposed; // XOR

Creating a slice from text. See also std.format.

import mir.algorithm.iteration: filter, all;
import mir.array.allocation;
import mir.exception;
import mir.functional: not;
import mir.ndslice.allocation;
import mir.parse;
import mir.primitives: empty;

import std.algorithm: map;
import std.string: lineSplitter, split;

    // std.functional, std.string, std.range;

Slice!(int*, 2) toMatrix(string str)
{
    string[][] data = str.lineSplitter.filter!(not!empty).map!split.array;

    size_t rows    = data   .length.enforce!"empty input";
    size_t columns = data[0].length.enforce!"empty first row";

    data.all!(a => a.length == columns).enforce!"rows have different lengths";
    auto slice = slice!int(rows, columns);
    foreach (i, line; data)
        foreach (j, num; line)
            slice[i, j] = num.fromString!int;
    return slice;
}

auto input = "\r1 2  3\r\n 4 5 6\n";

auto matrix = toMatrix(input);
assert(matrix == [[1, 2, 3], [4, 5, 6]]);

// back to text
import std.format;
auto text2 = format("%(%(%s %)\n%)\n", matrix);
assert(text2 == "1 2 3\n4 5 6\n");

See Also

iota.

Internal Binary Representation

Multidimensional Slice is a structure that consists of lengths, strides, and a iterator (pointer).

FieldIterator shell is used to wrap fields and random access ranges. FieldIterator contains a shift of the current initial element of a multidimensional slice and the field itself.

With the exception of mir.ndslice.allocation module, no functions in this package move or copy data. The operations are only carried out on lengths, strides, and pointers. If a slice is defined over a range, only the shift of the initial element changes instead of the range.

Mir n-dimensional Slices can be one of the three kinds.

Contiguous slice

Contiguous in memory (or in a user-defined iterator's field) row-major tensor that doesn't store strides because they can be computed on the fly using lengths. The row stride is always equaled 1.

Canonical slice

Canonical slice as contiguous in memory (or in a user-defined iterator's field) rows of a row-major tensor, it doesn't store the stride for row dimension because it is always equaled 1. BLAS/LAPACK matrices are Canonical but originally have column-major order. In the same time you can use 2D Canonical Slices with LAPACK assuming that rows are columns and columns are rows.

Universal slice

A row-major tensor that stores the strides for all dimensions. NumPy strides are Universal.

Internal Representation for Universal Slices

Type definition

Slice!(Iterator, N, Universal)

Schema

Slice!(Iterator, N, Universal)
    size_t[N]     _lengths
    sizediff_t[N] _strides
    Iterator      _iterator
Example

Definitions

import mir.ndslice;
auto a = new double[24];
Slice!(double*, 3, Universal) s = a.sliced(2, 3, 4).universal;
Slice!(double*, 3, Universal) t = s.transposed!(1, 2, 0);
Slice!(double*, 3, Universal) r = t.reversed!1;

Representation

s________________________
    lengths[0] ::=  2
    lengths[1] ::=  3
    lengths[2] ::=  4

    strides[0] ::= 12
    strides[1] ::=  4
    strides[2] ::=  1

    iterator        ::= &a[0]

t____transposed!(1, 2, 0)
    lengths[0] ::=  3
    lengths[1] ::=  4
    lengths[2] ::=  2

    strides[0] ::=  4
    strides[1] ::=  1
    strides[2] ::= 12

    iterator        ::= &a[0]

r______________reversed!1
    lengths[0] ::=  2
    lengths[1] ::=  3
    lengths[2] ::=  4

    strides[0] ::= 12
    strides[1] ::= -4
    strides[2] ::=  1

    iterator        ::= &a[8] // (old_strides[1] * (lengths[1] - 1)) = 8

Internal Representation for Canonical Slices

Type definition

Slice!(Iterator, N, Canonical)

Schema

Slice!(Iterator, N, Canonical)
    size_t[N]       _lengths
    sizediff_t[N-1] _strides
    Iterator        _iterator

Internal Representation for Contiguous Slices

Type definition

Slice!(Iterator, N)

Schema

Slice!(Iterator, N, Contiguous)
    size_t[N]     _lengths
    sizediff_t[0] _strides
    Iterator      _iterator

Meta