Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: ADSP усреднение на лету
Форум разработчиков электроники ELECTRONIX.ru > Цифровая обработка сигналов - ЦОС (DSP) > Алгоритмы ЦОС (DSP)
uriy
Через SPORT принимаютя отсчеты, нужно находить их среднее значение на лету. Количество отсчетов заранее не известно.
Dr.NoA
Попробуйте формулу

avg(i)=[(n-1)*avg(i-1)+x(i)]/n,
где
avg - среднее значение;
x - значение нового отсчета;
n - общее количество обработанных отсчетов.

После получения первого отсчета n=1, поэтому
avg(1) = [(1-1)*0 + x1]/1 = x1

После второго n=2:
avg(2) = [(2-1)*x1 + x2]/2 = (x1+x2)/2

и т.д.
vetal
Если необходимо на лету, то подойдет система типа аккумулятор.
f(t)=(f(t-1)+x)/2 или f(t)=(f(t-1)+x)>>1, при t>0

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

см. ниже.
MakSV
Используй скользящее среднее в этом случае тебе потребуется предыдущее значение и полученное из них получишь скользящую (g+g2)/2=s1
(g2+g3)/2=s2
(gn-1+gn)/2=sn
Это по двум точкам, если будет желание можно и больше точек использовать
dxp
Цитата(vetal @ Dec 28 2005, 04:30) *
Если необходимо на лету, то подойдет система типа аккумулятор.
f(t)=(f(t-1)+x)/2 или f(t)=(f(t-1)+x)>>1, при t>0

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

Это разве среднее будет?
dxp
Цитата(urasinov @ Dec 27 2005, 18:43) *
Через SPORT принимаютя отсчеты, нужно находить их среднее значение на лету. Количество отсчетов заранее не известно.

Среднее - это по определению сумма всех значений отсчетов деленное на количество отсчетов. Т.е. придется складывать их в буфер и после каждого вновь поступившего пересчитывать. С суммированием пробем нет - просто к сумме, полученной на предыдущем этапе, добавлять вновь поступивший отсчет. А вот деление будет самым ресурсоемким, поскольку делить придется на произвольное число. В ADSP-21хх, насколько помню, есть аппаратная поддержка деления, выполняется за 16 тактов.

Если бы задача стояла (как обычно) в усреднении по некоторому известному количеству отсчетов, то тогда это решалось бы на основе циклического буфера, организуемого с помощью DAG, это штатный способ пропускания данных через фильтр. Но у Вас, похоже, другая задача, придется делить. Если количество отсчетов хоть и не известно, но ограничено и известен диапазон (например, количество неизвестно, но может быть от 14 до 41), то можно соптимизировать - найти обратные делителям (1/14..1/41), поместить их в таблицу и на рантайме выбирать из таблицы нужное значение и умножать на него. Будет намного шустрее.
vetal
Цитата(dxp @ Dec 28 2005, 09:14) *
Цитата(vetal @ Dec 28 2005, 04:30) *

Если необходимо на лету, то подойдет система типа аккумулятор.
f(t)=(f(t-1)+x)/2 или f(t)=(f(t-1)+x)>>1, при t>0

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

Это разве среднее будет?


Стормозил. Нельзя одновременно делать 2 задачи.
тогда так:
а(t)=a(t-1)+x;
n++;
f(x)=a(t)/n;
Dr.NoA
Цитата(vetal @ Dec 28 2005, 10:36) *
Стормозил. Нельзя одновременно делать 2 задачи.
тогда так:
а(t)=a(t-1)+x;
n++;
f(x)=a(t)/n;


Кажется, это тоже самое что и я предлагал.
uriy
dxp
Да вариант с коэффициентами из таблицы мне понравился. Количество отсчетов у меня не превышает 64, т.е. можно сперва их принять а уж потом подсчитать среднее. Только мне не понятно откуда взялись цифры 14 и 41, по-моему ничто не мешает взять коэффициент 1/64 это не такая уж малая величина.
Но все же мне интересно если у меня отсчеты будут идти в количестве несокльких миллионов я же не буду их все складывать в буфер. Может возможно зная текущее среднее обновить его значение приняв следующий отсчет.
Dr.NoA
Цитата(urasinov @ Dec 28 2005, 22:01) *
Но все же мне интересно если у меня отсчеты будут идти в количестве несокльких миллионов я же не буду их все складывать в буфер. Может возможно зная текущее среднее обновить его значение приняв следующий отсчет.

Если речь идет о произвольном количестве отсчетов (например, несколько миллионов), то нужно использовать вариант vetal'а или мой, т.к. хранить нужно только 2 переменные. Разница просто в том, что у vetal необходимо хранить накопленную сумму всех отсчетов, поэтому рано или поздно произойдет переполнение. В моем варианте хранится текущее среднее, поэтому переполнения не будет, но требуется лишнее умножение. Вторая переменная для хранения - это количество обработанных отсчетов. Буферов никаких не надо.
dxp
Цитата(urasinov @ Dec 29 2005, 01:01) *
dxp
Да вариант с коэффициентами из таблицы мне понравился. Количество отсчетов у меня не превышает 64, т.е. можно сперва их принять а уж потом подсчитать среднее.

Ну дык вот. Заводим массив со значениями 1/2...1/64, при приеме очередного отсчета добавляем его к сумме предыдущих, далее умножаем на значение из массива (значение какждый раз другое - следующее).

Цитата(urasinov @ Dec 29 2005, 01:01) *
Только мне не понятно откуда взялись цифры 14 и 41,

Да это к примеру просто привел.

Цитата(urasinov @ Dec 29 2005, 01:01) *
по-моему ничто не мешает взять коэффициент 1/64 это не такая уж малая величина.

Это значение будет годиться только для вычисления среднего по 64 отсчетам. Для 63 нужен будет коэффициент 1/63, для 62 - 1/62 и т.д. Т.е., как уже сказал выше, массив из таких значений. Он для ADSP-21хх небольшой, все должно получиться.

Цитата(urasinov @ Dec 29 2005, 01:01) *
Но все же мне интересно если у меня отсчеты будут идти в количестве несокльких миллионов я же не буду их все складывать в буфер. Может возможно зная текущее среднее обновить его значение приняв следующий отсчет.

Не надо никакой буфер. Все принятые отсчеты суммируюся, для них буфер не нужен. Если счет пойдет на миллионы, то делать массив коеффициентов тоже не варинат, придется честно делить. Только тут уж 16-разрядной арифметикой не обойдется.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.