1 /++
2 $(H2 Multidimensional mutation algorithms)
3 
4 This is a submodule of $(MREF mir,ndslice).
5 
6 $(BOOKTABLE $(H2 Function),
7 $(TR $(TH Function Name) $(TH Description))
8 )
9 
10 License: $(HTTP www.apache.org/licenses/LICENSE-2.0, Apache-2.0)
11 Copyright: 2020 Ilya Yaroshenko, Kaleidic Associates Advisory Limited, Symmetry Investments
12 Authors: Ilya Yaroshenko
13 
14 Macros:
15 SUBREF = $(REF_ALTTEXT $(TT $2), $2, mir, ndslice, $1)$(NBSP)
16 T2=$(TR $(TDNW $(LREF $1)) $(TD $+))
17 +/
18 module mir.ndslice.mutation;
19 
20 import mir.ndslice.slice: Slice, SliceKind;
21 
22 /++
23 Copies n-dimensional minor.
24 +/
25 void copyMinor(size_t N, IteratorFrom, SliceKind KindFrom, IteratorTo, SliceKind KindTo, IndexIterator)(
26     Slice!(IteratorFrom, N, KindFrom) from,
27     Slice!(IteratorTo, N, KindTo) to,
28     Slice!IndexIterator[N] indices...
29 )
30 in {
31     import mir.internal.utility: Iota;
32     static foreach (i; Iota!N)
33         assert(indices[i].length == to.length!i);
34 }
35 do {
36     static if (N == 1)
37         to[] = from[indices[0]];
38     else
39     foreach (i; 0 .. indices[0].length)
40     {
41         copyMinor!(N - 1)(from[indices[0][i]], to[i], indices[1 .. N]);
42     }
43 }
44 
45 ///
46 version(mir_test)
47 @safe pure nothrow
48 unittest
49 {
50     import mir.ndslice;
51     //  0  1  2  3
52     //  4  5  6  7
53     //  8  9 10 11
54     auto a = iota!int(3, 4);
55     auto b = slice!int(2, 2);
56     copyMinor(a, b, [2, 1].sliced, [0, 3].sliced);
57     assert(b == [[8, 11], [4, 7]]);
58 }
59 
60 /++
61 Reverses data in the 1D slice.
62 +/
63 void reverseInPlace(Iterator)(Slice!Iterator slice)
64 {
65     import mir.utility : swap;
66     foreach (i; 0 .. slice.length / 2)
67         swap(slice[i], slice[$ - (i + 1)]);
68 }
69 
70 ///
71 version(mir_test)
72 @safe pure nothrow
73 unittest
74 {
75     import mir.ndslice;
76     auto s = 5.iota.slice;
77     s.reverseInPlace;
78     assert([4, 3, 2, 1, 0]);
79 }