开发者

Calculating RMS with overlapping windows

I have a 1-dimensional float array of root mean square values, each calculated with the same window length. Let's say

RMS = {0, 0.01, 0.4, ... }

Now the RMS for a larger window, which can be represented as a range of the original windows, can be calculated as the RMS of the "participating" RMS values from RMS[i] to RMS[i + len]. Here len is the length of the larger window divided by the lenght of the original windows.

I'd like to create a rolling window. I want

rollingRMS[0] = RMS from 0 to len
...
rollingRMS[n] = RMS from n to len+n

calculated as efficiently as possible. I know this isn't very hard to crack, but does anyone have ready code for this?

EDIT: I asked for sample code, so I guess it would be decent to provide some. The following is based on pierr's answer and is written in C#. It's a bit different from my original question as I realized it would be nice to have the resulting array to have the same size as the original and to have the windows end at each element.

// The RMS data to be analysed
floa开发者_运维知识库t[] RMS = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// The resulting rolling RMS values
float[] rollingRMS = new float[RMS.Length];
// Window lenght
int len = 3;
// Calculate: rollingRMS will hold root mean square from windows which end at 
// each respective sample in the RMS array. For the first len samples the input
// will be treated as zero-padded
for (int i = 0; i < RMS.Length; i++)
{
    if (i == 0)
        rollingRMS[i] = (float)Math.Sqrt((RMS[i] * RMS[i] / len));
    else if (i < len)
        rollingRMS[i] = (float)Math.Sqrt(
            (   RMS[i] * RMS[i] + 
                len * (rollingRMS[i - 1] * rollingRMS[i - 1])
            ) / len);
    else
        rollingRMS[i] = (float)Math.Sqrt(
            (   len * (rollingRMS[i - 1] * rollingRMS[i - 1]) +
                RMS[i] * RMS[i] -
                RMS[i - len] * RMS[i - len]
            ) / len);
} 


I am not sure that I have understood your problem correctly. But let me have a try.

a=[1,2,3,4,5,6,7,8,9,10]
LEN = 3
SquareOfRollingRMS[0] = (a[0]^2 + a[1]^2 + a[2]^2          ) / LEN
SquareOfRollingRMS[1] = (         a[1]^2 + a[2]^2 + a[3]^2 ) / LEN

It's not difficult to notice that:

SquareOfRollingRMS[i] = RollingRMS[i-1] * LEN - a[i-1]^2 + a[i+LEN-1]^2
RollingRMS[i] = SqurefOfRollingRMS[i]^(1/2)

Doing it this way ,you are avoiding recaculating the overlap windows.

EDIT:

You can save some divide and multiply operation by moving LEN to the left side of the equations. This might speed up a lot as dividing is usually relatively slow.

LEN_by_SquareOfRollingRMS[0] = (a[0]^2 + a[1]^2 + a[2]^2)
LEN_by_SquareOfRollingRMS[i] = LEN_by_RollingRMS[i-1] - a[i-1]^2 + a[i+LEN-1]^2
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜