Finding RMS value of arrays.

Hi, I'm very new to C++ and can't seem to work out why this piece of code wont work as i expected.

I have three arrays representing wave functions and i am trying to find out the averages and RMS values for each waves. The RMS seems to be eluding me.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83

#include <iostream>
#include <cmath>

using namespace std;

#define SIZE1 80
#define SIZE2 62
#define SIZE3 29

double getAverage(short arr[], int size)

{
  int    i, sum = 0;
  double avg;

  for (i = 0; i < size; ++i)
  {
    sum += arr[i];
   }

  avg = double(sum) / size;

  return avg;
}

double getRMS (short arr[], int size)

{
    int i;
    double sumsq;
    double RMS;
    sumsq = 0;


    for (i = 0; i< size; i++)
    {
        sumsq += arr[i]*arr[i];
        RMS = (1/size)*(sqrt(sumsq));

        return RMS;
    }

}

int main()
{
    short cosine[SIZE1] = {
        32767, 32666, 32364, 31862, 31163, 30273, 29196, 27938, 26509, 24916,
        23170, 21280, 19260, 17121, 14876, 12539, 10126, 7649, 5126, 2571,
        0, -2571, -5126, -7649, -10126, -12539, -14876, -17121, -19260, -21280,
        -23170, -24916, -26509, -27938, -29196, -30273, -31163, -31862, -32364, -32666,
        -32767, -32666, -32364, -31862, -31163, -30273, -29196, -27938, -26509, -24916,
        -23170, -21280, -19260, -17121, -14876, -12539, -10126, -7649, -5126, -2571,
        0, 2571, 5126, 7649, 10126, 12539, 14876, 17121, 19260, 21280,
        23170, 24916, 26509, 27938, 29196, 30273, 31163, 31862, 32364, 32666
    };
    short triangle[SIZE2] = {
        15500, 14500, 13500, 12500, 11500, 10500, 9500, 8500, 7500, 6500,
        5500, 4500, 3500, 2500, 1500, 500, -500, -1500, -2500, -3500,
        -4500, -5500, -6500, -7500, -8500, -9500, -10500, -11500, -12500, -13500,
        -14500, -15500, -14500, -13500, -12500, -11500, -10500, -9500, -8500, -7500,
        -6500, -5500, -4500, -3500, -2500, -1500, -500, 500, 1500, 2500,
        3500, 4500, 5500, 6500, 7500, 8500, 9500, 10500, 11500, 12500,
        13500, 14500
    };
    short sawtooth[SIZE3] = {
        -24000, -22000, -20000, -18000, -16000, -14000, -12000, -10000, -8000, -6000,
        -4000, -2000, 0, 2000, 4000, 6000, 8000, 10000, 12000, 14000,
        16000, 18000, 20000, 22000, 24000, 26000, 28000, 30000, 32000
    };

cout<<"Average of cosine:  "<<getAverage (cosine,SIZE1)<<endl;

cout<<"Average of traingle:  "<<getAverage (triangle,SIZE2)<<endl;

cout<< "Average of sawtooth:  "<<getAverage(sawtooth,SIZE3)<<endl;

cout<<"RMS of cosine"<<getRMS (cosine,SIZE1) <<endl;

return 0;
}


The values for averages are what i would expect, but the value for RMS cosine is found to be 0. Having gone through the array using a calculator i expect a value of roughly 408.

Any tips would be hugely appreciated.


edit: Equation to find RMS is ( 1/size of array * (sum of squares))^1/2
Last edited on
Hi there,

I believe you problem lies here:

 
RMS = (1/size)*(sqrt(sumsq)); //line 39 


You probably mean:

RMS = (static_cast<double>(1)/size)*(sqrt(sumsq));

If you don't cast 1 (or size) to a double, 1/size will be an integer by integer division, returning an integer result (0 in this case, because 1 divided by size will be 0. something).


Hope that helps.

All the best,
NwN
if your formula for RMS is correct, then RMS shouldn't be within the body of the for...loop, you should have:
1
2
3
4
5
6
7
8
sumsq=0;
for(int x=0; x<size;x++)
{
//sum of all squares
sumsq+=(array[x]*array[x]);
}
RMS= everything_goes_here;
return RMS

In addition to the points above, shouldn't it be
RMS = static_cast<double>(sqrt(sumsq/size)); ?

You may have an overflow issue with the product of 2 shorts on line 38
sumsq += arr[i]*arr[i];
Consider building up the product in an int variable first:
1
2
3
int prod = arr[i];
prod *= arr[i];
sumsq += prod;
Thank you all for your replies. Having taken your suggestions into account and changed the code to:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

double getRMS (short arr[], int size)

{
    int i;
    double sumsq;
    double RMS;
    sumsq = 0;


    for (i = 0; i< size; i++)
    {
        sumsq += arr[i]*arr[i];
    }
    RMS = sqrt((static_cast<double>(1)/size)*(sumsq));
    return RMS;
}


I am finding RMScosine to be 23169 and as I said above i think it should be around 408.
You may not have seen my post when you last posted. Try fixing the overflow problem mentioned there.
The RMS value of a pure sine wave (or cosine wave) is equal to the peak value divided by sqrt(2).

Thus, if the peak value is 32767, the RMS value should be 32767/sqrt(2) = 23169.8

http://en.wikipedia.org/wiki/Root_mean_square
Last edited on
Thanks for your useful hints.
Topic archived. No new replies allowed.