2009-10-17 5 views
1

J'ai un tableau flottant 1 dimension de root mean square valeurs, chacune calculée avec la même longueur de fenêtre. Disons queCalcul de RMS avec des fenêtres qui se chevauchent

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

Maintenant RMS pour une plus grande fenêtre, qui peut être représenté comme une gamme de fenêtres d'origine, peut être calculé comme le RMS des « participants » valeurs RMS de RMS[i] à RMS[i + len]. Ici len est la longueur de la plus grande fenêtre divisée par la longueur des fenêtres d'origine.

Je voudrais créer une fenêtre mobile. Je veux

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

calculé aussi efficacement que possible. Je sais que ce n'est pas très difficile à cracker, mais est-ce que quelqu'un a un code prêt pour ça? J'ai demandé un exemple de code, donc je suppose qu'il serait décent de fournir certains. Ce qui suit est basé sur la réponse de Pierr et est écrit en C#. C'est un peu différent de ma question initiale car je me suis rendu compte qu'il serait bien d'avoir le tableau résultant pour avoir la même taille que l'original et pour avoir les fenêtres fin à chaque élément.

// The RMS data to be analysed 
float[] 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); 
} 

Répondre

3

Je ne suis pas sûr d'avoir bien compris votre problème. Mais laissez-moi essayer.

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 

Il est difficile de ne pas remarquer que:

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

En procédant ainsi, vous évitez recaculating les fenêtres se chevauchent.

EDIT:

Vous pouvez économiser multiplier et diviser l'opération en déplaçant LEN sur le côté gauche des équations. Cela peut accélérer beaucoup car la division est généralement relativement lente.

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

Merci +1, je suppose que je vais ajouter le code de mon implémentation de cette question une fois que je l'ai fait. –

Questions connexes