分散・標準偏差の1ループ計算法
一般
分散・標準偏差を計算するために一般にはつぎの2つのループが必要である。
- 平均を求めるループ
- 二乗和を求めるループ
double sdNormal(long long int n) { double average = 0.0; for (long long int i=0; i<n; i++) { average += i; } average = average / n; double sd = 0.0; for (long long int i=0; i<n; i++) { sd += (i - average)*(i - average); } return sqrt(sd/n); }
1ループ計算法
しかし次のように分散・標準偏差の式を変形するとループは1つで済む。
σ∵σ2=n1i=1∑n(xi−xˉ)2=n1i=1∑nxi2−(n1i=1∑nxi)2=n1i=1∑n(xi−xˉ)2=n1i=1∑n(xi2−2xixˉ+xˉ2)=n1i−1∑nxi2−2xˉn1i=1∑nxi+n1i=1∑nxˉ2=(n1i=1∑nxi2)−2xˉ2+xˉ2=(n1i=1∑nxi2)−xˉ2=n1i=1∑nxi2−(n1i=1∑nxi)2double sdNew(long long int n) { double sum = 0.0; double sum2 = 0.0; for (long long int i=0; i<n; i++) { sum += i; sum2 += i*i; } return sqrt(sum2/n - (sum/n)*(sum/n)); }
参考
sdNormal()の処理時間を1.0とするとsdNew()は約0.9となった。
コンパイラで最適化を指定するとsdNormal()の1.0に対し約0.5となった。
🌏 Map
same layer | lower layer |
---|---|