Skip to content

Commit f2c3080

Browse files
committed
add pairwise and default lambdas for all and any
1 parent 4dec172 commit f2c3080

File tree

5 files changed

+125
-165
lines changed

5 files changed

+125
-165
lines changed

index.d

Lines changed: 25 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -10,107 +10,35 @@ $(BOOKTABLE ,
1010
$(TH Modules)
1111
$(TH Description)
1212
)
13-
$(LEADINGROW Multidimensional ndslices, iterators, and algorithms)
14-
$(TR
15-
$(TDNW $(MREF mir,ndslice))
16-
$(TD Package)
17-
)
18-
$(TR
19-
$(TDNW $(MREF mir,ndslice,slice))
20-
$(TD Slice structure, basic constructors)
21-
)
22-
$(TR
23-
$(TDNW $(MREF mir,ndslice,allocation))
24-
$(TD Allocation utilities)
25-
)
26-
$(TR
27-
$(TDNW $(MREF mir,ndslice,topology))
28-
$(TD Advanced constructors, SliceKind conversion utilities)
29-
)
30-
$(TR
31-
$(TDNW $(MREF mir,ndslice,mutation))
32-
$(TD Mutation algorithms)
33-
)
34-
$(TR
35-
$(TDNW $(MREF mir,ndslice,algorithm))
36-
$(TD Loop free programming)
37-
)
38-
$(TR
39-
$(TDNW $(MREF mir,ndslice,concatenation))
40-
$(TD Concatenation and padding)
41-
)
42-
$(TR
43-
$(TDNW $(MREF mir,ndslice,dynamic))
44-
$(TD Dynamic dimension manipulators)
45-
)
46-
$(TR
47-
$(TDNW $(MREF mir,ndslice,sorting))
48-
$(TD Sorting utilities)
49-
)
50-
$(TR
51-
$(TDNW $(MREF mir,ndslice,iterator))
52-
$(TD Iterator declarations)
53-
)
54-
$(TR
55-
$(TDNW $(MREF mir,ndslice,field))
56-
$(TD Field declarations)
57-
)
58-
$(TR
59-
$(TDNW $(MREF mir,ndslice,ndfield))
60-
$(TD NdField declarations)
61-
)
13+
$(LEADINGROW Algorithms constructors, multidimensional arrays, iterators)
14+
$(TR $(TDNW $(MREF mir,ndslice)) $(TD Package))
15+
$(TR $(TDNW $(MREF mir,ndslice,algorithm)) $(TD Loop free programming))
16+
$(TR $(TDNW $(MREF mir,ndslice,allocation)) $(TD Allocation utilities))
17+
$(TR $(TDNW $(MREF mir,ndslice,concatenation)) $(TD Concatenation and padding))
18+
$(TR $(TDNW $(MREF mir,ndslice,dynamic)) $(TD Dynamic dimension manipulators))
19+
$(TR $(TDNW $(MREF mir,ndslice,field)) $(TD Field declarations))
20+
$(TR $(TDNW $(MREF mir,ndslice,iterator)) $(TD Iterator declarations))
21+
$(TR $(TDNW $(MREF mir,ndslice,mutation)) $(TD Mutation algorithms))
22+
$(TR $(TDNW $(MREF mir,ndslice,ndfield)) $(TD NdField declarations))
23+
$(TR $(TDNW $(MREF mir,ndslice,slice)) $(TD Slice structure, basic constructors))
24+
$(TR $(TDNW $(MREF mir,ndslice,sorting)) $(TD Sorting utilities))
25+
$(TR $(TDNW 🔷 $(MREF mir,ndslice,topology) 🔷) $(TD Advanced ndslice constructors (key module).))
6226
$(LEADINGROW Finance)
63-
$(TR
64-
$(TDNW $(MREF mir,timeseries))
65-
$(TD Time-series)
66-
)
27+
$(TR $(TDNW $(MREF mir,timeseries)) $(TD Time-series))
6728
$(LEADINGROW Math)
68-
$(TR
69-
$(TDNW $(MREF mir,math,common))
70-
$(TD Common math functions)
71-
)
72-
$(TR
73-
$(TDNW $(MREF mir,math,constant))
74-
$(TD Constants)
75-
)
76-
$(TR
77-
$(TDNW $(MREF mir,math,func))
78-
$(TD Special math functions)
79-
)
29+
$(TR $(TDNW $(MREF mir,math,common)) $(TD Common math functions))
30+
$(TR $(TDNW $(MREF mir,math,constant)) $(TD Constants))
31+
$(TR $(TDNW $(MREF mir,math,func)) $(TD Special math functions))
8032
$(LEADINGROW Numeric)
81-
$(TR
82-
$(TDNW $(MREF mir,interpolation))
83-
$(TD Interpolation algorithms)
84-
)
85-
$(TR
86-
$(TDNW $(MREF mir,math,sum))
87-
$(TD Various precise summation algorithms)
88-
)
33+
$(TR $(TDNW $(MREF mir,interpolation)) $(TD Interpolation algorithms))
34+
$(TR $(TDNW $(MREF mir,math,sum)) $(TD Various precise summation algorithms))
8935
$(LEADINGROW Accessories)
90-
$(TR
91-
$(TDNW $(MREF mir,utility))
92-
$(TD Everyday utilities)
93-
)
94-
$(TR
95-
$(TDNW $(MREF mir,bitmanip))
96-
$(TD Bit fields manipulations)
97-
)
98-
$(TR
99-
$(TDNW $(MREF mir,conv))
100-
$(TD Conversion utilities)
101-
)
102-
$(TR
103-
$(TDNW $(MREF mir,functional))
104-
$(TD Functions that manipulate other functions)
105-
)
106-
$(TR
107-
$(TDNW $(MREF mir,array,primitives))
108-
$(TD Array range primitives with ndslice-like API)
109-
)
110-
$(TR
111-
$(TDNW $(MREF mir,primitives))
112-
$(TD Templates used to check primitives)
113-
)
36+
$(TR $(TDNW $(MREF mir,utility)) $(TD Everyday utilities))
37+
$(TR $(TDNW $(MREF mir,array,primitives)) $(TD Array range primitives with ndslice-like API))
38+
$(TR $(TDNW $(MREF mir,bitmanip)) $(TD Bit fields manipulations))
39+
$(TR $(TDNW $(MREF mir,conv)) $(TD Conversion utilities))
40+
$(TR $(TDNW $(MREF mir,functional)) $(TD Functions that manipulate other functions))
41+
$(TR $(TDNW $(MREF mir,primitives)) $(TD Templates used to check primitives))
11442
)
11543

11644
Copyright: Copyright © 2016-, Ilya Yaroshenko.

source/mir/ndslice/algorithm.d

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,7 @@ bool[2] minmaxPosImpl(alias fun, SliceKind kind, size_t[] packs, Iterator)(ref s
452452
Finds a positions (ndslices) such that
453453
`position[0].first` is minimal and `position[1].first` is maximal elements in the slice.
454454
455-
Position is sub-ndslice of the same dimension in the right-(down-(etc)) corner.
455+
Position is sub-ndslice of the same dimension in the right-$(RPAREN)down-$(RPAREN)etc$(LPAREN)$(LPAREN) corner.
456456
457457
Params:
458458
pred = A predicate.
@@ -461,7 +461,7 @@ See_also:
461461
$(LREF minmaxIndex),
462462
$(LREF minPos),
463463
$(LREF maxPos),
464-
$(REF Slice.backward, mir,ndslice,slice).
464+
$(SUBREF slice, Slice.backward).
465465
+/
466466
template minmaxPos(alias pred = "a < b")
467467
{
@@ -1026,7 +1026,7 @@ Like $(LREF find), but only returns whether or not the search was successful.
10261026
Params:
10271027
pred = The predicate.
10281028
+/
1029-
template any(alias pred)
1029+
template any(alias pred = "a")
10301030
{
10311031
import mir.functional: naryFun;
10321032
static if (__traits(isSame, naryFun!pred, pred))
@@ -1039,7 +1039,7 @@ template any(alias pred)
10391039
All slices must have the same shape.
10401040
+/
10411041
@fastmath bool any(Slices...)(Slices slices)
1042-
if (Slices.length && allSatisfy!(isSlice, Slices))
1042+
if ((Slices.length == 1 || !__traits(isSame, pred, "a")) && Slices.length && allSatisfy!(isSlice, Slices))
10431043
{
10441044
slices.checkShapesMatch;
10451045
return !slices[0].anyEmpty && anyImpl!pred(slices);
@@ -1147,7 +1147,7 @@ Params:
11471147
pred = The predicate.
11481148
11491149
+/
1150-
template all(alias pred)
1150+
template all(alias pred = "a")
11511151
{
11521152
import mir.functional: naryFun;
11531153
static if (__traits(isSame, naryFun!pred, pred))
@@ -1160,7 +1160,7 @@ template all(alias pred)
11601160
All slices must have the same shape.
11611161
+/
11621162
@fastmath bool all(Slices...)(Slices slices)
1163-
if (Slices.length && allSatisfy!(isSlice, Slices))
1163+
if ((Slices.length == 1 || !__traits(isSame, pred, "a")) && Slices.length && allSatisfy!(isSlice, Slices))
11641164
{
11651165
slices.checkShapesMatch;
11661166
return slices[0].anyEmpty || allImpl!pred(slices);

source/mir/ndslice/package.d

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ $(TR $(TDNW $(SUBMODULE topology) $(BR)
136136
$(SUBREF topology, map)
137137
$(SUBREF topology, ndiota)
138138
$(SUBREF topology, pack)
139+
$(SUBREF topology, pairwise)
139140
$(SUBREF topology, repeat)
140141
$(SUBREF topology, reshape)
141142
$(SUBREF topology, ReshapeError)
@@ -211,8 +212,6 @@ $(TR $(TDNW $(SUBMODULE dynamic)
211212
$(TR $(TDNW $(SUBMODULE sorting)
212213
$(BR) $(SMALL Sorting utilities))
213214
$(TD
214-
$(SUBREF sorting, isSorted)
215-
$(SUBREF sorting, isStrictlyMonotonic)
216215
$(SUBREF sorting, sort)
217216
)
218217
)

source/mir/ndslice/sorting.d

Lines changed: 68 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,111 +1,121 @@
11
/++
22
This is a submodule of $(MREF mir,ndslice).
33
4+
Note:
5+
The combination of
6+
$(SUBREF topology, pairwise) with lambda `"a <= b"` (`"a < b"`) and $(SUBREF algorithm, all) can be used
7+
to check if an ndslice is sorted (strictly monotonic). See also the examples in the module.
8+
9+
See_also: $(SUBREF topology, flattened)
10+
11+
`isSorted` and `isStrictlyMonotonic`
12+
413
License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).
514
Copyright: Andrei Alexandrescu 2008-2016, Ilya Yaroshenko 2016-,
615
Authors: Ilya Yaroshenko, Andrei Alexandrescu
16+
17+
Macros:
18+
SUBREF = $(REF_ALTTEXT $(TT $2), $2, mir, ndslice, $1)$(NBSP)
719
+/
820
module mir.ndslice.sorting;
921

22+
///
23+
unittest
24+
{
25+
import mir.ndslice.algorithm: all;
26+
import mir.ndslice.slice;
27+
import mir.ndslice.sorting: sort;
28+
import mir.ndslice.topology: pairwise;
29+
30+
auto arr = [1, 1, 2].sliced;
31+
32+
assert(arr.pairwise!"a <= b".all);
33+
assert(!arr.pairwise!"a < b".all);
34+
35+
arr = [4, 3, 2, 1].sliced;
36+
37+
assert(!arr.pairwise!"a <= b".all);
38+
assert(!arr.pairwise!"a < b".all);
39+
40+
sort(arr);
41+
42+
assert(arr.pairwise!"a <= b".all);
43+
assert(arr.pairwise!"a < b".all);
44+
}
45+
1046
import mir.ndslice.slice;
1147
import mir.internal.utility;
1248

1349
@fastmath:
1450

15-
/++
16-
Checks whether a slice is sorted according to the comparison
17-
operation $(D less). Performs $(BIGOH ndslice.elementsCount) evaluations of `less`.
18-
Unlike `isSorted`, $(LREF _isStrictlyMonotonic) does not allow for equal values,
19-
i.e. values for which both `less(a, b)` and `less(b, a)` are false.
20-
With either function, the predicate must be a strict ordering just like with
21-
`isSorted`. For example, using `"a <= b"` instead of `"a < b"` is
22-
incorrect and will cause failed assertions.
23-
24-
Params:
25-
less = Predicate the ndslice should be sorted by.
26-
Note:
27-
isSorted requires predicates for floating point types looks like `!(cmp_condition)`
28-
to return false if the ndslice contains NaNs.
29-
+/
51+
deprecated(`Use 'yourSlice.pairwise!"a <= b".all' instead. Imports:
52+
import mir.ndslice.algorithm: all;
53+
import mir.ndslice.topology: pairwise;
54+
`)
3055
template isSorted(alias less = "!(a >= b)")
3156
{
3257
import mir.functional: naryFun;
3358
static if (__traits(isSame, naryFun!less, less))
34-
/++
35-
slice = A slice to check for sortedness.
36-
Returns:
37-
`true` if the ndslice is sorted, false otherwise. `isSorted` allows
38-
duplicates, $(LREF _isStrictlyMonotonic) not.
39-
+/
4059
@fastmath bool isSorted(SliceKind kind, size_t[] packs, Iterator)
4160
(Slice!(kind, packs, Iterator) slice)
4261
if (packs.length == 1)
4362
{
44-
import mir.functional: reverseArgs;
63+
import mir.functional: reverseArgs, not;
4564
import mir.ndslice.algorithm: all;
46-
import mir.ndslice.topology: flattened, slide;
47-
return slice.flattened.slide!(2, reverseArgs!less).all!"!a";
65+
import mir.ndslice.topology: flattened, pairwise;
66+
return slice.flattened.pairwise!(not!(reverseArgs!less)).all;
4867
}
4968
else
5069
alias isSorted = .isSorted!(naryFun!less);
5170
}
5271

53-
/// ditto
72+
deprecated(`Use 'yourSlice.pairwise!"a < b".all' instead. Imports:
73+
import mir.ndslice.algorithm: all;
74+
import mir.ndslice.topology: pairwise;
75+
`)
5476
template isStrictlyMonotonic(alias less = "a < b")
5577
{
5678
import mir.functional: naryFun;
5779
static if (__traits(isSame, naryFun!less, less))
58-
///
5980
@fastmath bool isStrictlyMonotonic(SliceKind kind, size_t[] packs, Iterator)
6081
(Slice!(kind, packs, Iterator) slice)
6182
if (packs.length == 1)
6283
{
6384
import mir.ndslice.algorithm: all;
64-
import mir.ndslice.topology: flattened, slide;
65-
return slice.flattened.slide!(2, less).all!"a";
85+
import mir.ndslice.topology: flattened, pairwise;
86+
return slice.flattened.pairwise!less.all;
6687
}
6788
else
6889
alias isStrictlyMonotonic = .isStrictlyMonotonic!(naryFun!less);
6990
}
7091

71-
72-
///
7392
unittest
7493
{
75-
assert([1, 1, 2].sliced.isSorted);
76-
// strictly monotonic doesn't allow duplicates
77-
assert(![1, 1, 2].sliced.isStrictlyMonotonic);
94+
import mir.ndslice.algorithm: all;
95+
import mir.ndslice.topology: pairwise;
7896

79-
auto arr = [4, 3, 2, 1].sliced;
80-
assert(!isSorted(arr));
81-
assert(!isStrictlyMonotonic(arr));
82-
83-
sort(arr);
84-
assert(isSorted(arr));
85-
assert(isStrictlyMonotonic(arr));
86-
}
87-
88-
unittest
89-
{
9097
auto a = [1, 2, 3].sliced;
91-
assert(isSorted(a[0 .. 0]));
92-
assert(isSorted(a[0 .. 1]));
93-
assert(isSorted(a));
98+
assert(a[0 .. 0].pairwise!"a <= b".all);
99+
assert(a[0 .. 1].pairwise!"a <= b".all);
100+
assert(a.pairwise!"a <= b".all);
94101
auto b = [1, 3, 2].sliced;
95-
assert(!isSorted(b));
102+
assert(!b.pairwise!"a <= b".all);
96103

97104
// ignores duplicates
98105
auto c = [1, 1, 2].sliced;
99-
assert(isSorted(c));
106+
assert(c.pairwise!"a <= b".all);
100107
}
101108

102109
unittest
103110
{
104-
assert([1, 2, 3][0 .. 0].sliced.isStrictlyMonotonic);
105-
assert([1, 2, 3][0 .. 1].sliced.isStrictlyMonotonic);
106-
assert([1, 2, 3].sliced.isStrictlyMonotonic);
107-
assert(![1, 3, 2].sliced.isStrictlyMonotonic);
108-
assert(![1, 1, 2].sliced.isStrictlyMonotonic);
111+
import mir.ndslice.algorithm: all;
112+
import mir.ndslice.topology: pairwise;
113+
114+
assert([1, 2, 3][0 .. 0].sliced.pairwise!"a < b".all);
115+
assert([1, 2, 3][0 .. 1].sliced.pairwise!"a < b".all);
116+
assert([1, 2, 3].sliced.pairwise!"a < b".all);
117+
assert(![1, 3, 2].sliced.pairwise!"a < b".all);
118+
assert(![1, 1, 2].sliced.pairwise!"a < b".all);
109119
}
110120

111121

@@ -130,13 +140,16 @@ template sort(alias less = "a < b")
130140
///
131141
unittest
132142
{
143+
import mir.ndslice.algorithm: all;
133144
import mir.ndslice.slice;
145+
import mir.ndslice.sorting: sort;
146+
import mir.ndslice.topology: pairwise;
134147

135148
int[10] arr = [7,1,3,2,9,0,5,4,8,6];
136149

137150
auto data = arr[].ptr.sliced(arr.length);
138151
data.sort();
139-
assert(data.isSorted);
152+
assert(data.pairwise!"a <= b".all);
140153
}
141154

142155
void quickSortImpl(alias less, Iterator)(Slice!(Contiguous, [1], Iterator) slice)

0 commit comments

Comments
 (0)