2016-03-23 26 views
3

我很好奇,如果我的标准偏差方法可以提高效率。通过高效率我的意思是快速,而且我的意思是指从方法调用到方法返回的延迟。我的标准偏差计算可以更有效吗?

下面的代码:

public double stdDev(ArrayList<Double> input) { 

    double Nrecip = (1.0/(input.size())); 
    double sum  = 0.0; 
    double average = 0.0; 

    for (Double input : inputs) { 
     average += input; 
    } average *= Nrecip; 

    for (Double input : inputs) { 
     sum += ((input - average)*(input - average)); 
    } sum *= Nrecip; 

    return Math.sqrt(sum); 

} 

我将不胜感激任何意见。

+0

你可以做'平均+ = Nrecip *输入;',但不会做什么更快 –

+2

你可以使用'double'代替Double'的'和使用的一小部分记忆。 –

+0

计算'(输入 - 平均值)'而不是两次? –

回答

4

您可以一次计算标准偏差。使用double[]也会更有效。

public static double stdDev(double... a) { 
    double sum = 0; 
    double sq_sum = 0; 
    for (int i = 0; i < n; ++i) { 
     double ai = a[i]; 
     sum += ai; 
     sq_sum += ai * ai; 
    } 
    double mean = sum/n; 
    double variance = sq_sum/n - mean * mean; 
    return Math.sqrt(variance); 
} 

这该解决方案in C here

传递内存曾经可以提高性能的转换。

+0

很好的答案,谢谢。 “double ... a”是什么意思?我不熟悉那种语法。另外,我正在使用'ArrayList ',因为这个方法通常会以循环方式使用,所以使用'ArrayList'可以进行简单的更新。两种数据结构之间的速度损失是否显着?我认为'ArrayList'有恒定的时间读取。 – d0rmLife

+1

@ d0rmLife ArrayList是一个常量时间,创建'new Double'的成本也是如此,但常数因子更高。使用'double..'就像一个数组,但是你可以使用'double d = stdDev(1,2,3,4,5);'使用'double []'可以使用' ArrayList '这可以在开始使用CPU缓存时发挥作用。 –

+1

@ d0rmLife这里是一个包装一个'double []'但行为像一个ArrayList的类的例子http://trove4j.sourceforge.net/javadocs/gnu/trove/list/array/TDoubleArrayList.html –

0

使用org.apache.commons.math3.stat.descriptive

public double stdDev(ArrayList<Double> input) { 

    DescriptiveStatistics ds = new DescriptiveStatistics(input.toArray(new Double[0])); 

    return ds.getStandardDeviation(); 

}