Magare
Magare

Reputation: 1

My standard deviation function gives the wrong answer

Im currently trying to code a program in C that can calculate the average of an array of numbers and the standard deviation of it. code was written in code composer studio v12 and debugged on a msp430g2553 . Ive narrowed the problem down to the 'float gem = avg(input, sizeof input / sizeof input[0]);' part of the function.

replacing the problematic part 'float gem = avg(input, sizeof input / sizeof input[0]);' of the function with the actual average (float gem = 6.625;) fixes the function after which it will work as intended.

code/function in question:

#include <msp430.h> 
#include <math.h> //library used for the sqrt and powf functions.

float avg(float input[], int n) // function used to calculate the average of an array of n length.
{
    int i = 0;
    float sum = 0;
    for (i = 0; i < n; i++)
    {
        sum = input[i] + sum;
    }
    return sum / n;
}

float std_dev(float input[], int n) // function used to calculate standard deviation 
{
    int i = 0;
    float sum = 0;
    float gem = avg(input, sizeof input / sizeof input[0]);
    for (i = 0; i < n; i++)
    {
        sum = sum + powf((input[i] -gem ), 2);
    }
    return sqrt(sum / 4);

}
/**
 * main.c
 */
int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer
    float cijfers[] = { 3.2, 5.7, 8.5, 9.1 };

    float som;
    som = avg(cijfers, sizeof cijfers / sizeof cijfers[0]);

    float deviatie;
    deviatie = std_dev(cijfers, sizeof cijfers / sizeof cijfers[0]);

    return 0;
}

Upvotes: 0

Views: 128

Answers (2)

0___________
0___________

Reputation: 67855

The problem is here:

float std_dev(float input[], int n) // function used to calculate standard deviation 
{
    int i = 0;
    float sum = 0;
    float gem = avg(input, sizeof input / sizeof input[0]);

input is a pointer to float and sizeof(input) will give you the size of the pointer not the size of the array this pointer is referencing.

On 16 bit MSP430 system sizeof input / sizeof input[0] will give you 1 or 0 depending on the addressing mode (pointers can be 2 or 4 bytes long)

Upvotes: 0

abelenky
abelenky

Reputation: 64730

float std_dev(float input[], int n) // function used to calculate standard deviation 
{
    const float gem = avg( input, n ); // Pass parameter N, since we already have it.
    float sum = 0;

    for (int i = 0; i < n; i++)        // Declare i to be loop-local
    {
        sum += (input[i] - gem) * (input[i] - gem); // Re-wrote for simplicity.
    }
    return sqrt(sum/n);                // Change the /4 to a /n
}

You already have the size of the array as parameter n. Just use that when calling function avg, both for simplicity, and because the sizeof "trick" doesn't work in this context.

Calling powf is not "wrong", but unnecessary when you're just trying to do a basic squaring. Its easier just to do multiplication of the value by itself.

I don't know why you did a / 4 at the end. To the best of my knowledge, the standard deviation is just the square-root of the variance.

Upvotes: 2

Related Questions