Получение 0 пытается вычислить стандартное отклонение
У меня проблема с тем, что я пытаюсь вычислить стандартное отклонение, но я просто получаю значение 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
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]
сумма: 15
intervalForMath.size: 29
размер этого: 29
AverageDistFromMean: 0.0
сигма: 1,0
стандартное отклонение: 0,0
1 ответ
Вы выполняете целочисленное деление, которое часто будет возвращать (несколько) неожиданные результаты.
Когда вы делите два целых числа, результат вычисляется как целое число, а затем конвертируется в двойное число. Таким образом, вы теряете ту точность, которая вам нужна.
Приведение одного (или обоих) целых чисел к двойному значению даст вам то, что вы ожидаете.
double averageDistFromMean = sum / (double)sizeofthis;