dimensions to iterate along, length of d, 1 <= d < n. Negative dimensions are supported.
(n-d)-dimensional slice composed of d-dimensional slices
2-dimensional slice support
import mir.ndslice; // ------------ // | 0 1 2 3 | // | 4 5 6 7 | // | 8 9 10 11 | // ------------ auto slice = iota(3, 4); //-> // | 3 | //-> // | 4 | size_t[1] shape3 = [3]; size_t[1] shape4 = [4]; // ------------ // | 0 1 2 3 | // | 4 5 6 7 | // | 8 9 10 11 | // ------------ auto x = slice.alongDim!(-1); // -1 is the last dimension index, the same as 1 for this case. static assert(is(typeof(x) == Slice!(SliceIterator!(IotaIterator!sizediff_t), 1, Universal))); assert(x.shape == shape3); assert(x.front.shape == shape4); assert(x.front == iota(4)); x.popFront; assert(x.front == iota([4], 4)); // --------- // | 0 4 8 | // | 1 5 9 | // | 2 6 10 | // | 3 7 11 | // --------- auto y = slice.alongDim!0; // alongDim!(-2) is the same for matrices. static assert(is(typeof(y) == Slice!(SliceIterator!(IotaIterator!sizediff_t, 1, Universal)))); assert(y.shape == shape4); assert(y.front.shape == shape3); assert(y.front == iota([3], 0, 4)); y.popFront; assert(y.front == iota([3], 1, 4));
3-dimensional slice support, N-dimensional also supported
1 import mir.ndslice; 2 3 // ---------------- 4 // | 0 1 2 3 4 | 5 // | 5 6 7 8 9 | 6 // | 10 11 12 13 14 | 7 // | 15 16 17 18 19 | 8 // - - - - - - - - 9 // | 20 21 22 23 24 | 10 // | 25 26 27 28 29 | 11 // | 30 31 32 33 34 | 12 // | 35 36 37 38 39 | 13 // - - - - - - - - 14 // | 40 41 42 43 44 | 15 // | 45 46 47 48 49 | 16 // | 50 51 52 53 54 | 17 // | 55 56 57 58 59 | 18 // ---------------- 19 auto slice = iota(3, 4, 5); 20 21 size_t[2] shape45 = [4, 5]; 22 size_t[2] shape35 = [3, 5]; 23 size_t[2] shape34 = [3, 4]; 24 size_t[2] shape54 = [5, 4]; 25 size_t[1] shape3 = [3]; 26 size_t[1] shape4 = [4]; 27 size_t[1] shape5 = [5]; 28 29 // ---------- 30 // | 0 20 40 | 31 // | 5 25 45 | 32 // | 10 30 50 | 33 // | 15 35 55 | 34 // - - - - - 35 // | 1 21 41 | 36 // | 6 26 46 | 37 // | 11 31 51 | 38 // | 16 36 56 | 39 // - - - - - 40 // | 2 22 42 | 41 // | 7 27 47 | 42 // | 12 32 52 | 43 // | 17 37 57 | 44 // - - - - - 45 // | 3 23 43 | 46 // | 8 28 48 | 47 // | 13 33 53 | 48 // | 18 38 58 | 49 // - - - - - 50 // | 4 24 44 | 51 // | 9 29 49 | 52 // | 14 34 54 | 53 // | 19 39 59 | 54 // ---------- 55 auto a = slice.alongDim!0.transposed; 56 static assert(is(typeof(a) == Slice!(SliceIterator!(IotaIterator!sizediff_t, 1, Universal), 2, Universal))); 57 58 assert(a.shape == shape54); 59 assert(a.front.shape == shape4); 60 assert(a.front.unpack == iota([3, 4], 0, 5).universal.transposed); 61 a.popFront; 62 assert(a.front.front == iota([3], 1, 20)); 63 64 // ---------------- 65 // | 0 1 2 3 4 | 66 // | 5 6 7 8 9 | 67 // | 10 11 12 13 14 | 68 // | 15 16 17 18 19 | 69 // - - - - - - - - 70 // | 20 21 22 23 24 | 71 // | 25 26 27 28 29 | 72 // | 30 31 32 33 34 | 73 // | 35 36 37 38 39 | 74 // - - - - - - - - 75 // | 40 41 42 43 44 | 76 // | 45 46 47 48 49 | 77 // | 50 51 52 53 54 | 78 // | 55 56 57 58 59 | 79 // ---------------- 80 auto x = slice.alongDim!(1, 2); 81 static assert(is(typeof(x) == Slice!(SliceIterator!(IotaIterator!sizediff_t, 2), 1, Universal))); 82 83 assert(x.shape == shape3); 84 assert(x.front.shape == shape45); 85 assert(x.front == iota([4, 5])); 86 x.popFront; 87 assert(x.front == iota([4, 5], (4 * 5))); 88 89 // ---------------- 90 // | 0 1 2 3 4 | 91 // | 20 21 22 23 24 | 92 // | 40 41 42 43 44 | 93 // - - - - - - - - 94 // | 5 6 7 8 9 | 95 // | 25 26 27 28 29 | 96 // | 45 46 47 48 49 | 97 // - - - - - - - - 98 // | 10 11 12 13 14 | 99 // | 30 31 32 33 34 | 100 // | 50 51 52 53 54 | 101 // - - - - - - - - 102 // | 15 16 17 18 19 | 103 // | 35 36 37 38 39 | 104 // | 55 56 57 58 59 | 105 // ---------------- 106 auto y = slice.alongDim!(0, 2); 107 static assert(is(typeof(y) == Slice!(SliceIterator!(IotaIterator!sizediff_t, 2, Canonical), 1, Universal))); 108 109 assert(y.shape == shape4); 110 assert(y.front.shape == shape35); 111 int err; 112 assert(y.front == slice.universal.strided!1(4).reshape([3, -1], err)); 113 y.popFront; 114 assert(y.front.front == iota([5], 5)); 115 116 // ------------- 117 // | 0 5 10 15 | 118 // | 20 25 30 35 | 119 // | 40 45 50 55 | 120 // - - - - - - - 121 // | 1 6 11 16 | 122 // | 21 26 31 36 | 123 // | 41 46 51 56 | 124 // - - - - - - - 125 // | 2 7 12 17 | 126 // | 22 27 32 37 | 127 // | 42 47 52 57 | 128 // - - - - - - - 129 // | 3 8 13 18 | 130 // | 23 28 33 38 | 131 // | 43 48 53 58 | 132 // - - - - - - - 133 // | 4 9 14 19 | 134 // | 24 29 34 39 | 135 // | 44 49 54 59 | 136 // ------------- 137 auto z = slice.alongDim!(0, 1); 138 static assert(is(typeof(z) == Slice!(SliceIterator!(IotaIterator!sizediff_t, 2, Universal)))); 139 140 assert(z.shape == shape5); 141 assert(z.front.shape == shape34); 142 assert(z.front == iota([3, 4], 0, 5)); 143 z.popFront; 144 assert(z.front.front == iota([4], 1, 5));
Use alongDim to calculate column mean/row mean of 2-dimensional slice
import mir.ndslice.topology: alongDim; import mir.ndslice.fuse: fuse; import mir.math.stat: mean; import mir.algorithm.iteration: all; import mir.math.common: approxEqual; auto x = [ [0.0, 1.0, 1.5, 2.0, 3.5, 4.25], [2.0, 7.5, 5.0, 1.0, 1.5, 0.0] ].fuse; // Use alongDim with map to compute mean of row/column. assert(x.alongDim!1.map!mean.all!approxEqual([12.25 / 6, 17.0 / 6])); assert(x.alongDim!0.map!mean.all!approxEqual([1, 4.25, 3.25, 1.5, 2.5, 2.125])); // FIXME // Without using map, computes the mean of the whole slice // assert(x.alongDim!1.mean == x.sliced.mean); // assert(x.alongDim!0.mean == x.sliced.mean);
Use alongDim and map with a lambda, but may need to allocate result. This example uses fuse, which allocates. Note: fuse!1 will transpose the result.
import mir.ndslice.topology: iota, alongDim, map; import mir.ndslice.fuse: fuse; import mir.ndslice.slice: sliced; auto x = [1, 2, 3].sliced; auto y = [1, 2].sliced; auto s1 = iota(2, 3).alongDim!1.map!(a => a * x).fuse; assert(s1 == [[ 0, 2, 6], [ 3, 8, 15]]); auto s2 = iota(2, 3).alongDim!0.map!(a => a * y).fuse!1; assert(s2 == [[ 0, 1, 2], [ 6, 8, 10]]);
byDim, iota, slice, ipack, transposed.
Returns a slice that can be iterated along dimension. Transposes other dimensions on top and then packs them.
Combines byDim and evertPack.