@@ -7,7 +7,7 @@ at expense of precision, one can use $(REF_ALTTEXT $(TT Summation.fast), Summati
77
88License: $(LINK2 http://boost.org/LICENSE_1_0.txt, Boost License 1.0).
99
10- Authors: Ilya Yaroshenko, John Michael Hall
10+ Authors: Shigeki Karita (original numir code), Ilya Yaroshenko, John Michael Hall
1111
1212Copyright: 2019 Symmetry Investments Group and Kaleidic Associates Advisory Limited.
1313
@@ -129,13 +129,13 @@ template mean(Summation summation = Summation.appropriate)
129129 }
130130}
131131
132- // /ditto
132+ // / ditto
133133template mean (F, string summation)
134134{
135135 mixin (" alias mean = .mean!(F, Summation." ~ summation ~ " );" );
136136}
137137
138- // /ditto
138+ // / ditto
139139template mean (string summation)
140140{
141141 mixin (" alias mean = .mean!(Summation." ~ summation ~ " );" );
@@ -155,6 +155,143 @@ version(mir_test)
155155 assert (is (typeof (mean! float ([1 , 2 , 3 ])) == float ));
156156}
157157
158+ // / Mean of vector
159+ version (mir_test)
160+ @safe @nogc pure nothrow
161+ unittest
162+ {
163+ import mir.ndslice.slice : sliced;
164+
165+ static immutable x = [0.0 , 1.0 , 1.5 , 2.0 , 3.5 , 4.25 ,
166+ 2.0 , 7.5 , 5.0 , 1.0 , 1.5 , 0.0 ];
167+ assert (x.sliced.mean == 29.25 / 12 );
168+ }
169+
170+ // / Mean of matrix
171+ version (mir_test)
172+ @safe @nogc pure nothrow
173+ unittest
174+ {
175+ import mir.ndslice.slice : sliced;
176+
177+ static immutable x = [0.0 , 1.0 , 1.5 , 2.0 , 3.5 , 4.25 ,
178+ 2.0 , 7.5 , 5.0 , 1.0 , 1.5 , 0.0 ];
179+ assert (x.sliced(2 , 6 ).mean == 29.25 / 12 );
180+ }
181+
182+ // / Column mean of matrix
183+ version (mir_test)
184+ @safe @nogc pure nothrow
185+ unittest
186+ {
187+ import mir.ndslice.slice : sliced;
188+ import mir.ndslice.topology : alongDim, byDim, map;
189+
190+ static immutable x = [0.0 , 1.0 , 1.5 , 2.0 , 3.5 , 4.25 ,
191+ 2.0 , 7.5 , 5.0 , 1.0 , 1.5 , 0.0 ];
192+ static immutable result = [1 , 4.25 , 3.25 , 1.5 , 2.5 , 2.125 ];
193+
194+ // Use byDim or alongDim with map to compute mean of row/column.
195+ assert (x.sliced(2 , 6 ).byDim! 1. map! mean == result);
196+ assert (x.sliced(2 , 6 ).alongDim! 0. map! mean == result);
197+
198+ // FIXME
199+ // Without using map, computes the mean of the whole slice
200+ // assert(x.sliced(2, 6).byDim!1.mean == x.sliced.mean);
201+ // assert(x.sliced(2, 6).alongDim!0.mean == x.sliced.mean);
202+ }
203+
204+ // / Can also set algorithm or output type
205+ version (mir_test)
206+ @safe @nogc pure nothrow
207+ unittest
208+ {
209+ import mir.ndslice.slice: sliced;
210+ import mir.ndslice.topology: map, repeat;
211+
212+ // Set sum algorithm or output type
213+
214+ static immutable a = [1 , 1e100 , 1 , - 1e100 ];
215+
216+ auto x = a.sliced * 10_000;
217+ assert (x.mean! " kbn" == 20_000 / 4 );
218+ assert (x.mean! " kb2" == 20_000 / 4 );
219+ assert (x.mean! " precise" == 20_000 / 4 );
220+ assert (x.mean! (double , " precise" ) == 20_000.0 / 4 );
221+
222+ auto y = uint .max.repeat(3 );
223+ assert (y.mean! ulong == 12884901885 / 3 );
224+ }
225+
226+ /+ +
227+ For integral slices, pass output type as template parameter to ensure output
228+ type is correct
229+ +/
230+ version (mir_test)
231+ @safe @nogc pure nothrow
232+ unittest
233+ {
234+ import mir.ndslice.slice : sliced;
235+ import std.math : approxEqual;
236+
237+ static immutable x = [0 , 1 , 1 , 2 , 4 , 4 ,
238+ 2 , 7 , 5 , 1 , 2 , 0 ];
239+ assert (approxEqual(x.sliced.mean! double , 29.0 / 12 , 1.0e-10 ));
240+ }
241+
242+ // / Mean works for complex numbers (and other user-defined types)
243+ version (mir_test)
244+ @safe @nogc pure nothrow
245+ unittest
246+ {
247+ import mir.ndslice.slice : sliced;
248+
249+ static immutable cdouble [] x = [1.0 + 2i, 2 + 3i, 3 + 4i, 4 + 5i];
250+ static immutable cdouble result = 2.5 + 3. 5i;
251+ assert (x.sliced.mean == result);
252+ }
253+
254+ // / Compute mean tensors along specified dimention of tensors
255+ version (mir_test)
256+ @safe @nogc pure nothrow
257+ unittest
258+ {
259+ import mir.ndslice : alongDim, iota, as, map;
260+ /*
261+ [[0,1,2],
262+ [3,4,5]]
263+ */
264+ auto x = iota(2 , 3 ).as! double ;
265+ assert (x.mean == (5.0 / 2.0 ));
266+
267+ static immutable m0 = [(0.0 + 3.0 )/ 2.0 , (1.0 + 4.0 )/ 2.0 , (2.0 + 5.0 )/ 2.0 ];
268+ assert (x.alongDim! 0. map! mean == m0);
269+ assert (x.alongDim! (- 2 ).map! mean == m0);
270+
271+ static immutable m1 = [(0.0 + 1.0 + 2.0 )/ 3.0 , (3.0 + 4.0 + 5.0 )/ 3.0 ];
272+ assert (x.alongDim! 1. map! mean == m1);
273+ assert (x.alongDim! (- 1 ).map! mean == m1);
274+
275+ assert (iota(2 , 3 , 4 , 5 ).as! double .alongDim! 0. map! mean == iota([3 , 4 , 5 ], 3 * 4 * 5 / 2 ));
276+ }
277+
278+ // /
279+ version (mir_test)
280+ @safe @nogc pure nothrow
281+ unittest
282+ {
283+ import mir.ndslice.slice : sliced;
284+ import mir.ndslice.topology : alongDim, byDim, map;
285+
286+ static immutable x = [0.0 , 1.00 , 1.50 , 2.0 , 3.5 , 4.250 ,
287+ 2.0 , 7.50 , 5.00 , 1.0 , 1.5 , 0.000 ];
288+ static immutable result = [1.0 , 4.25 , 3.25 , 1.5 , 2.5 , 2.125 ];
289+
290+ // Use byDim or alongDim with map to compute mean of row/column.
291+ assert (x.sliced(2 , 6 ).byDim! 1. map! mean == result);
292+ assert (x.sliced(2 , 6 ).alongDim! 0. map! mean == result);
293+ }
294+
158295version (mir_test)
159296@safe pure nothrow unittest
160297{
0 commit comments