Вопрос

So I was using this method that calculates the standard deviation of my array but it doesn't seem to give me the right value.

double numbers[] = new double[10];
double sumOfAllItems = 0;

private double total()
{
    for (int i = 0; i < numbers.Length; i++)
    {
        sumOfAllItems += numbers[i];
    }

    return sumOfAllItems;
}

public double mean()
{
    // working
    **sumOfAllItems = 0;**
    return total() / numbers.Length;
}

// numbers are from (1-10) (too lazy to type up all of them.

public double variance()
{
    // each (value - mean) squared
    double summationsTotal = 0; // (numbers[i] - mean() squared

    for (int i = 0; i < numbers.Length; i++)
    {
        summationsTotal += Math.Pow(numbers[i] - mean(), 2);
    }

    return summationsTotal / (numbers.Length - 1);
}

I manually calculated the Variance and it gave me an answer of a 9.166666. This is for sample formula.

However, when I calculated it on my GUI, it gave me 866.25 instead. Is there anything wrong with this code?

Это было полезно?

Решение 2

Ok you have got your answer. I would suggest an alternate approach with Linq goodies and extension methods.

public static double StandardDeviation(this ICollection<double> values)
{
    return Math.Sqrt(values.Variance());
}

public static double Variance(this ICollection<double> values)
{
    if (values.Count == 0)
        return 0;

    var avg = values.Average();
    return values.Select(x => Math.Pow(x - avg, 2)).Sum() / values.Count;
}

Call it like:

var variance = numbers.Variance(); //or so

Другие советы

The problem is here:

double sumOfAllItems = 0;

private double total()
{
    for (int i = 0; i < numbers.Length; i++)
    {
        sumOfAllItems += numbers[i];
    }

    return sumOfAllItems;
}

It should be:

double sumOfAllItems = 0;

private double total()
{
   sumOfAllItems = 0;
   for (int i = 0; i < numbers.Length; i++)
    {
        sumOfAllItems += numbers[i];
    }

    return sumOfAllItems;
}

It would be more efficient too to cache the mean rather than recalculating it inside the variance function - it's not going to change. Something like:

public double variance()
{
    // each (value - mean) squared
    double dMean - mean();
    double summationsTotal = 0; // (numbers[i] - mean() squared

    for (int i = 0; i < numbers.Length; i++)
    {
        summationsTotal += Math.Pow(numbers[i] - dMmean, 2);
    }

    return summationsTotal / (numbers.Length - 1);
}

You need to take the square root of the square of differences and then average them. So add a square root in there. And when you do the division don't use -1 as you are not dealing with indexing but the actual count of the items.

You are recalculating total() many times without zeroing it first. So your total gets large wrong value. For quick fix you should zero the sumOfAllItems variable in your total() method. But you would do better if you too calculated the mean() just for one time in variance() before entering the for loop. Your code will get faster.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top