sno*_*yak 10 java algorithm math angle
所以我正在使用罗盘角度(以度为单位)进行应用.我已经设法确定角度均值的计算,使用以下内容(可在http://en.wikipedia.org/wiki/Directional_statistics#The_fundamental_difference_between_linear_and_circular_statistics中找到):
double calcMean(ArrayList<Double> angles){
double sin = 0;
double cos = 0;
for(int i = 0; i < angles.size(); i++){
sin += Math.sin(angles.get(i) * (Math.PI/180.0));
cos += Math.cos(angles.get(i) * (Math.PI/180.0));
}
sin /= angles.size();
cos /= angles.size();
double result =Math.atan2(sin,cos)*(180/Math.PI);
if(cos > 0 && sin < 0) result += 360;
else if(cos < 0) result += 180;
return result;
}
Run Code Online (Sandbox Code Playgroud)
所以我正确地得到了我的平均值/平均值,但是我无法获得正确的方差/ stddev值.我很确定我正在计算我的方差不正确,但想不出正确的方法.
这是我如何计算方差:
double calcVariance(ArrayList<Double> angles){
//THIS IS WHERE I DON'T KNOW WHAT TO PUT
ArrayList<Double> normalizedList = new ArrayList<Double>();
for(int i = 0; i < angles.size(); i++){
double sin = Math.sin(angles.get(i) * (Math.PI/180));
double cos = Math.cos(angles.get(i) * (Math.PI/180));
normalizedList.add(Math.atan2(sin,cos)*(180/Math.PI));
}
double mean = calcMean(angles);
ArrayList<Double> squaredDifference = new ArrayList<Double>();
for(int i = 0; i < normalizedList.size(); i++){
squaredDifference.add(Math.pow(normalizedList.get(i) - mean,2));
}
double result = 0;
for(int i = 0; i < squaredDifference.size(); i++){
result+=squaredDifference.get(i);
}
return result/squaredDifference.size();
}
Run Code Online (Sandbox Code Playgroud)
虽然这是计算方差的正确方法,但我不是我应该使用的.我认为我应该使用arctangent,但标准偏差/方差值似乎是关闭的.救命?
编辑: 示例:输入值0,350,1,0,0,0,1,358,9,1结果,平均角度为0.0014(因为角度非常接近于零),但如果您只是进行非角度平均,你会得到72 ...这是关闭的.由于我不知道如何操纵个别值应该是什么,计算的方差是25074,导致标准偏差为158度,这是疯了!(它应该只有几度)我认为我需要做的是正确地标准化单个值,这样我就可以得到正确的方差/ stddev值.
Jon*_*oni 14
sqrt(-log R²)
如果您将样本视为单位圆上的复数,则通过维基百科页面链接到圆形标准差,其中R = |样本|的平均值.因此标准偏差的计算与平均角度的计算非常相似:
double calcStddev(ArrayList<Double> angles){
double sin = 0;
double cos = 0;
for(int i = 0; i < angles.size(); i++){
sin += Math.sin(angles.get(i) * (Math.PI/180.0));
cos += Math.cos(angles.get(i) * (Math.PI/180.0));
}
sin /= angles.size();
cos /= angles.size();
double stddev = Math.sqrt(-Math.log(sin*sin+cos*cos));
return stddev;
}
Run Code Online (Sandbox Code Playgroud)
如果你想一下它就有意义了:当你在单位圆上平均一堆彼此接近的点时,结果离圆圈不太远,所以R将接近1并且stddev接近0.如果点沿圆圈均匀分布,则它们的平均值将接近0,因此R将接近0并且stddev非常大.