@@ -18,7 +18,6 @@ $(T2 repeat, Slice with identical values)
1818$(T2 iota, Contiguous Slice with initial flattened (contiguous) index.)
1919$(T2 ndiota, Contiguous Slice with initial multidimensional index.)
2020$(T2 linspace, Evenly spaced numbers over a specified interval.)
21-
2221)
2322
2423$(BOOKTABLE $(H2 Products),
@@ -36,12 +35,14 @@ $(T2 as, Convenience function that creates a lazy view,
3635where each element of the original slice is converted to a type `T`.)
3736$(T2 bitpack, Bitpack slice over an unsigned integral slice.)
3837$(T2 bitwise, Bitwise slice over an unsigned integral slice.)
38+ $(T2 diff, Differences between vector elements.)
3939$(T2 flattened, Contiguous 1-dimensional slice of all elements of a slice.)
4040$(T2 map, Multidimensional functional map.)
4141$(T2 retro, Reverses order of iteration for all dimensions)
42+ $(T2 slide, Sliding map for vectors.)
4243$(T2 stride, Strides 1-dimensional slice)
43- $(T2 zip, Zips slices into a slice of tuples.)
4444$(T2 unzip, Selects a slice from a zipped slice.)
45+ $(T2 zip, Zips slices into a slice of tuples.)
4546
4647)
4748
@@ -2542,6 +2543,77 @@ pure nothrow unittest
25422543
25432544private enum TotalDim (NdFields... ) = [staticMap! (DimensionCount, NdFields)].sum;
25442545
2546+ /+ +
2547+ Sliding map for vectors.
2548+
2549+ Suitable for simple convolution algorithms.
2550+
2551+ Params:
2552+ params = windows length.
2553+ fun = map functions with `params` arity.
2554+ See_also: $(LREF diff).
2555+ +/
2556+ template slide (size_t params, alias fun)
2557+ if (params <= ' z' - ' a' + 1 )
2558+ {
2559+ import mir.functional: naryFun;
2560+ static if (params == 1 )
2561+ {
2562+ alias slide = .map! (naryFun! fun);
2563+ }
2564+ else
2565+ static if (__traits(isSame, naryFun! fun, fun))
2566+ {
2567+ /+ +
2568+ Params:
2569+ slice = An 1-dimensional input slice.
2570+ Returns:
2571+ 1d-slice composed of `fun(slice[i], ..., slice[i + params - 1])`.
2572+ +/
2573+ @fastmath auto slide(SliceKind kind, Iterator)
2574+ (Slice! (kind, [1 ], Iterator) slice)
2575+ {
2576+ auto s = slice.flattened;
2577+ s._lengths[0 ] -= params - 1 ;
2578+ if (cast (sizediff_t )s._lengths[0 ] < 0 )
2579+ s._lengths[0 ] = 0 ;
2580+ alias I = SlideIterator! (_IteratorOf! (typeof (s)), params, fun);
2581+ return Slice! (Contiguous, [1 ], I)(
2582+ s._lengths,
2583+ s._strides,
2584+ I(s._iterator));
2585+ }
2586+ }
2587+ else alias slide = .slide! (params, naryFun! fun);
2588+ }
2589+
2590+ // /
2591+ unittest
2592+ {
2593+ auto data = 10. iota;
2594+ auto sw = data.slide! (3 , " a + 2 * b + c" );
2595+
2596+ import mir.utility: max;
2597+ assert (sw.length == max(0 , cast (ptrdiff_t )data.length - 3 + 1 ));
2598+ assert (sw == sw.length.iota.map! " (a + 1) * 4" );
2599+ }
2600+
2601+ /+ +
2602+ Differences between vector elements.
2603+ Params:
2604+ lag = an integer indicating which lag to use
2605+ Returns: lazy difference 1d-slice.
2606+
2607+ See_also: $(LREF slide).
2608+ +/
2609+ alias diff (size_t lag = 1 ) = slide! (lag + 1 , (' a' + lag) ~ " - a" );
2610+
2611+ // /
2612+ unittest
2613+ {
2614+ assert ([2 , 4 , 3 , - 1 ].sliced.diff == [2 , - 1 , - 4 ]);
2615+ }
2616+
25452617/+ +
25462618Cartesian product.
25472619
0 commit comments