Menu

- Learn
- Documentation
  - Language Reference
  - Library Reference
  - Command-line Reference
  - Feature Overview
  - Articles
- Packages
- Community
  - Blog
  - Orgs using D
  - Twitter
  - Forums
  - IRC
  - Wiki
  - GitHub
  - Issues
  - Foundation
  - Donate
- Resources
  - Books
  - Tutorials
  - Tools
  - Editors
  - IDEs
  - Visual D
  - Acknowledgments
  - D Style
  - Glossary
  - Sitemap

Search
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.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 | Description
--- | ---
transposed | Permutes dimensions. iotaSlice(3, 4, 5, 6, 7).transposed!(4, 0, 1).shape returns [7, 3, 4, 5, 6].
swapped | Swaps dimensions iotaSlice(3, 4, 5).swapped!(1, 2).shape returns [3, 5, 4].
everted | Reverses the order of dimensions iotaSlice(3, 4, 5).everted.shape returns [5, 4, 3].

See also evertPack .

## Iteration operators

Function Name | Description
--- | ---
strided | Multiplies the stride of a selected dimension by a factor. iotaSlice(13, 40).strided!(0, 1)(2, 5).shape equals to [7, 8].
reversed | Reverses the direction of `iteration` for selected dimensions. slice.reversed!0 returns the slice with reversed direction of `iteration` for top level dimension.
allReversed | Reverses the direction of `iteration` for all dimensions. iotaSlice(4, 5).allReversed equals to 20.iota.retro.sliced(4, 5).

## Other operators

Function Name | Description
--- | ---
rotated | Rotates two selected dimensions by k*90 degrees. iotaSlice(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)
@@@DEPRECATED_2017-04@@@
rotated | No | slice.rotated!(2, 3)(-1) | slice.rotated(2, 3, -1)
@@@DEPRECATED_2017-04@@@
strided | Yes/No | slice.strided!(1, 2)(20, 40) | slice.strided(1, 20).strided(2, 40)
@@@DEPRECATED_2017-04@@@
transposed | Yes | slice.transposed!(1, 4, 3) | slice.transposed(1, 4, 3)
@@@DEPRECATED_2017-04@@@
reversed | Yes | slice.reversed!(0, 2) | slice.reversed(0, 2)
@@@DEPRECATED_2017-04@@@

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.experimental.ndslice.selection : iotaSlice;
      assert(iotaSlice(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.experimental.ndslice.selection : iotaSlice;
      assert(iotaSlice(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.experimental.ndslice.selection : iotaSlice;
      assert(iotaSlice(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.experimental.ndslice.selection : iotaSlice;
      auto slice = iotaSlice(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)(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.experimental.ndslice.selection : iotaSlice;
      assert(iotaSlice(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, size_t M)(Slice!(N, Range) `slice`, size_t[M] `dimensions`...);
Slice!(2, Range) `transposed`(Range)(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[M] `dimensions` | indexes of `dimensions` to be brought to the first position
  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.experimental.ndslice.selection : iotaSlice;
      assert(iotaSlice(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.experimental.ndslice.selection : iotaSlice;
      assert(iotaSlice(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.experimental.ndslice.selection : iotaSlice;
      assert(iotaSlice(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.experimental.ndslice.selection : iotaSlice;
      assert(iotaSlice(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, size_t M)(Slice!(N, Range) `slice`, size_t[M] `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[M] `dimensions` | indexes of `dimensions` to reverse order of iteration
  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 a `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.experimental.ndslice.selection : iotaSlice;
      static assert(iotaSlice(13, 40).strided!(0, 1)(2, 5).shape == [7, 8]);
      static assert(iotaSlice(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.experimental.ndslice.selection : iotaSlice;
      auto a = iotaSlice(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.experimental.ndslice.selection : iotaSlice;
      auto a = iotaSlice(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.experimental.ndslice.selection : iotaSlice;
      auto a = iotaSlice(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, size_t M)(Slice!(N, Range) `slice`, size_t[M] `dimensions`...);
template `dropBackOne`(Dimensions...) if (Dimensions.length)
Slice!(N, Range) `dropBackOne`(size_t N, Range, size_t M)(Slice!(N, Range) `slice`, size_t[M] `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.experimental.ndslice.selection : iotaSlice;
      auto a = iotaSlice(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.experimental.ndslice.selection : iotaSlice;
      auto a = iotaSlice(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.experimental.ndslice.selection : iotaSlice;
      auto a = iotaSlice(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.selection : iotaSlice;
      assert(iotaSlice(5, 3, 6, 7)
          .dropToHypercube
          .shape == cast(size_t[4])[3, 3, 3, 3]);

Copyright © 1999-2017 by the D Language Foundation | Page generated by Ddoc on Thu Feb 16 13:40:06 2017