java - 尝试计算标准差时收到 0

标签 java android math standard-deviation

我遇到了一个问题,我试图计算标准差,但最终得到的值为 0。

代码如下,但问题出现在这些行上:

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

我尝试使用 int 或 float 代替,但结果仍然为零,而它应该在 0.5 左右。

我将在下面粘贴 LogCat 输出,以防有帮助。

有人有什么想法吗?

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 输出:

平均:264

距离平均值:[-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]

总和:15

intervalsForMath.size:29

大小:29

平均距离:0.0

西格玛:1.0

标准偏差:0.0

最佳答案

您正在执行整数除法,这通常会返回(有些)意外的结果。

当您除两个整数时,结果将计算为整数,然后转换为 double 型。因此,您失去了所需的精度。

像这样将一个(或两个)整数转换为 double 将产生您所期望的结果。

double averageDistFromMean = sum / (double)sizeofthis;

关于java - 尝试计算标准差时收到 0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19282235/

相关文章:

java - 我应该使用什么查询来使用 Jsoup 从 html 页面中提取符号?

java - 如何在java中保存日期(dd.mm.yyyy)

java - 如何在Javafx中设置全屏或最大化所有场景

android - 迁移到 FormsApplicationActivity 导致 NavigationRenderer 出现异常

android - 从服务器获取主题颜色并在整个android应用程序中更改它的好方法是什么?

java - HttpURLConnection 很慢

java - 非法状态异常 : Content has been consumed - How to resolve?

python - 操作顺序如何在 Python 上进行?

C++定点库?

algorithm - 随机一个 512 位整数 N,它不是 2、3 或 5 的倍数