Goal: give a moving average of a measurement like belt throughput, i.e. smooth or dampen the input signal so it doesn't fluctuate too much

Theory

theory

the idea is that every tick the value is a mix of the previous value (the memory) and the new input:

X_new = (1-s) * X_old + s * Input

Where s is a smoothing constant: setting it to .5 would mean that old and new are treated equally, so the current value contributes 1/16=6.25% of the value in 4 ticks. Since ticks are really quick in factorio, it is more reasonable to take a smoothing factor like .01, so the value of one second (60 ticks) ago contributes around 50% (.99 ^ 60).

Since factorio has integer calculus (only whole numbers, .99 is rounded down to zero) you don't really want to divide raw input by 100. Rather, you want to multiply everything with z:

z*X_new = z*O_old - X_old + input

And then scale down by z before displaying. You might even want to multiply the input by some amount to scale the amount up, e.g. multiply belt readings by 3600 to get items per minute instead of items per tick.

Overview:

This can be implemented in 3 combinators only, but I use slightly more to make it more understandable:

The main work is done by the central combinator, which embodies the main formula explained above: V_new = V_old - V_old/S + Input = V_old - V_old*N + Input

The addition is implemented by putting all components together on the input side.
- V_old is its own output (of the previous tick)
- V_old * N is the output of the bottom combinator (memory decay)
- Input is the V output of the top combinator (input)

Thus, every tick calculates a new version of V to which input is added and a fraction of the previous output is removed. The resulting variable V can be seen as the exponential average times the smoothing factor.

The combinator settings itself are the simple 'memory cell' / counter, where the output is copied to the input unless the red reset signal is nonzero:

Input: The topmost combinator scales up the input value (everything) and outputs it as V (for value):

Memory decay

The bottom combinator divides the current value of V by N, which is the negative value of the smoothing factor (so -100 if the smoothing factor is 100):

N is calculated by multiplying the constant value S by -1 in the constant and arithmetic combinators on the left hand side:

(the red signal is the reset signal: set to 1 to reset the counter, set back to zero to resume counting)

The final combinator scales down the value by dividing by the smoothing constant S:

In this case it ouputs to A because the counter wants its input on A, but of course you can put it on whatever you want.