2013-06-11 121 views
1

我將公式轉換爲C++。這是正確的運行標準偏差。計算運行標準偏差

this->runningStandardDeviation = (this->sumOfProcessedSquaredSamples - sumSquaredDividedBySampleCount)/(sampleCount - 1); 

以下是完整的功能:

void BM_Functions::standardDeviationForRunningSamples (float samples [], int sampleCount) 
{ 
    // update the running process samples count 
    this->totalSamplesProcessed += sampleCount; 

    // get the mean of the samples 
    double mean = meanForSamples(samples, sampleCount); 

    // sum the deviations 
    // sum the squared deviations 
    for (int i = 0; i < sampleCount; i++) 
    { 
     // update the deviation sum of processed samples 
     double deviation = samples[i] - mean; 
     this->sumOfProcessedSamples += deviation; 

     // update the squared deviations sum 
     double deviationSquared = deviation * deviation; 
     this->sumOfProcessedSquaredSamples += deviationSquared; 
    } 

    // get the sum squared 
    double sumSquared = this->sumOfProcessedSamples * this->sumOfProcessedSamples; 

    // get the sum/N 
    double sumSquaredDividedBySampleCount = sumSquared/this->totalSamplesProcessed; 

    this->runningStandardDeviation = sqrt((this->sumOfProcessedSquaredSamples -  sumSquaredDividedBySampleCount)/(sampleCount - 1)); 
} 
+1

'sumOfProcessedSquaredSamples - sumSquaredDividedBySampleCount'看起來可疑,您可以加入一些意見,以顯示你想要達到的目標每個變量是什麼意思?謝謝。 – cxyzs7

+0

也不應該有一個平方根的地方? – user829755

+0

謝謝,錯過了平方根。爲什麼方程顯示σ*σ= ...而不是σ= sqrt(....)? – jarryd

回答

1

您可以檢查是否有足夠sampleSount(1會導致除數爲零)

確保該變量具有合適的數據類型(浮點)

否則此外觀正確...

+0

關於數據類型。我在所有這些方程中都使用雙打。這是低效的嗎?我會在一段時間內完成這個圖書館,所以電腦只會更強大。未來的證明?我認爲如果任何音頻程序員故意傳遞1,它應該會崩潰,如果它的副作用崩潰可能會突出問題。 – jarryd

7

數字用於計算運行均值和方差/ SD的穩定和高效的算法是Welford's algorithm

一個C++實現是:

std::pair<double,double> getMeanVariance(const std::vector<double>& vec) { 
    double mean = 0, M2 = 0, variance = 0; 

    size_t n = vec.size(); 
    for(size_t i = 0; i < n; ++i) { 
     double delta = vec[i] - mean; 
     mean += delta/(i + 1); 
     M2 += delta * (vec[i] - mean); 
     variance = M2/(i + 1); 
     if (i >= 2) { 
      // <-- You can use the running mean and variance here 
     } 
    } 

    return std::make_pair(mean, variance); 
} 

注:獲得SD,只取sqrt(variance)

+0

如果你可以看看,我已經添加了我的實現。我昨天「正式」以C++開始,所以請原諒任何錯誤。 – jarryd

+0

我會投票改變「穩定」到「更穩定」。而與這些浮點部門,我不會對效率如此確定... –

+0

有效的一次運行,沒有調整到完美(這將使得它很難得到的算法)。如果你知道一種方法來計算沒有分裂的均值或方差,我很樂意聽到它。 – smocking