C++Guns – RoboBlog

18.02.2015

rosettacode - Simple moving average

Filed under: Allgemein — Tags: , , — Thomas @ 12:02

http://rosettacode.org/wiki/Averages/Simple_moving_average#C.2B.2B

The original rosetta C example shows the usage of variable function arguments. The C++ example shows how to implement a circular buffer. They are confusing and inefficient. My Version shows how to implement a simple moving average using modern c++ techniques.


#include < iostream >
#include < vector >

class SMA {
public:
    SMA(int period) : values(period), sum(0.0), idx(0), size(0) {
    }

    void add(double value) {
        const size_t period = values.size();
        // here is the magic. Update sum and vector in place
        sum = sum - values[idx] + value;
        values[idx] = value;

        // this implements the circular buffer
        idx = (idx+1)%period;
        if(size+1 <= period) {
            ++size;
        }
    }

    double avg() const {
        return sum/size;
    }

private:
    // store the last seen values
    std::vector values;
    // store the sum. so we dont have to recalculate it every time
    double sum;
    // the next element in the buffer we can override
    int idx;
    // ho many values was allready inserted. This is usually the same as the given periodb
    size_t size;
};

int main() {
    SMA foo(3);
    SMA bar(5);

    std::vector data = { 1, 2, 3, 4, 5, 5, 4, 3, 2, 1 };

    for(auto &val : data) {
        foo.add(val);
        std::cout << "Added " << val << " avg: " << foo.avg() << std::endl;
    }
    std::cout << std::endl;

    for(auto &val : data) {
        bar.add(val);
        std::cout << "Added " << val << " avg: " << bar.avg() << std::endl;
    }

    return 0;
}


No Comments

No comments yet.

RSS feed for comments on this post.

Sorry, the comment form is closed at this time.

Powered by WordPress