ditto
Data element type
Data iterator type
Label Iterators types
This type
ptr alias is available only if the slice kind is Contiguous contiguous and the .Slice.iterator is a pointers.
Multidimensional stride property.
Provides access to a slice as if it were flattened.
Multidimensional input range primitive.
Multidimensional input range primitive.
Convenience function for backward indexing.
Duplicates slice.
Duplicates slice.
Multidimensional input range primitive.
Field (array) data.
Accesses the first deep element of the slice.
Multidimensional input range primitive.
Duplicates slice.
Duplicates slice.
Iterator
Label for the dimensions 'd'. By default returns the row label.
Accesses the last deep element of the slice.
Multidimensional length property.
Element-wise operator overloading for slices.
Element-wise operator overloading for scalars.
Select the last n elements for the dimension.
opIndex overload for const slice
opIndex overload for immutable slice
$(BOLD Indexed slice.)
$(BOLD Partially or fully defined slice.)
$(BOLD Partially defined index)
$(BOLD Partially defined index)
$(BOLD Fully defined index)
$(BOLD Fully defined index)
Assignment of a value (e.g. a number) to a fully defined index.
Assignment of a value (e.g. a number) to a fully defined index.
Assignment of a value (e.g. a number) to a fully defined slice.
Assignment of a regular multidimensional array to a fully defined slice.
Assignment of a value of Slice type to a fully defined slice.
Op Assignment op= of a value (e.g. a number) to a fully defined slice.
Op Assignment op= of a regular multidimensional array to a fully defined slice.
Op Assignment op= of a value of Slice type to a fully defined slice.
Op Assignment op= of a value (e.g. a number) to a fully defined index.
Increment ++ and Decrement -- operators for a fully defined index.
Increment ++ and Decrement -- operators for a fully defined slice.
Slice!(IotaIterator!size_t) is the basic type for [a .. b] syntax for all ndslice based code.
Element-wise binary operator overloading.
Multidimensional input range primitive.
Peforms popBackAll for all dimensions
Multidimensional input range primitive.
Peforms popFrontAll for all dimensions
Multidimensional input range primitive.
Save primitive.
Slice selected dimension.
Select the last n elements for the dimension.
Select the first n elements for the dimension.
Cast to const and immutable slices in case of underlying range is a pointer.
Cast to const and immutable slices in case of underlying range is a pointer.
Strips label off the DataFrame
Strips label off the DataFrame
Labels count.
Dimensions count
Strides count
Data Iterator
Labels iterators
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");
iota.
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 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 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.
A row-major tensor that stores the strides for all dimensions. NumPy strides are Universal.
Type definition
Slice!(Iterator, N, Universal)
Schema
Slice!(Iterator, N, Universal) size_t[N] _lengths sizediff_t[N] _strides Iterator _iterator
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
Type definition
Slice!(Iterator, N, Canonical)
Schema
Slice!(Iterator, N, Canonical) size_t[N] _lengths sizediff_t[N-1] _strides Iterator _iterator
Type definition
Slice!(Iterator, N)
Schema
Slice!(Iterator, N, Contiguous) size_t[N] _lengths sizediff_t[0] _strides Iterator _iterator
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]`)