Арифметическое скользящее среднее

Алгоритмизация / Арифметическое скользящее среднее

При обработке экспериментальных данных часто возникает необходимость их усреднения. С этой целью часто используют алгоритм арифметического скользящего среднего.
Скользящее среднее — общее название для семейства функций, значения которых в каждой точке определения равны среднему значению исходной функции за предыдущий период. Скользящие средние обычно используются с данными временных рядов для сглаживания краткосрочных колебаний и выделения основных тенденций или циклов. Математически скользящее среднее является одним из видов свертки и поэтому его можно рассматривать как фильтр низких частот, используемых в обработке сигналов.
Простое (арифметическое) скользящее среднее численно равно среднему арифметическому значений исходной функции за установленный период и вычисляется по формуле:
Скользящее среднее
где fi – исходные значения рассматриваемой функции; h=k-l – сглаживающий интервал – количество значений исходной функции для расчета скользящего среднего.
На рисунке представлены функции скользящего среднего для исходной последовательности значений с разной величиной сглаживающего интервала.
Скользящее среднее с разным интервалом усреднения
Чем шире сглаживающий интервал, тем более плавным будет график результирующей функции.
Однако с другой стороны, увеличение сглаживающего интервала приводит к временному сдвигу усредненной функции относительно исходной.
Из предыдущего своего значения простое скользящее среднее может быть получено по следующей рекуррентной формуле:

Рекуррентная формула скользящего среднего
где fk-h — значение исходной функции в точке k-h (в случае временного ряда, самое «раннее» значение исходной функции, используемое для вычисления предыдущей скользящей средней), fk— значение исследуемой функции точке k (последнее значение).
При реализации рекуррентной формулы удобно использовать массив для хранения значений сглаживающего интервала, а также переменную, содержащую сумму этих значений.

Реализация

#include <iostream>
#include <stdlib.h>
using namespace std;
// Задание начального набора значений
double ** getData(int n) {
  double **f;
  f = new double* [3];
  f[0] = new double[n];
  f[1] = new double[n];
  f[2] = new double[n];
  for(int i=0; i<n; i++) {
    f[0][i] = (double)i;
    f[1][i] = 8*(double)i - 3;
  // Добавление случайной составляющей
  //f[1][i] = 8*(double)i - 3 + ((rand()%100)-50)*0.05;
  }
  return f;
}
// Вычисление результата скользящего среднего
void getMA(double **x, int n, int size) {
  // size - количество отсчетов интервала усреднения
  double sumx = 0; // сумма отсчетов на интервале
  double *mas; // массив для хранения size отсчетов
  int index = 0; // индекс элемента массива
  mas = new double[size];
  for(int i=0; i<size; i++) mas[i] = 0;
  for(int i=0; i<n; i++) {
    sumx -= mas[index];
    mas[index] = x[1][i];
    sumx += mas[index];
    index++;
    if(index >= size)
      index = 0; // возврат к началу "окна"
    x[2][i] = sumx / size;
  }
  return;
}
int main() {
  double **x;
  int n, h;
  system("chcp 1251");
  system("cls");
  cout << "Введите количество точек: ";
  cin >> n;
  cout << "Введите сглаживающий интервал: ";
  cin >> h;
  x = getData(n);
  getMA(x, n, h);
  for(int i=0; i<n; i++)
    cout << x[0][i] << " - " << x[1][i] << " - " << x[2][i] << endl;
  getchar(); getchar();
  return 0;
}

Результат выполнения
Скользящее среднее: консоль
График функции скользящего среднего с интервалом усреднения h=4 для данных, приведенных здесь, показан на рисунке.
Скользящее среднее: график

Назад

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *