Question

I'm having a problem where I'm trying to calculate the standard deviation but I'm just ending up with a value of 0.

The code is below, but the problem is occurring on these lines:

    int sizeofthis = intervalsForMath.size();
    Log.d("sizeofThis", "" + sizeofthis);
    double averageDistFromMean = sum/sizeofthis;

I've tried using int or float instead, but I'm still getting a result of zero, when it should be around 0.5.

I'll paste the LogCat output below, in case that helps.

Does anyone have any ideas?

public ArrayList<Integer> DoMathStdDev(ArrayList<Integer> intervalsForMath) {


    ArrayList<Integer> timeDataCalc = new ArrayList<Integer>(); // Array to contain the recently calculated bpms and delay times            

    timeDataCalc.add(0, (intervalsForMath.get(intervalsForMath.size() - 1))); // Get Last Interval
    ArrayList <Integer> sanitisedIntervalsForMath = new ArrayList<Integer>(); //Create Array to hold array with unusual entries removed
    if (intervalsForMath.size() >= 4) { //Only want to get standard deviation if the array has 4 values or more
    int sum = 0; //reset sum
    for (int ii = 0; ii < intervalsForMath.size(); ii++) { 
        sum = sum + (intervalsForMath.get(ii)); //create total of all the entries as sum
    }
    int average = (sum / (intervalsForMath.size())); //take average from the total (sum) divided by intervals size
    Log.d("average", "" + average); //I'll put the results of the log at the bottom

    // calculate distance from mean of all indices
    ArrayList<Integer> distFromMean = new ArrayList<Integer>(); //Create arraylist for DistFrom Mean
    for (int i = 0; i < intervalsForMath.size(); i++) {
        distFromMean.add(i, (intervalsForMath.get(i)-average)); //Create DistFromMean, distance from average for each entry
    }
    Log.d("distFromMean", "" + distFromMean);

    sum = 0; //reset sum
    for (int iii = 0; iii < distFromMean.size(); iii++) {
        sum = sum + (distFromMean.get(iii)); //create total of all the entries as sum
    }
    Log.d("sum", "" + sum);
    Log.d("intervalsForMath.size", "" + intervalsForMath.size());
    int sizeofthis = intervalsForMath.size();
    Log.d("sizeofThis", "" + sizeofthis);
    double averageDistFromMean = sum/sizeofthis;
    Log.d("averageDistFromMean", "" + averageDistFromMean);
    double stdDeviation = sigma*(Math.sqrt(averageDistFromMean)); //take average from that and square root it for StdDev and times it by the sigma amount
    Log.d("sigma", "" + sigma);
    Log.d("stdDeviation", "" + stdDeviation);


        // I THINK YOU CAN IGNORE EVERYTHING BELOW HERE


    //remove intervals that fall outside the standard deviation

    for (int iiii = 0; iiii < intervalsForMath.size(); iiii++) { //For each index in intervals for Math
        if (intervalsForMath.get(iiii) <= (average+stdDeviation) || intervalsForMath.get(iiii) >= (average-stdDeviation))  { // Check if the entry is inside the standard deviation
            sanitisedIntervalsForMath.add(intervalsForMath.get(iiii)); //Add entries that pass that check into the sanitisedIntervalsForMath array
        }       
    }

    } else {
        for (int iiiii = 0; iiiii < intervalsForMath.size(); iiiii++) {
            sanitisedIntervalsForMath.add(iiiii, intervalsForMath.get(iiiii));
        }
    }

    int numberOfIndices;
    if (sanitisedIntervalsForMath.size() <= 3) {
        numberOfIndices = sanitisedIntervalsForMath.size();
    } else {
        numberOfIndices = 4;
    }

    if (numberOfIndices == 1) {

        timeDataCalc.add(1,
                (sanitisedIntervalsForMath.get(intervalsForMath.size() - 1)));
        timeDataCalc.add(2,
                (sanitisedIntervalsForMath.get(intervalsForMath.size() - 1)));
        timeDataCalc.add(3,
                (sanitisedIntervalsForMath.get(intervalsForMath.size() - 1)));
        timeDataCalc.add(4,
                (sanitisedIntervalsForMath.get(intervalsForMath.size() - 1)));

    } else {
        // Get last 4 intervals represented as WXYZ

        ArrayList<Integer> intervalsWXYZ = new ArrayList<Integer>();
        for (int i = (sanitisedIntervalsForMath.size()) - numberOfIndices; i < sanitisedIntervalsForMath
                .size(); i++) {
            intervalsWXYZ.add(sanitisedIntervalsForMath.get(i));
        }

        // Get last4BeatsMedian, add it to timeDataCalc index 1
        Collections.sort(intervalsWXYZ);
        if ((intervalsWXYZ.size() % 2) == 0) {
            timeDataCalc.add(1,((intervalsWXYZ.get((int) ((intervalsWXYZ.size() / (float) 2) - 1))) + (intervalsWXYZ.get((int) ((intervalsWXYZ.size() / ((float) 2)) + 0)))) / 2);
        } else {
            timeDataCalc.add(1, (intervalsWXYZ.get((int) (intervalsWXYZ.size() / (float) 2))));
        }
        // Get last4BeatsMean, add it to timeDataCalc index 2
        int sum = 0;
        for (int i = 0; i < intervalsWXYZ.size(); i++) {
            sum = sum + (intervalsWXYZ.get(i));
        }
        timeDataCalc.add(2, (sum / (intervalsWXYZ.size())));
        intervalsWXYZ.clear();

        // Get Whole Session Median & Mean

        if (intervalsForMath.size() >= 4) {

            // Get Whole Session Median, add it to timeDataCalc index 3

            ArrayList<Integer> intervalsWhole = new ArrayList<Integer>();
            for (int i = 0; i < sanitisedIntervalsForMath.size(); i++) {
                intervalsWhole.add(sanitisedIntervalsForMath.get(i));
            }
            Collections.sort(intervalsWhole);
            if ((intervalsWhole.size() % 2) == 0) {
                timeDataCalc
                        .add(3,
                                ((intervalsWhole.get((int) ((intervalsWhole
                                        .size() / (float) 2) - 1))) + (intervalsWhole
                                        .get((int) ((intervalsWhole.size() / ((float) 2)) + 0)))) / 2);
            } else {
                timeDataCalc.add(3, (intervalsWhole
                        .get((int) (intervalsWhole.size() / (float) 2))));
            }

            // Get Whole Session Mean, add it to timeDataCalc index 4
            sum = 0; //reset sum
            for (int ii = 0; ii < intervalsWhole.size(); ii++) {
                sum = sum + (intervalsWhole.get(ii)); //create total of all the entries as sum
            }
            int average = (sum / (intervalsWhole.size())); //take average from that
            timeDataCalc.add(4, average);
            intervalsWhole.clear();
        }
    }


    return timeDataCalc;
}

Logcat output:

Average: 264

distFromMean: [-264,224,28,17,-50,-78,-42,-94,-89,-94,-76,-105,-107,39,-96,-90,-92,-413,-107,-88,-114,-93,-100,-92,32,-127,-125,-93,1478]

sum: 15

intervalsForMath.size: 29

sizeofThis: 29

averageDistFromMean: 0.0

sigma: 1.0

stdDeviation: 0.0

Was it helpful?

Solution

You are performing integer division, which will often return (somewhat) unexpected results.

When you divide two integers, the result is calculated as an integer, then converted to a double. Thus you lose the precision that you need.

Casting one (or both) of your integers to a double like so will produce you what you expect.

double averageDistFromMean = sum / (double)sizeofthis;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top