How to resolve the algorithm Averages/Simple moving average step by step in the C++ programming language

Published on 7 June 2024 03:52 AM

How to resolve the algorithm Averages/Simple moving average step by step in the C++ programming language

Table of Contents

Problem Statement

Computing the simple moving average of a series of numbers. Create a stateful function/class/instance that takes a period and returns a routine that takes a number as argument and returns a simple moving average of its arguments so far. A simple moving average is a method for computing an average of a stream of numbers by only averaging the last   P   numbers from the stream,   where   P   is known as the period. It can be implemented by calling an initialing routine with   P   as its argument,   I(P),   which should then return a routine that when called with individual, successive members of a stream of numbers, computes the mean of (up to), the last   P   of them, lets call this   SMA(). The word   stateful   in the task description refers to the need for   SMA()   to remember certain information between calls to it:

Stateful   also means that successive calls to   I(),   the initializer,   should return separate routines that do   not   share saved state so they could be used on two independent streams of data. Pseudo-code for an implementation of   SMA   is:

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Averages/Simple moving average step by step in the C++ programming language

The provided C++ code demonstrates the implementation of a Simple Moving Average (SMA) algorithm for calculating the average of a sequence of values over a specified period. It involves a class named SMA that manages the values and provides methods to add new values and calculate the average.

Class Definition: The SMA class has the following member variables and methods:

  • Constructor: Initializes the SMA with a specified period (number of values to average over). It creates a dynamic array (window) of double values, initializes the head and tail pointers, and sets the total to 0.
  • Destructor: Deallocates the dynamic array window.
  • add: Adds a new value to the average. It handles initialization and circular buffer management by advancing the head and tail pointers as needed.
  • avg: Returns the average of the last P elements added to the SMA. If no elements have been added, it returns 0.0.
  • inc: Helper method that increments a pointer within the circular buffer, wrapping around if necessary.
  • size: Helper method that returns the number of values stored in the SMA.

Main Function: The main function creates two instances of the SMA class with periods of 3 and 5, respectively. It then iterates through an array of data values and adds them to the SMAs. After each addition, it prints the added value and the calculated average.

How it Works: The SMA algorithm maintains a circular buffer of values. As new values are added, the oldest value is removed from the buffer, and the new value is added to the end of the buffer. The average is then calculated as the sum of all values in the buffer divided by the number of values.

In this specific implementation, the head and tail pointers are used to keep track of the oldest and newest values in the buffer. The total variable stores the sum of all values in the buffer to efficiently calculate the average without having to sum the entire buffer each time.

The code demonstrates the use of SMAs to calculate the average of data over different periods, showcasing how the average changes as new values are added.

Source code in the cpp programming language

#include <iostream>
#include <stddef.h>
#include <assert.h>

using std::cout;
using std::endl;

class SMA {
public:
	SMA(unsigned int period) :
		period(period), window(new double[period]), head(NULL), tail(NULL),
				total(0) {
		assert(period >= 1);
	}
	~SMA() {
		delete[] window;
	}

	// Adds a value to the average, pushing one out if nescessary
	void add(double val) {
		// Special case: Initialization
		if (head == NULL) {
			head = window;
			*head = val;
			tail = head;
			inc(tail);
			total = val;
			return;
		}

		// Were we already full?
		if (head == tail) {
			// Fix total-cache
			total -= *head;
			// Make room
			inc(head);
		}

		// Write the value in the next spot.
		*tail = val;
		inc(tail);

		// Update our total-cache
		total += val;
	}

	// Returns the average of the last P elements added to this SMA.
	// If no elements have been added yet, returns 0.0
	double avg() const {
		ptrdiff_t size = this->size();
		if (size == 0) {
			return 0; // No entries => 0 average
		}
		return total / (double) size; // Cast to double for floating point arithmetic
	}

private:
	unsigned int period;
	double * window; // Holds the values to calculate the average of.

	// Logically, head is before tail
	double * head; // Points at the oldest element we've stored.
	double * tail; // Points at the newest element we've stored.

	double total; // Cache the total so we don't sum everything each time.

	// Bumps the given pointer up by one.
	// Wraps to the start of the array if needed.
	void inc(double * & p) {
		if (++p >= window + period) {
			p = window;
		}
	}

	// Returns how many numbers we have stored.
	ptrdiff_t size() const {
		if (head == NULL)
			return 0;
		if (head == tail)
			return period;
		return (period + tail - head) % period;
	}
};

int main(int argc, char * * argv) {
	SMA foo(3);
	SMA bar(5);

	int data[] = { 1, 2, 3, 4, 5, 5, 4, 3, 2, 1 };
	for (int * itr = data; itr < data + 10; itr++) {
		foo.add(*itr);
		cout << "Added " << *itr << " avg: " << foo.avg() << endl;
	}
	cout << endl;
	for (int * itr = data; itr < data + 10; itr++) {
		bar.add(*itr);
		cout << "Added " << *itr << " avg: " << bar.avg() << endl;
	}

	return 0;
}


  

You may also check:How to resolve the algorithm Loops/While step by step in the Retro programming language
You may also check:How to resolve the algorithm Text processing/2 step by step in the Ada programming language
You may also check:How to resolve the algorithm Word wrap step by step in the R programming language
You may also check:How to resolve the algorithm Substring/Top and tail step by step in the sed programming language
You may also check:How to resolve the algorithm Zig-zag matrix step by step in the PL/I programming language