0

Please note that I do not ask for the code, but for insight, possibly from someone who as already encountered a similar issue.

I am mantaining code that runs in real time in an embedded system. For safety reasons a new check must be implemented.

This check is based on the integrated value of a certain variable. The integral must span the last "T_s" seconds, i.e. at each new cycle I have to remove the value that the variable had T_s seconds ago and add the current one.

The naive approach would be to store in an array the last T_s*frequency floating point values.

Running at 62.5Hz, this rapidly wastes lots of precious and limited memory.

Are there known approaches that, at the obvious expense of accuracy, significantly reduce the memory footprint of such a check?

The value is a measurement coming from a real system, it is not generated by a function.

I thought about storing N averages, each of M points and then integrate the N averages, this would reduce the memory requirement to N+M numbers, that can be made significantly smaller than T_s*frequency, but I wonder:

  • if this has been studied and an "optimal" point has been found (as a function of M, for example). I serached, but apparently my google-fu is broken, as searching anything including "numerical integration" does not lead to what I look for.

  • if there is a better approach

I tagged this post with C because that is the official language of the project, any solution that does not work in ANSI-C is not viable for me, unfortunately.

Federico
  • 1,032
  • 3
  • 15
  • 33
  • 1
    Are the intervals where you calculate the integrated value overlapping, or one after the other? –  Oct 10 '14 at 14:02
  • @Evert there is only one interval. The check is on the integral from "t-T_s" to "t", with t the current timestamp. I implemented it as an array of the last T_s*sampletime values and a separate variable containing the sum of those values. At each step I subtract the oldest one, add the newly received one and shift by one the array, adding the new value on top. – Federico Oct 10 '14 at 14:06
  • @Evert the N averages, instead, would be one after the other, no overlapping between them. – Federico Oct 10 '14 at 14:07
  • @Federico Do you need to run the check at each sample, or can you batch it? When I worked on audio on embedded processors, we would only process data when we had 128 samples. Can you do something similar? – Degustaf Oct 10 '14 at 14:20
  • @Degustaf the check must run each cycle. – Federico Oct 10 '14 at 17:02

1 Answers1

0

I cannot seem to find the internet page where statistics calculations with only three(?) variables were described. Maybe you do when your google-fu recovers.

Alas, if you don't need 100% accuracy but can live with an average value, you could do something like:

avg = (avg * 0.95) + ((newValue - avg) * 0.05);

This will give you an approximate average of older values where the most recent one (newValue) has no more than 1/20 of influence; the result multiplied by 20 is then basically your average integral. Of course, you may adjust the two constants to any value of 1-(1/N) and 1/N, respectively, for any number N of samples to consider.

Edit:

"On-line" (iterator) algorithms for estimating statistical median, mode, skewness, kurtosis?

and

https://math.stackexchange.com/questions/106700/incremental-averageing

may have some useful answers, too.

Community
  • 1
  • 1
JimmyB
  • 11,178
  • 1
  • 23
  • 42
  • the problem with those links (and partially your idea) is that they do not "forget" what happened T_s seconds ago, but they will keep that information. It is true though that the old values will become less and less important. I will test it as soon as I can. – Federico Oct 10 '14 at 17:06
  • Btw, "storing N averages, each of M points and then integrate the N averages" sounds promising. If you need to discard whole seconds of some 60 samples it seems logical to add/average those 60 samples for each second into a single value per second and then only have to store one value for each *second* of the interval covered. – JimmyB Oct 10 '14 at 20:52
  • Btw #2, "and shift by one the array". You'll probably want to use an implementation of a FIFO buffer, a.k.a. ring buffer, a.k.a. cyclic buffer to avoid having to move the whole array's content over and over again. – JimmyB Oct 10 '14 at 20:55
  • Yes, I thought about the cyclic approach for the runtime optimized version, thanks for mentioning. – Federico Oct 10 '14 at 21:31