Skip to content

Conversation

@jmh530
Copy link
Contributor

@jmh530 jmh530 commented Jul 14, 2020

I did this more too satisfy my own curiosity in terms of potentially adding the same functionality to mir-stat at some point in the future.

One of the things I noticed is that MeanAccumulator does not have + and - defined in the same way that Summator does. It doesn't really have a big impact in this case because I avoid modifying count. However, it means the logic for adjusting it is in MovingAverage instead of MeanAccumulator. I would guess, without testing myself and not being 100% sure, that when compiling with -O the adding and subtraction of count is elided.

import mir.rc.array: RCI;

MeanAccumulator!(T, summation) meanAccumulator;
Slice!(RCI!T) circularBuffer;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it should be double[], you may want to add @disable this(this)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy to make this change, but I don't really understand the motivation for using double[] here, as opposed to a Slice, either just a simple contiguous one or the reference-counted one I used.

Honestly, I expected that making the change would have led to a gc allocation and was a little surprised when it didn't.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A double[] doesn't really mean a GC-allocated memory. It is just a slice of memory. The idea is to allow a user to reuse existing memory. For example, it may be a stack-allocated memory and fallback to a manually allocated memory in case of a large size.


/// ma always keeps precise average of last 1000 elements
auto ma = new MovingAverage(linspace!double([1000], [0.0, 999]).array);
auto ma = MovingAverage!(double, Summation.precise)(linspace!double([1000], [0.0, 999]).rcslice);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can allocate rcarray and pass its view [].

import mir.ndslice.topology: linspace;

class MovingAverage
struct MovingAverage(T, Summation summation)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only precise summtation can be used for this kind of moving everage algorithm.

swap(circularBuffer[frontIndex++], x);
summator -= x;
meanAccumulator.summator -= x;
frontIndex %= circularBuffer.length;
Copy link
Member

@9il 9il Jul 15, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw, in case you wish to add similar API to mir-stat:

// this line should be before `meanAccumulator.summator -= x;` frontIndex = frontIndex == circularBuffer.length ? 0 : frontIndex; meanAccumulator.summator -= x;

This will be a much faster then %=

Summator!(double, Summation.precise) summator;
import mir.math.stat: MeanAccumulator;
import mir.ndslice.slice: Slice;
import mir.rc.array: RCI;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 LOC isn't used

@9il 9il merged commit 6881e02 into libmir:master Jul 15, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants