趣味は車輪の再発明♪

[C++] 移動平均を計算するテンプレートクラス


詳解 OpenCV ―コンピュータビジョンライブラリを使った画像処理・認識
Gary Bradski Adrian Kaehler
オライリージャパン
売り上げランキング: 25,746


■ たかみんつ / ソフト開発メモINDEX / C++インデックス /


数値データの移動平均を得るためのテンプレートクラスです。

平均回数をコンストラクタで指定してインスタンスを生成し、生データをupdateメソッドに与えれば平均値が返されます。

指定回数に満たない場合も、平均値が返されます。isStableメソッドがfalseを返しますので、不要なら無視してください。

MovingAverage.h

#include <deque>
template<class InputType, class InnerAvgType=double,
    class AvgType=InputType>
class MovingAverage {
    int average_count;
    std::deque<InputType> buffer;
    InnerAvgType average;
public:
    MovingAverage() : average_count(1), average(0) { }
    MovingAverage(int average_count)
        : average_count(average_count), average(0)
    {
        assert(average_count > 0);
    }
    
    int getAverageCount() const {
        return average_count;   
    }
    void setAverageCount(int n) {
        assert(n > 0);
        average_count = n;
        reset();
    }
    
    // reset average value and counter.
    void reset() {
        average = 0;
        buffer.clear();
    }
    // average value stability
    bool isStable() const {
        return buffer.size() >= average_count;
    } 
    // update and return average value
    AvgType update(const InputType& input) {
        InnerAvgType total = average * buffer.size();
        if(buffer.size() >= average_count) {
            total -= buffer.at(0);
            buffer.pop_front();
        }
        buffer.push_back(input);
        total += (InnerAvgType)input;
        average = total / buffer.size();
        return (AvgType)average;
    }
    operator AvgType () {
        return (AvgType)average;
    }
};

GitHub Gist takamin/MovingAverage.h に置いてあります。どうぞご自由にご利用ください。

test.cpp というか使い方ですw

#include <iostream>
#include <assert.h>
#include "MovingAverage.h"
int main(int argc, char*argv[]) {
    MovingAverage<int> intAverager(5);
    int data[]      = {
        1,2,3,4,5,6,7,8,9,10,9,8,7,
        6,5,4,3,2,1,0,0,0,0,0,0,0};
    for(int i = 0; i < sizeof(data)/sizeof(data[0]); i++) {
        int average = intAverager.update(data[i]);
        std::cerr << "input " << data[i]
            << " average = " << average << std::endl;
    }
}

MinGWのg++で動作確認しています。


Pythonプロフェッショナルプログラミング 第2版
秀和システム (2015-05-21)
売り上げランキング: 1,813


クラウドではじめる機械学習 Azure MLでらくらく体験
脇森浩志 杉山雅和 羽生貴史
リックテレコム
売り上げランキング: 2,081

実践Node.js プログラミング (Programmer's SELECTION)
Mike Cantelon Marc Harter T.J. Holowaychuk Nathan Rajlich
翔泳社
売り上げランキング: 40,213

■ たかみんつ / ソフト開発メモINDEX / C++インデックス /



RSS Feed Widget
[C++] 移動平均を計算するテンプレートクラス
(http://bicycle.life.coocan.jp/takamints/index.php/doc/cplusplus/MovingAverage)
by Koji Takami ( email: vzg03566@gmail.com, GitHub: takamin )