Как лучше искать среднее, если мы знаем только 2 последних значения - страница 3

 
George Merts:

Почему ? На мой взгляд - если получается экспотенциальное, то среднее тем более получается. А если не получается обычного среднего - то и экспотенциального не получить.

Впрочем - выше уже правильно написали, надо хранить не все значения, а только сумму, и количество.

Имеется в виду два значения: последнее значение ряда и сумму предыдущих. Для расчета простого скользящего среднего за n периодов нужно три значения: последнее значение ряда, значение ряда n-периодов назад и сумму.

Как это реализовать на практике я показал на примере. 

 

Для простой средней надо не три значения, а n значений, где n равно периоду средней.

Для экспоненциальной нужно только одно новое значение, и рассчитанное ранее значение средней. 

 
Dmitry Fedoseev:

Для простой средней надо не три значения, а n значений, где n равно периоду средней.

Для экспоненциальной нужно только одно новое значение, и рассчитанное ранее значение средней. 

Он, видимо, имел в виду, что после того, как мы первый раз посчитали простую среднюю, используя n значений, то в последующих расчетах уже надо не n значений, а всего лишь 3... это оптимизация расчетов такая.
 
Marat Sultanov:
Он, видимо, имел в виду, что после того, как мы первый раз посчитали простую среднюю, используя n значений, то в последующих расчетах уже надо не n значений, а всего лишь 3... это оптимизация расчетов такая.
Но третье значение сдвинуто на n, поэтому нужно где то хранить все n значений, или иметь доступ к истории на глубину n. Здесь число 3 не показательно.
 
Dmitry Fedoseev:
Но третье значение сдвинуто на n, поэтому нужно где то хранить все n значений, или иметь доступ к истории на глубину n. Здесь число 3 не показательно.
ну так а чем плох пример со статическими переменными, предложенный ранее? ) мы там и храним n значений и общую сумму, затем просто прибывляем новое значение если оно появилось и заново пересчитываем
 
Dmitry Fedoseev:
Но третье значение сдвинуто на n, поэтому нужно где то хранить все n значений, или иметь доступ к истории на глубину n. Здесь число 3 не показательно.

Не обязательно. Зная последнюю сумму, первые значения этой суммы можно с помощью буфера хранить, тогда следующую среднюю можно без проблем посчитать используя 3 значения.

Но это целесообразно если нам нужна средняя с указанным периодом. 

Грубо говоря:

void OnStart()
{
   double Res = 0;
  
   Res = GetMa(1);
   Res = GetMa(2);
   Res = GetMa(3);
   Res = GetMa(4);
   Res = GetMa(5);
   Res = GetMa(6);
   Res = GetMa(7);
   Res = GetMa(8);
   Res = GetMa(9);
  
   Print(Res);
}


const int MAPeriod = 3;

double Summ     = 0;
int    Count    = 0;
double ValsBuf[];
int    LastIndex = 0;

double GetMa(const double new_value)
{
   if (Count < MAPeriod)
   {
      if (Count == 0)
      {
         Summ  = 0;
        
         ArrayResize(ValsBuf, MAPeriod); ArrayInitialize(ValsBuf, 0);
        
         LastIndex = 0;
      }
      
      Summ += new_value;
      
      ValsBuf[Count] = new_value;
      
      ++Count;
      
      return Summ/Count;
   }
  
   Summ -= ValsBuf[LastIndex];
   Summ += new_value;
  
   ValsBuf[LastIndex] = new_value;
  
   ++LastIndex;
  
   if (LastIndex >= MAPeriod) LastIndex = 0;
  
   return Summ/MAPeriod;
}
Добавлено: Да, приходится использовать буфер для хранения, как вы и сказали, но по ресурсам затрата ведь минимальная, верно?
 
изначально была задача посчитать среднее арифметическое а не скользящую среднюю вообще-то ) зачем мне скользящая средняя для проскальзываний? :)) если бы мне нужна была СК я бы просто хранил очередь значений нужного размера и считал бы через MAonArray. Хотя.. может быть и есть смысл именно в скользящей средней.. но это уже детали
 
Maxim Dmitrievsky:
изначально была задача посчитать среднее арифметическое а не скользящую среднюю вообще-то )

Да, просто разговор ушел в другое русло, а именно как можно быстро посчитать среднюю для случая, когда есть период средней :)

если бы мне нужна была СК я бы просто хранил очередь значений нужного размера и считал бы через MAonArray

Если использовать MAonArray. Таким способом будет лишнюю оперативки жрать (если хранить все значения в буфере без перераспределения при появлении нового значения, т.е. расширяя буфер)... Либо лишняя затрата ресурсов на работу с памятью (придется сдвигать все значения в буфере при появлении нового), в случае, если размер буфера равно периоду средней.

зачем мне скользящая средняя для проскальзываний? :))

Да понятно, что незачем, конечно, но вдруг кому-то нужна будет средняя проскальзываний за последние n значений ;)

 

Marat Sultanov:

...


Добавлено: Да, приходится использовать буфер для хранения, как вы и сказали, но по ресурсам затрата ведь минимальная, верно?

Хорошо сделано, с кольцевым буфером, без лишних вычислений.