std.experimental.ndslice.iteration - D Programming Language

D Programming Language
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 local clone.

# std.experimental.ndslice.iteration

This is a submodule of std.experimental.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 | Descriprottion
--- | ---
transposed | 100000.iota.sliced(3, 4, 5, 6, 7).transposed!(4, 0, 1).shape returns [7, 3, 4, 5, 6].
swapped | 1000.iota.sliced(3, 4, 5).swapped!(1, 2).shape returns [3, 5, 4].
everted | 1000.iota.sliced(3, 4, 5).everted.shape returns [5, 4, 3].

See also evertPack .

## Iteration operators

Function Name | Description
--- | ---
strided | 1000.iota.sliced(13, 40).strided!(0, 1)(2, 5).shape equals to [7, 8].
reversed | slice.reversed!0 returns the slice with reversed direction of iteration for top level dimension.
allReversed | 20.iota.sliced(4, 5).allReversed equals to 20.iota.retro.sliced(4, 5).

## Other operators

Function Name | Description
--- | ---
rotated | 10.iota.sliced(2, 3).rotated equals to [[2, 5], [1, 4], [0, 3]].

#### Drop operators

dropToHypercube drop dropBack dropOne dropBackOne dropExactly dropBackExactly allDrop allDropBack allDropOne allDropBackOne allDropExactly allDropBackExactly

    DropOperatorName:
        dropToHypercube
        DropRoot
        DropRoot DropSuffix
        DropRoot Back
        DropRoot Back DropSuffix
    DropRoot:
        drop
        allDrop
    DropSuffix:
        One
        Exactly

## 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.
License:
Boost License 1.0.
Authors:
Ilya Yaroshenko

Source: std/experimental/ndslice/iteration.d

template swapped(size_t dimensionA, size_t dimensionB)
Slice!(N, Range) swapped(size_t N, Range)(Slice!(N, Range) slice, size_t dimensionA, size_t dimensionB);
Slice!(2, Range) swapped(Range)(Slice!(2, Range) slice);
  Swaps two dimensions.
  Parameters:

  Slice!(N, Range) slice | input slice
  size_t dimensionA | first dimension
  size_t dimensionB | second dimension

  Returns:
  n-dimensional slice of the same type
  See Also:
  everted, transposed
  Examples:
  Template

      import std.experimental.ndslice.slice;
      import std.range: iota;
      assert(10000.iota
          .sliced(3, 4, 5, 6)
          .swapped!(3, 1)
          .shape == cast(size_t[4])[3, 6, 5, 4]);

  Examples:
  Function

      import std.experimental.ndslice.slice;
      import std.range: iota;
      assert(10000.iota
          .sliced(3, 4, 5, 6)
          .swapped(1, 3)
          .shape == cast(size_t[4])[3, 6, 5, 4]);

  Examples:
  2D

      import std.experimental.ndslice.slice;
      import std.range: iota;
      assert(10000.iota
          .sliced(3, 4)
          .swapped
          .shape == cast(size_t[2])[4, 3]);

template rotated(size_t dimensionA, size_t dimensionB)
Slice!(N, Range) rotated(size_t N, Range)(Slice!(N, Range) slice, size_t dimensionA, size_t dimensionB, sizediff_t k = 1);
Slice!(2, Range) rotated(Range)(Slice!(2, Range) 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!(N, Range) 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:
  Template

      import std.experimental.ndslice.slice;
      import std.range: iota;
      auto slice = 10.iota.sliced(2, 3);

      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!(N, Range) everted(size_t N, Range)(auto ref Slice!(N, Range) slice);
  Reverses the order of dimensions.
  Parameters:

  Slice!(N, Range) slice | input slice

  Returns:
  n-dimensional slice of the same type
  See Also:
  swapped, transposed
  Examples:

      import std.experimental.ndslice.slice;
      import std.range: iota;
      assert(1000.iota
          .sliced(3, 4, 5)
          .everted
          .shape == cast(size_t[3])[5, 4, 3]);

template transposed(Dimensions...) if (Dimensions.length)
Slice!(N, Range) transposed(size_t N, Range)(auto ref Slice!(N, Range) slice, size_t dimension);
Slice!(N, Range) transposed(size_t N, Range)(auto ref Slice!(N, Range) slice, in size_t[] dimensions...);
Slice!(2, Range) transposed(Range)(auto ref Slice!(2, Range) slice);
  N-dimensional transpose operator. Brings selected dimensions to the first position.
  Parameters:

  Slice!(N, Range) slice | input slice
  Dimensions | indexes of dimensions to be brought to the first position
  size_t[] dimensions | indexes of dimensions to be brought to the first position
  size_t dimension | index of dimension to be brought to the first position

  Returns:
  n-dimensional slice of the same type
  See Also:
  swapped, everted
  Examples:
  Template

      import std.experimental.ndslice.slice;
      import std.range: iota;
      assert(100000.iota
          .sliced(3, 4, 5, 6, 7)
          .transposed!(4, 1, 0)
          .shape == cast(size_t[5])[7, 4, 3, 5, 6]);

  Examples:
  Function

      import std.experimental.ndslice.slice;
      import std.range: iota;
      assert(100000.iota
          .sliced(3, 4, 5, 6, 7)
          .transposed(4, 1, 0)
          .shape == cast(size_t[5])[7, 4, 3, 5, 6]);

  Examples:
  Single-argument function

      import std.experimental.ndslice.slice;
      import std.range: iota;
      assert(100000.iota
          .sliced(3, 4, 5, 6, 7)
          .transposed(4)
          .shape == cast(size_t[5])[7, 3, 4, 5, 6]);

  Examples:
  2-dimensional transpose

      import std.experimental.ndslice.slice;
      import std.range: iota;
      assert(100.iota
          .sliced(3, 4)
          .transposed
          .shape == cast(size_t[2])[4, 3]);

Slice!(N, Range) allReversed(size_t N, Range)(Slice!(N, Range) slice);
  Reverses the direction of iteration for all dimensions.
  Parameters:

  Slice!(N, Range) slice | input slice

  Returns:
  n-dimensional slice of the same type
  Examples:

      import std.experimental.ndslice.slice;
      import std.range: iota, retro;
      auto a = 20.iota.sliced(4, 5).allReversed;
      auto b = 20.iota.retro.sliced(4, 5);
      assert(a == b);

template reversed(Dimensions...) if (Dimensions.length)
Slice!(N, Range) reversed(size_t N, Range)(Slice!(N, Range) slice, size_t dimension);
Slice!(N, Range) reversed(size_t N, Range)(Slice!(N, Range) slice, in size_t[] dimensions...);
  Reverses the direction of iteration for selected dimensions.
  Parameters:

  Slice!(N, Range) slice | input slice
  Dimensions | indexes of dimensions to reverse order of iteration
  size_t[] dimensions | indexes of dimensions to reverse order of iteration
  size_t dimension | index of dimension to reverse order of iteration

  Returns:
  n-dimensional slice of the same type
  Examples:

      import std.experimental.ndslice.slice;
      auto slice = [1, 2, 3, 4].sliced(2, 2);
      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]]);

template strided(Dimensions...) if (Dimensions.length)
Slice!(N, Range) strided(size_t N, Range)(Slice!(N, Range) slice, size_t dimension, size_t factor);
  Multiplies the stride of the selected dimension by the factor.
  Parameters:

  Slice!(N, Range) slice | input slice
  Dimensions | indexes of dimensions to be strided
  dimensions | indexes of dimensions to be strided
  factors | list of step extension factors
  size_t factor | step extension factors

  Returns:
  n-dimensional slice of the same type
  Examples:

      import std.experimental.ndslice.slice;
      auto slice
           = [0,1,2,3,    4,5,6,7,   8,9,10,11].sliced(3, 4);

      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 std.range: iota;
      static assert(1000.iota.sliced(13, 40).strided!(0, 1)(2, 5).shape == [7, 8]);
      static assert(100.iota.sliced(93).strided!(0, 0)(7, 3).shape == [5]);

Slice!(N, Range) allDropOne(size_t N, Range)(Slice!(N, Range) slice);
Slice!(N, Range) allDropBackOne(size_t N, Range)(Slice!(N, Range) slice);
  Convenience function which calls slice.popFront!dimension() for each dimension and returns the slice.
  allDropBackOne provides the same functionality but calls slice.popBack!dimension() instead.
  Parameters:

  Slice!(N, Range) slice | input slice

  Returns:
  n-dimensional slice of the same type
  Examples:

      import std.experimental.ndslice.slice;
      import std.range: iota, retro;
      auto a = 20.iota.sliced(4, 5);

      assert(a.allDropOne[0, 0] == 6);
      assert(a.allDropOne.shape == cast(size_t[2])[3, 4]);
      assert(a.allDropBackOne[$ - 1, $ - 1] == 13);
      assert(a.allDropBackOne.shape == cast(size_t[2])[3, 4]);

Slice!(N, Range) allDropExactly(size_t N, Range)(Slice!(N, Range) slice, size_t n);
Slice!(N, Range) allDropBackExactly(size_t N, Range)(Slice!(N, Range) slice, size_t n);
  These functions are similar to allDrop and allDropBack but they call slice.popFrontExactly!dimension(n) and slice.popBackExactly!dimension(n) instead.

  Note: Unlike allDrop, allDropExactly(n) assume that the slice holds a multi-dimensional cube with a size of at least n. This makes allDropExactly faster than allDrop. Only use allDropExactly when it is guaranteed that the slice holds a multi-dimensional cube with a size of at least n.

  Parameters:

  Slice!(N, Range) slice | input slice
  size_t n | number of elements to drop

  Returns:
  n-dimensional slice of the same type
  Examples:

      import std.experimental.ndslice.slice;
      import std.range: iota, retro;
      auto a = 20.iota.sliced(4, 5);

      assert(a.allDropExactly(2)[0, 0] == 12);
      assert(a.allDropExactly(2).shape == cast(size_t[2])[2, 3]);
      assert(a.allDropBackExactly(2)[$ - 1, $ - 1] == 7);
      assert(a.allDropBackExactly(2).shape == cast(size_t[2])[2, 3]);

Slice!(N, Range) allDrop(size_t N, Range)(Slice!(N, Range) slice, size_t n);
Slice!(N, Range) allDropBack(size_t N, Range)(Slice!(N, Range) slice, size_t n);
  Convenience function which calls slice.popFrontN!dimension(n) for each dimension and returns the slice.
  allDropBack provides the same functionality but calls slice.popBackN!dimension(n) instead.

  Note: allDrop and allDropBack remove up to n elements and stop when the slice is empty.

  Parameters:

  Slice!(N, Range) slice | input slice
  size_t n | number of elements to drop

  Returns:
  n-dimensional slice of the same type
  Examples:

      import std.experimental.ndslice.slice;
      import std.range: iota, retro;
      auto a = 20.iota.sliced(4, 5);

      assert(a.allDrop(2)[0, 0] == 12);
      assert(a.allDrop(2).shape == cast(size_t[2])[2, 3]);
      assert(a.allDropBack(2)[$ - 1, $ - 1] == 7);
      assert(a.allDropBack(2).shape == cast(size_t[2])[2, 3]);

      assert(a.allDrop    (5).shape == cast(size_t[2])[0, 0]);
      assert(a.allDropBack(5).shape == cast(size_t[2])[0, 0]);

template dropOne(Dimensions...) if (Dimensions.length)
Slice!(N, Range) dropOne(size_t N, Range)(Slice!(N, Range) slice, size_t dimension);
Slice!(N, Range) dropOne(size_t N, Range)(Slice!(N, Range) slice, in size_t[] dimensions...);
template dropBackOne(Dimensions...) if (Dimensions.length)
Slice!(N, Range) dropBackOne(size_t N, Range)(Slice!(N, Range) slice, size_t dimension);
Slice!(N, Range) dropBackOne(size_t N, Range)(Slice!(N, Range) slice, in size_t[] dimensions...);
  Convenience function which calls slice.popFront!dimension() for selected dimensions and returns the slice.
  dropBackOne provides the same functionality but calls slice.popBack!dimension() instead.
  Parameters:

  Slice!(N, Range) slice | input slice

  Returns:
  n-dimensional slice of the same type
  Examples:

      import std.experimental.ndslice.slice;
      import std.range: iota, retro;
      auto a = 20.iota.sliced(4, 5);

      assert(a.dropOne!(1, 0)[0, 0] == 6);
      assert(a.dropOne (1, 0)[0, 0] == 6);
      assert(a.dropOne!(1, 0).shape == cast(size_t[2])[3, 4]);
      assert(a.dropOne (1, 0).shape == cast(size_t[2])[3, 4]);
      assert(a.dropBackOne!(1, 0)[$ - 1, $ - 1] == 13);
      assert(a.dropBackOne (1, 0)[$ - 1, $ - 1] == 13);
      assert(a.dropBackOne!(1, 0).shape == cast(size_t[2])[3, 4]);
      assert(a.dropBackOne (1, 0).shape == cast(size_t[2])[3, 4]);

      assert(a.dropOne!(0, 0)[0, 0] == 10);
      assert(a.dropOne (0, 0)[0, 0] == 10);
      assert(a.dropOne!(0, 0).shape == cast(size_t[2])[2, 5]);
      assert(a.dropOne (0, 0).shape == cast(size_t[2])[2, 5]);
      assert(a.dropBackOne!(1, 1)[$ - 1, $ - 1] == 17);
      assert(a.dropBackOne (1, 1)[$ - 1, $ - 1] == 17);
      assert(a.dropBackOne!(1, 1).shape == cast(size_t[2])[4, 3]);
      assert(a.dropBackOne (1, 1).shape == cast(size_t[2])[4, 3]);

template dropExactly(Dimensions...) if (Dimensions.length)
Slice!(N, Range) dropExactly(size_t N, Range)(Slice!(N, Range) slice, size_t dimension, size_t n);
template dropBackExactly(Dimensions...) if (Dimensions.length)
Slice!(N, Range) dropBackExactly(size_t N, Range)(Slice!(N, Range) slice, size_t dimension, size_t n);
  These functions are similar to drop and dropBack but they call slice.popFrontExactly!dimension(n) and slice.popBackExactly!dimension(n) instead.

  Note: Unlike drop, dropExactly assumes that the slice holds enough elements in the selected dimension. This makes dropExactly faster than drop.

  Parameters:

  Slice!(N, Range) slice | input slice
  ns | list of numbers of elements to drop
  size_t n | number of elements to drop

  Returns:
  n-dimensional slice of the same type
  Examples:

      import std.experimental.ndslice.slice;
      import std.range: iota, retro;
      auto a = 20.iota.sliced(4, 5);

      assert(a.dropExactly    !(1, 0)(2, 3)[0, 0] == 17);
      assert(a.dropExactly    !(1, 0)(2, 3).shape == cast(size_t[2])[1, 3]);
      assert(a.dropBackExactly!(0, 1)(2, 3)[$ - 1, $ - 1] == 6);
      assert(a.dropBackExactly!(0, 1)(2, 3).shape == cast(size_t[2])[2, 2]);

      assert(a.dropExactly(1, 2).dropExactly(0, 3)[0, 0] == 17);
      assert(a.dropExactly(1, 2).dropExactly(0, 3).shape == cast(size_t[2])[1, 3]);
      assert(a.dropBackExactly(0, 2).dropBackExactly(1, 3)[$ - 1, $ - 1] == 6);
      assert(a.dropBackExactly(0, 2).dropBackExactly(1, 3).shape == cast(size_t[2])[2, 2]);

template drop(Dimensions...) if (Dimensions.length)
Slice!(N, Range) drop(size_t N, Range)(Slice!(N, Range) slice, size_t dimension, size_t n);
template dropBack(Dimensions...) if (Dimensions.length)
Slice!(N, Range) dropBack(size_t N, Range)(Slice!(N, Range) slice, size_t dimension, size_t n);
  Convenience function which calls slice.popFrontN!dimension(n) for the selected dimension and returns the slice.
  dropBack provides the same functionality but calls slice.popBackN!dimension(n) instead.

  Note: drop and dropBack remove up to n elements and stop when the slice is empty.

  Parameters:

  Slice!(N, Range) slice | input slice
  ns | list of numbers of elements to drop
  size_t n | number of elements to drop

  Returns:
  n-dimensional slice of the same type
  Examples:

      import std.experimental.ndslice.slice;
      import std.range: iota, retro;
      auto a = 20.iota.sliced(4, 5);

      assert(a.drop    !(1, 0)(2, 3)[0, 0] == 17);
      assert(a.drop    !(1, 0)(2, 3).shape == cast(size_t[2])[1, 3]);
      assert(a.dropBack!(0, 1)(2, 3)[$ - 1, $ - 1] == 6);
      assert(a.dropBack!(0, 1)(2, 3).shape == cast(size_t[2])[2, 2]);
      assert(a.dropBack!(0, 1)(5, 5).shape == cast(size_t[2])[0, 0]);

      assert(a.drop(1, 2).drop(0, 3)[0, 0] == 17);
      assert(a.drop(1, 2).drop(0, 3).shape == cast(size_t[2])[1, 3]);
      assert(a.dropBack(0, 2).dropBack(1, 3)[$ - 1, $ - 1] == 6);
      assert(a.dropBack(0, 2).dropBack(1, 3).shape == cast(size_t[2])[2, 2]);
      assert(a.dropBack(0, 5).dropBack(1, 5).shape == cast(size_t[2])[0, 0]);

Slice!(N, Range) dropToHypercube(size_t N, Range)(Slice!(N, Range) slice);
  Returns maximal multidimensional cube.
  Parameters:

  Slice!(N, Range) slice | input slice

  Returns:
  n-dimensional slice of the same type
  Examples:

      import std.experimental.ndslice.slice;
      import std.range: iota, retro;
      assert(1000.iota
          .sliced(5, 3, 6, 7)
          .dropToHypercube
          .shape == cast(size_t[4])[3, 3, 3, 3]);

Copyright © 1999-2016 by Digital Mars ®, All Rights Reserved | Page generated by Ddoc on Sat Feb 27 18:58:51 2016