» Программирование>Как сделать "усреднитель" битовой последовательноости.
dr.ON 21:56 15.09.2008
Как программно сделать аналог RC-цепочки на которую поступает прямоугольный сигнал( 0 - 1)
нада вычислить грубо говоря скользящее соотношение "1" и "0".
т.е.
...11000101010... - результат 50%
...100100100100... - 33%
...110110110110... - 66%
************************************************
sum = sum * 0.999 + X * 0.001
где X = 1 или 0
( ну это правда совсем извращения( нелинейность))
хотя не так уж и звращенно. Работает красиво. ************************************************
if( X == 1)
{
sum = sum + ( ( 1 - sum) / 1000)
}
else
{
sum = sum - ( sum / 1000)
}
Ктонибудь знает как проще?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^
P.S. Забыл сказать - это нужно для реализации на 8ми битном микроконтроллере и следовательно решения в лоб( типа выделяем массив на N бит( кольцевой), кидаем туда биты и каждый раз пересчитываем "1" и "0" и делим вконце) неприемлемы.
P.S.Пока решил по первому методу
uint16 sum;
.............
sum -= ( sum >> 8);
if( X)
{
sum += 256;
}
.............
[Ответ]
lukas 13:56 16.09.2008
а отчего пересчитывать неприемлемо? сколько есть тактов на всякое? тот уинт16 как колцевой буфер использовать. считать както так http://en.wikipedia.org/wiki/Popcount говорят, на некоторых архитектурах даже спец инструкция такая есть.
[Ответ]
dr.ON 16:03 16.09.2008
Сообщение от lukas:
а отчего пересчитывать неприемлемо? сколько есть тактов на всякое?...
От того что усреднять хочется например ~512 последних бит.
Это многовато.
[Ответ]
MadFish 16:58 16.09.2008
dr.ON, а чем не подходит школьная арифметика? 512 бит=100 % 1 бит = 0.1953125 %
пришла 1 добавили 0.1953125 нолик отняли?
[Ответ]
dr.ON 18:00 16.09.2008
Сообщение от MadFish:
dr.ON, а чем не подходит школьная арифметика? 512 бит=100 % 1 бит = 0.1953125 %
пришла 1 добавили 0.1953125 нолик отняли?
А какой результат будет у последовательности 10101010101..... ? А должен быть 50%
************************************************
Еще одно решение( но оно посложнее первого)
..........
if( ( cnt1 > 512) || ( cnt0 > 512))
{
cnt0 = cnt0 / 2;
cnt1 = cnt1 / 2;
}
if( X == 1)
{
cnt1++;
}
else
{
cnt0++;
}
res = cnt1 * 100 / ( cnt1 + cnt0)
.........................
[Ответ]
lordv 10:29 17.09.2008
Нет, с усреднением не пойдёт, как я и предполагал.
Смотри, если у тебя последовательность шла вначале из одних нулей - у тебя наполняется cnt0.
Допустим, единиц вообще не было.
Далее, при превышении порога в 512 cnt0 ополовинивается и становится равным 256.
Допустим, дальше пошли одни единицы - у тебя среднее будет расти 0 до 0.66, и тут у тебя cnt1 достигает порога в 512.
cnt1 ополовинивается и равен 256.
Далее опять идут одни единицы.
Среднее скачком падает до 0.33, затем растёт до 0.66, пока cnt1 опять не переполняется.
Далее опять идут единицы, и опять среднее меняется от 0.33 до 0.66.
И так далее.
Т.е. функция среднего сигнала для данной последовательности будет иметь пилообразный вид с максимумом 0.66, а в реальности она должна быть гладкой и асимпотически стремиться к единице.
Хотя, если характер распределение единиц более-менее случайный (Гауссово распределение, например), то такой алгоритм, скорее всего, подойдёт, хотя математически доказать, наверное, уже не смогу, позабыл всё :-)
[Ответ]
dr.ON 11:23 17.09.2008
Сообщение от lordv:
Смотри, если у тебя последовательность шла вначале из одних нулей - у тебя наполняется cnt0.
Допустим, единиц вообще не было.
Далее, при превышении порога в 512 cnt0 ополовинивается и становится равным 256.
Допустим, дальше пошли одни единицы - у тебя среднее будет расти 0 до 0.66, и тут у тебя cnt1 достигает порога в 512.
cnt1 ополовинивается и равен 256.
+ ополовинивается cnt0
= 256 / ( 256 + 128) ~ 0, 66
Никаких скачков не будет
[Ответ]
][irurg 16:15 18.09.2008
простите что вмешиваюсь, не понял чем вариант MadFish не устроил?
Сообщение от dr.ON:
у последовательности10101010101..... ?
из 512 бит получается 256 "1", = 256*0,1953%=49,996% , что и требовалось доказать. нули просто не учитываем ..
[Ответ]
dr.ON 18:13 18.09.2008
Сообщение от ][irurg:
из 512 бит получается 256 "1", = 256*0,1953%=49,996% , что и требовалось доказать. нули просто не учитываем ..
После этого пошли еще 512 бит ...101010...
что получится ?
а должно 50%!
тока он предлагал так:
101010
..+0,1953%-0,1953%+0,1953%-0,1953%+0,1953%-0,1953%+0,1953%-0,1953%...
и того значение не меняется и "трусится" в произвольной точке сколь угодно долго
[Ответ]
][irurg 11:36 19.09.2008
секунду. условие было
Сообщение от dr.ON:
усреднять хочется например ~512 последних бит.
т.е. количесвто бит известно заранее.
он просто ошибся в ниписании, имел ввиду как понимаю: на 1 - прибавляем %, на 0 не делаем ничего. получаем соотв % "1". если наоброт - процент "0".
если известно общее количество бит, то способ самый правильный имхо
почему кстати нельзя просто считать соотношение?
if (X==1) sum1+=1;
sum+=1;
sred1=100*sum1/sum; // percent of "1"
sred0=100-sred1; // percent of "0"
[Ответ]
dr.ON 12:35 19.09.2008
Сообщение от ][irurg:
т.е. количесвто бит известно заранее.
Нет приблизительно. Эта задача для оценки мгновенного соотношения 1 и 0 в бесконечной последовательности в окне размером примерно 512.
Я же в самом начале написал СКОЛЬЗЯЩЕЕ( и даже выделил жирным).
т.е. загнал 512 бит получил результат.
загнал еще один, опять получил и т.д.
т.е. НАПРИМЕР +-
учитываем
с 0го по 511 бит
затем с 1 по 512
2 ... 513
..........
[Ответ]
DeniSS1 16:03 19.09.2008
Проще никак. Потому что для
Сообщение от dr.ON:
с 0го по 511 бит
затем с 1 по 512
2 ... 513
..........
тебе нужно знать последовательность битов.
Поясню про
Сообщение от dr.ON:
sum = sum * 0.999 + X * 0.001
где X = 1 или 0
Допустим, есть последовательность из 1000 битов (считать проще), идущих чередованием 0101... Поступает 1. Мы имеем промежуток 10101...101. В нём 502 единицы и 498 нулей. Получается 50.2% единиц. Считаем по формуле. sum = 50 * 0.999 + 1 * 0.001 = 49.95 + 0.001 = 49.951. На первый взгляд разница не существенна, но если дальше если каждый второй бит будет единицей, то получится лажа
Единственный выход, который вижу: хранить небольшое кол-во битов (например, 64 или 128) и считать тоже самое скользящее соотношение для них.
[Ответ]
dr.ON 09:36 22.09.2008
Сообщение от DeniSS1:
имеем промежуток 10101...101. В нём 502 единицы и 498 нулей.....
Мне кажется 501/499 ( но это ерунда)
Сообщение от DeniSS1:
Получается 50.2% единиц. Считаем по формуле. sum = 50 * 0.999 + 1 * 0.001 = 49.95 + 0.001 = 49.951. На первый взгляд разница не существенна, но если дальше если каждый второй бит будет единицей, то получится лажа
Дальше плохо понимаю.
Вот график и и сама "модель" в экселе ( 100% = 65535)
P.S. Битовая последовательность шумоподобная( 1010.. и т.д. это для проверки алгоритмов)
Хранить требуемое колво бит нет возможности и не нужно.
Изображения