Standard deviation function

Feb 20, 2016 at 1:57am
I've been trying to write a code for standard deviation and I thought I nearly had it, but it's still slightly off. Could I please get some help? It's getting a bit frustrating.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
double arrStdDev(int array[], int length){
  double mean = 0;
  double sum = 0;
  double var = 0;
  double avg = 0;
  for(int i = 0; i < length; i++){
    if(length > 0){
      mean += array[i];
      avg = mean /= length;
      sum += (array[i] - avg)*(array[i] - avg);
      var = sum / length;
      return sqrt(var);
    }else{
      return 0;
    }
  }
  return 0;
}
Feb 20, 2016 at 2:29am

but it's still slightly off.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// my population standard deviation function
double stdDev(const int arr[], const int& size)
{
    double mean{};
    for(int a{}; a < size; a++) mean += (double)arr[a];
    mean /= size;
    
    double var{};   // variance
    for(int b{}; b < size; b++) {
        // calculate the difference from the mean
        double diff{ arr[b] - mean };
        // square the difference
        var += diff * diff;
    }
    // variance is the average of the above
    var /= size;
    
    return sqrt(var);
}


stdDev = 1.41421
arrStdDev = 0.357771


I don't think it's slightly off.

The problem with your function is that you calculate the mean once per loop, length times, when you're meant to loop through the whole array, get the sum and divide that by the size of the array.

http://cpp.sh/7fz4b
Last edited on Feb 20, 2016 at 2:33am
Feb 20, 2016 at 3:00am
Okay, sorry, it was more messed up than I thought.
I took the code you gave and changed around some syntax to suit my assignment/machine (my version won't allow me to do whatever you did with the braces, i have to declare them normally), and I'm still failing the tests I'm running..
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
double arrStdDev(const int arr[], const int& size){
  if(size > 0){
  double mean = 0;
  for(int a = 0; a < size; a++){
    mean += (double)arr[a];
    mean /= size;
  }
  double var = 0;  
  for(int t = 0; t < size; t++){
    double diff =  arr[t] - mean;
    var += diff * diff;
  }
  var /= size;
  return sqrt(var);
  }else{
    return 0;
  }
}


These are the tests I'm running:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  void testStdDev2() {
    int a[] = {1,2,3};
    TS_ASSERT_EQUALS(arrStdDev(a, 3), 0.816);
  }
  
  void testStdDev3() {
    int a[] = {1,2,3,4,5};
    TS_ASSERT_EQUALS(arrStdDev(a, 5), 1.414);
  }
  
  void testStdDev4() {
    int a[] = {1,2,3,4};
    TS_ASSERT_EQUALS(arrStdDev(a, 4), 1.118);
  }


In MyTests::testStdDev2:
stats_test.h:100: Error: Expected (arrStdDev(a, 3) == 0.816), found (1.1024 != 0.8160)
In MyTests::testStdDev3:
stats_test.h:105: Error: Expected (arrStdDev(a, 5) == 1.414), found (2.2989 != 1.4139)
In MyTests::testStdDev4:
stats_test.h:110: Error: Expected (arrStdDev(a, 4) == 1.118), found (1.6975 != 1.1180)
Last edited on Feb 20, 2016 at 3:01am
Feb 20, 2016 at 3:12am
1
2
3
4
  for(int a = 0; a < size; a++){
    mean += (double)arr[a];
    mean /= size;
  }


Move that outside the loop.


my version won't allow me to do whatever you did with the braces


It's called uniform initialisation, a C++11 feature.
http://www.stroustrup.com/C++11FAQ.html#uniform-init
Last edited on Feb 20, 2016 at 3:16am
Feb 20, 2016 at 3:15am
Alright. I think that improved it a bit, but the tests are still failing. What else may be a problem?
Running cxxtest tests (28 tests).................
In MyTests::testStdDev2:
stats_test.h:100: Error: Expected (arrStdDev(a, 3) == 0.816), found (0.8164 != 0.8160)
In MyTests::testStdDev3:
stats_test.h:105: Error: Expected (arrStdDev(a, 5) == 1.414), found (1.4142 != 1.4139)
In MyTests::testStdDev4:
stats_test.h:110: Error: Expected (arrStdDev(a, 4) == 1.118), found (1.1180 != 1.1180)

(and thank you for helping me, I appreciate it)
Feb 20, 2016 at 3:25am
Because of floating point comparisons.
https://isocpp.org/wiki/faq/newbie#floating-point-arith
Feb 20, 2016 at 3:32am
I'm still confused..the instructions for my assignment said to return the final result as a double. Should I be swapping all my = signs with the isEqual command?
Feb 20, 2016 at 3:44am
I don't know what you're trying to ask.
You've fixed the standard deviation calculations but because they're a floating point value, there is no true way to test the equality.
As far as I'm concerned, you've fixed your problem which was the standard deviation function.

Sorry if this sounds like I'm insulting you.
Feb 20, 2016 at 3:49am
It's okay, I'm just frustrated because this lab is due in an hour and I've now finished every part besides this one, which is preventing me from submitting it for grading properly.

I need to know how to modify the code so that it passes unit tests, because as it is I'm getting a 0% in that category. Can I change the code away from floating point values so that it outputs what the unit test wants?
Feb 20, 2016 at 4:27am
You could try to return the value truncated to three decimals, something like:

return static_cast<int>(sqrt(var) * 1000) / 1000.0;
Feb 20, 2016 at 4:31am
Hey that worked! Thanks a ton, I really appreciate it. And thanks integralfx for helping me fix the initial calculations.
Feb 20, 2016 at 8:09am
Hi,

Should I be swapping all my = signs with the isEqual command?


Yes !! :+D, but it is the == not =
Feb 20, 2016 at 10:46am
Hello! Can anyone help me with this ? http://www.cplusplus.com/forum/beginner/185007/
Feb 20, 2016 at 2:13pm
@fizrub

Please don't bust into someone else's Topic. You have your own topic, so post something there, and it will be pushed to the top of the list again.

Anyway, you had an answer to your last question. Write a new question in your Topic stating what you don't understand.
Topic archived. No new replies allowed.