@@ -190,48 +190,55 @@ nothrow @nogc unittest
190
190
191
191
// / Moving mean
192
192
version (mir_test)
193
+ @safe pure nothrow @nogc
193
194
unittest
194
195
{
195
- import mir.ndslice.topology: linspace ;
196
+ import mir.internal.utility: isFloatingPoint ;
196
197
import mir.math.sum;
197
- import mir.array.allocation: array;
198
+ import mir.ndslice.topology: linspace;
199
+ import mir.rc.array: rcarray;
198
200
199
- class MovingAverage
201
+ struct MovingAverage (T)
202
+ if (isFloatingPoint! T)
200
203
{
201
- Summator! (double , Summation.precise) summator;
204
+ import mir.math.stat: MeanAccumulator;
205
+
206
+ MeanAccumulator! (T, Summation.precise) meanAccumulator;
202
207
double [] circularBuffer;
203
208
size_t frontIndex;
204
209
205
- double avg () @property const
210
+ @disable this (this );
211
+
212
+ auto avg () @property const
206
213
{
207
- return summator.sum / circularBuffer.length ;
214
+ return meanAccumulator.mean ;
208
215
}
209
216
210
217
this (double [] buffer)
211
218
{
212
219
assert (buffer.length);
213
220
circularBuffer = buffer;
214
- summator = 0 ;
215
- summator.put(buffer);
221
+ meanAccumulator.put(buffer);
216
222
}
217
223
218
224
// /operation without rounding
219
- void put (double x)
225
+ void put (T x)
220
226
{
221
227
import mir.utility: swap;
222
- summator += x;
228
+ meanAccumulator. summator += x;
223
229
swap(circularBuffer[frontIndex++ ], x);
224
- summator -= x ;
225
- frontIndex %= circularBuffer.length ;
230
+ frontIndex = frontIndex == circularBuffer.length ? 0 : frontIndex ;
231
+ meanAccumulator.summator -= x ;
226
232
}
227
233
}
228
234
229
235
// / ma always keeps precise average of last 1000 elements
230
- auto ma = new MovingAverage(linspace! double ([1000 ], [0.0 , 999 ]).array);
236
+ auto x = linspace! double ([1000 ], [0.0 , 999 ]).rcarray;
237
+ auto ma = MovingAverage! double (x[]);
231
238
assert (ma.avg == (1000 * 999 / 2 ) / 1000.0 );
232
239
// / move by 10 elements
233
- foreach (x ; linspace! double ([10 ], [1000.0 , 1009.0 ]))
234
- ma.put(x );
240
+ foreach (e ; linspace! double ([10 ], [1000.0 , 1009.0 ]))
241
+ ma.put(e );
235
242
assert (ma.avg == (1010 * 1009 / 2 - 10 * 9 / 2 ) / 1000.0 );
236
243
}
237
244
0 commit comments