[an error occurred while processing this directive]
Самое оптимальное при необходимости "экономить вычисления" - комбинация из "скользящего средневзвешенного" с отбрасываним минимальных и максимальных значений.
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)

миниатюрный аудио-видеорекордер mAVR

Отправлено Abc123 21 октября 2002 г. 12:24
В ответ на: каким алгоритмом лучше всего усреднять полученный результат? отправлено Romario 19 октября 2002 г. 16:08


Очень экономные результаты дает такая метода:
1) Выбираем параметр количества отбрасываемых крайних
(минимальных / максимальных) значений, например Nmin=Nmax=1

2) выбираем длину фильтра (количество усредняемых значений),
например, Navg = 4

3) Выбираем коэффициенты (весА), тривиальный случай
"скользяещего среднего", когда коэффициенты = 1.
Но если хочется "новым" значениям присвоить больший вес
- пожалуйста. Если нет ограничений на использование плавающей
точки, тогда бери коэффициенты КИХ-фильтра "по науке" и вперед...
(это тема отдельного разговора),
рассмотрим случай, приближеннный к микроконтроллерным задачам,
т.е. ежели режим "строжайшей экономии":
- все вычисления "только в целых числах",
- никаких "делений" (только сдвиги)
- никаких "умножений" (только сдвиги и/или сложения)
то, например,
Вариант_1: K[] = 1, 2, 2, 3 ( "сумма K[i]" = AvgDiv = 8 )
или
Вариант_2: K[] = 1, 3, 5, 7 ( "сумма K[i]" = AvgDiv = 16 )


4) Буфер значений имеет длину Nbuf = Nmin + Navg + Nmax = 1+4+1 = 6

5) Еще 2 переменных нужны для индексов крайних значений
Imin, Imax

6) При поступлении нового значения X:
- вычисляем Imin, Imax,
- из всего буфера "сырых значений" ( X [6] )
рассматриваем все кроме крайних ( Xm[4] )
и по ним вычисляем "средневзвешенное"

Avg = ( Xm[1] * K[1]
+ Xm[2] * K[2]
+ Xm[3] * K[3]
+ Xm[4] * K[4]
) / AvgDiv;

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

Вариант_1: K[] = 1, 2, 2, 3 ( "сумма K[i]" = AvgDiv = 8 )

Avg = ( Xm[1]
+ ( Xm[2] + Xm[2] )
+ ( Xm[3] + Xm[3] )
+ ( Xm[4] + Xm[4] + Xm[4] )
) >> 3;

Вариант_2: K[] = 1, 3, 5, 7 ( "сумма K[i]" = AvgDiv = 16 )

Avg = ( Xm[1]
+ ( Xm[2] << 1 + Xm[2] ) // x*3 -> x*2+x
+ ( Xm[3] << 2 + Xm[3] ) // x*5 -> x*4+x
+ ( Xm[4] << 3 - Xm[4] ) // x*7 -> x*8-x
) >> 4; // /= 16


Аналогично можно построить и для
Nmin = Mmax = 2
Navg = 32
Nbuf = 2+2+32 = 36


Составить ответ  |||  Конференция  |||  Архив

Ответы



Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание  |||  Без кадра

E-mail: info@telesys.ru