Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Вопросы по итеративному декодированию
Форум разработчиков электроники ELECTRONIX.ru > Цифровая обработка сигналов - ЦОС (DSP) > Алгоритмы ЦОС (DSP)
Страницы: 1, 2, 3, 4, 5
des00
наткнулся в сети на вот такой документ на странице 11 приведены интересные размеры блоков кодирования, которых нет в IEEE Std 802.16-2009/2012. Причем в таблице на этой странице приведены режимы кодирования OFDM которыми даже не пахнет в стандарте. И какой то режим SC2. Прошел поиском по стандартам, тишина. Гугл на вопрос Wimax SC2 mode тоже молчит. Неужели это банальный Single Carrier ?
andyp
Цитата(des00 @ Mar 11 2015, 20:24) *
наткнулся в сети на вот такой документ на странице 11 приведены интересные размеры блоков кодирования, которых нет в IEEE Std 802.16-2009/2012. Причем в таблице на этой странице приведены режимы кодирования OFDM которыми даже не пахнет в стандарте. И какой то режим SC2. Прошел поиском по стандартам, тишина. Гугл на вопрос Wimax SC2 mode тоже молчит. Неужели это банальный Single Carrier ?



Документ начинается на букву С, что значит contribution для рассмотрения комитетом. Видимо, это предложение комитет по стандартизации не убедило. В стандарте вроде нет TCC для SC модуляции.
des00
Мучаю кодек в режиме wimax-ofdm и прихожу к выводу, что фраза про возможные размеры блока кодирования от 8 до 1024 байт (см. приложение), с ограничением только на кратность 7ми не соответствуют действительности. Необходимо наложить условие что размер блока должен быть кратен 4-м байтам (например делаю проверку 20/24байта работает, 21/22/23/25/26 нет). Судя по всему, используемые ими блоки явно или неявно соответствуют этому условию. Правда мне не совсем понятно что это за магическое число 32 и как оно связано с решеткой.

Занятная фишка в DVB/Wimax-OFDMA перемежители определены для j = 0..N-1, а вот wimax-OFDM j = 1..N (см. приложение). И пары инвертируются тоже другие. Все это в пределах одного стандарта. Забавно sm.gif
andyp
Цитата(des00 @ Mar 12 2015, 13:34) *
Мучаю кодек в режиме wimax-ofdm и прихожу к выводу, что фраза про возможные размеры блока кодирования от 8 до 1024 байт (см. приложение), с ограничением только на кратность 7ми не соответствуют действительности. Необходимо наложить условие что размер блока должен быть кратен 4-м байтам (например делаю проверку 20/24байта работает, 21/22/23/25/26 нет). Судя по всему, используемые ими блоки явно или неявно соответствуют этому условию. Правда мне не совсем понятно что это за магическое число 32 и как оно связано с решеткой.


21 не подходит. Кратно 7. На счет остальных размеров - не знаю. В WiMAX OFDMA эти размеры не используется. Таких слотов не бывает (Писал уже, что минимальный размер кодового блока определяется слотом и всегда кратен слотам, это собственно и дает кратность 6 байтам для размеров блоков, описанных в стандарте. Минимальный слот - 48 поднесущих * 2 (QPSK) / 2 (наименьшая скорость кодера) = 6 байт)

В OFDM тоже узкий набор блоков используется (таблица 8-45) минимальный кодовый блок 6*Nsubch пар, но не меньше 8 байт. Nsubch = 1,2,4,8,16, т.е. 12 байт.

Цитата
Занятная фишка в DVB/Wimax-OFDMA перемежители определены для j = 0..N-1, а вот wimax-OFDM j = 1..N (см. приложение). И пары инвертируются тоже другие. Все это в пределах одного стандарта. Забавно sm.gif


Пары инвертируются одни и те же (используются инверсные условия для перестановки пар). Вот интерливеры - да, разные.

PS Стандарт писался с большой кровью, OFDMА здорово позже, чем OFDM. В первых версиях было полно багов.
des00
Цитата(andyp @ Mar 12 2015, 18:46) *
21 не подходит. Кратно 7. На счет остальных размеров - не знаю. В WiMAX OFDMA эти размеры не используется.....

про 21 да, написал на автомате. По остальным размерам вот характерный пример : в приложении результат сравнения блоков OFDMA 6/12/18 байт и тех же блоков OFDM (выбран лучший перемежитель) на одном и том же кодеке. Видно что если размер OFDM не кратен 4 байтам, то результаты сильно хуже OFDMA. В баги и недоработки я охотно верю, но все это осталось и в редакции 2012 года(!!!), недоработка же видна не вооруженным глазом.

Судя по всему, я неправильно понял смысл фразы в стандарте
Цитата
For all the frame sizes, k is a multiple of 8 and N is a multiple of 4. N shall be limited to: 8 <= N/4 <= 1024
Распространив это на любые размеры произвольных данных кодирования, а она относилась к любым размерами блоков используемых в конкретном стандарте sad.gif Эх, а так бы хотелось мягкий кодек с вариацией пакетов данных с точностью до байта в диапазоне 6-1024 (без усечения кода) sm.gif
Цитата
Пары инвертируются одни и те же (используются инверсные условия для перестановки пар). Вот интерливеры - да, разные.

Сыплю голову пеплом, по OFDMA пробежался, увидел похожесть на DVB и пропустил момент что условие другое, инвертируется другая пара чем в DVB sad.gif А вот интерливер не просто другой, а совсем другой, в OFDMA он как в DVB и первый адрес перемежения == 1, тогда как в OFDM == P0+1

PS. а каким именно документом вы пользуетесь по Wimax ? у меня ieee802.16-2009 и ieee802-16-2012. Там таблицы 8-45 нет, там сквозная нумерация через весь документ.
andyp
Цитата(des00 @ Mar 12 2015, 18:25) *
в приложении результат сравнения блоков OFDMA 6/12/18 байт и тех же блоков OFDM (выбран лучший перемежитель) на одном и том же кодеке. Видно что если размер OFDM не кратен 4 байтам, то результаты сильно хуже OFDMA. В баги и недоработки я охотно верю, но все это осталось и в редакции 2012 года(!!!), недоработка же видна не вооруженным глазом.


OFDMA появилось позже, поэтому там кое-что пофиксили. Старый кодек для OFDM нельзя было менять, так как народ уже железо во всю делал. Когда принимали стандарт, этого не учли, так и приходится с этим жить. Теперь уже все - новые изменения выбьют все старое работающее железо, а это миллиарды баксов.

Цитата
Эх а так бы хотелось мягкий кодек с вариацией пакетов данных с точностью до байта в диапазоне 6-1024 (без усечения кода) sm.gif


Чудес не бывает на коротких кодовых блоках по теореме Шеннона. Инфа о каждом информационном бите должна быть
размазана по большому количеству передаваемых бит.

Цитата
PS. а каким именно документом вы пользуетесь по Wimax ? у меня ieee802.16-2009 и ieee802-16-2012. Там таблицы 8-45 нет, там сквозная нумерация через весь документ.


Отсюда
http://standards.ieee.org/getieee802/downl...802.16-2012.pdf
Форму заполняешь и скачиваешь.
файл 18 мегабайт, форум закачать не дает.
des00
Цитата(andyp @ Mar 13 2015, 00:15) *
Чудес не бывает на коротких кодовых блоках по теореме Шеннона.

Согласен, но я немного о другом. Кодек в котором можно было бы поставить размер фрейма 200-256 байт, с гранулярностью размера блока в 1 байт, был бы совсем не лишним. Намного проще вариьировать параметры фреймов в радиоканале, под разные задачи.
Цитата
Отсюда

Спасибо, у меня в документах это была таблица 255 (сплошная магия чисел 2^8-1 sm.gif)
andyp
Цитата(des00 @ Mar 12 2015, 19:35) *
Согласен, но я немного о другом. Кодек в котором можно было бы поставить размер фрейма 200-256 байт, с гранулярностью размера блока в 1 байт, был бы совсем не лишним. Намного проще вариьировать параметры фреймов в радиоканале, под разные задачи.


Ну тут уже сталкиваемся с недостатками турбо-кодов. Спектр кода зависит от интерливера. Интерливер зависит от размеров блока. Вообще говоря, дуобинарный турбо-код wimax - большое достижение. Стоит вспомнить первые интерливеры - индексы вообще не генерировались на лету, только лукап. Все работало только для небольшого количества размеров кодовых блоков. Вторая итерация - интерливер 3GPP - рассчеты по модулю простого числа в реальном времени. Жесть.
des00
Цитата(andyp @ Mar 12 2015, 23:51) *
Спектр кода зависит от интерливера. Интерливер зависит от размеров блока.

В порядке эксперимента, хотел сделать нестандартный размер блока и пробовал методом подбора, на основе логических умозаключений, найти параметры интерливера. Шаг влево-вправо приравнивается к побегу. В итоге бросил. Тут похоже надо собирать стенд измерения спектра кода и его оценивать.
andyp
Цитата(des00 @ Mar 12 2015, 20:26) *
В порядке эксперимента, хотел сделать нестандартный размер блока и пробовал методом подбора, на основе логических умозаключений, найти параметры интерливера. Шаг влево-вправо приравнивается к побегу. В итоге бросил. Тут похоже надо собирать стенд измерения спектра кода и его оценивать.


Ну да. Это лучше не трогать, если полного понимания нет. У меня нет. В идеале, к словам с малым весом первого кодера долны прицепляться слова с большим весом второго. Это должно работать для большинства кодовых слов. Оставшиеся слова с малым весом дадут error floor.

PS Вобщем, все это имеет отношение к spectral thinning и interleaver gain, что впрочем совсем не объясняет, как синтезируются хорошие интерливеры с просто получаемыми индексами для больших наборов кодовых блоков. Про это я ничего не читал sad.gif и как инженер приходил на готовенькое.
smoke_111
Для 3GPP турбокода используется, как мне помнится, QPP-интерливер, в принципе его несложно пересчитать для нужного размера кодового блока, как правило получается прилично, наверно возможно прилепить его и дуо бинари коду.
И да, для нестандартного кодового блока условие цикличности выполняется?
des00
Цитата(smoke_111 @ Mar 13 2015, 13:39) *
И да, для нестандартного кодового блока условие цикличности выполняется?

насколько я понял условие цикличности, она выполняется всегда когда размер блока в битах не кратен 7.
des00
Решил немного порыть RCS в ширь, интересуют решетки с 16 ти состояниями. Порылся в сети, кроме документов с результатами (рвет решетку с 8 состояниями как тузик грелку), нашел документ 2013 года : предложения к DVB-RCS2, там есть схема кодера, и его полиномы, но нет перемежителя. По остальному ничего не нарылось. Может есть у кого более подробная информация о таком кодере? Спасибо.

PS. Или там тот же самый перемежитель что и в DVB-RCS (в смысле те же самые длины фреймов и параметры перемежения) ?
andyp
Цитата(des00 @ Mar 19 2015, 19:28) *
PS. Или там тот же самый перемежитель что и в DVB-RCS (в смысле те же самые длины фреймов и параметры перемежения) ?


Вот что нашлось:

Нажмите для просмотра прикрепленного файла

Teodor B. Iliev, Georgi V. Hristov, Plamen Z. Zahariev, Mihail P. Iliev Performance of the Duo-Binary Turbo Codes in WiMAX Systems

Статья есть в книжке

@book{book:343999,
title = {Novel Algorithms and Techniques in Telecommunications and Networking},
author = {Tarek Sobh, Khaled Elleithy, Ausif Mahmood},
publisher = {Springer},
isbn = {904813661X,9789048136612},
year = {2010},
series = {},
edition = {1st Edition.},
volume = {},
url = {http://gen.lib.rus.ec/book/index.php?md5=4EB39F68FE046888CD1458FCE938C107}
}

Может, еще это будет представлять интерес:
C. Berrou, Y. Saouter, C. Douillard, S. Kerouйdan, and M. Jйzйquel,
”Designing good permutations for turbo codes: Toward a single model,”
in Proceedings of IEEE International Conference on Communication,
Paris, France, 2004, pp. 341–345.
des00
Цитата(andyp @ Mar 20 2015, 02:42) *
Вот что нашлось:

Спасибо, покопаюсь в этих материалах.

До кучи нашел занятный документ: даташит на декодер S7000. Пишут что размер блока может быть с гранулярностью в 1 байт.
andyp
Цитата(des00 @ Mar 20 2015, 09:08) *
До кучи нашел занятный документ: даташит на декодер S7000. Пишут что размер блока может быть с гранулярностью в 1 байт.


Какой-то вид circular ARP, как у Berrou, судя по тому, что длины, кратные 15, запрещены и есть ограничение на общую длину блока.
des00
Цитата(andyp @ Mar 20 2015, 16:00) *
Какой-то вид circular ARP, как у Berrou, судя по тому, что длины, кратные 15, запрещены и есть ограничение на общую длину блока.

я понял по другому, что 15 это период решетки 2^4-1 (как 7 как у 2^3-1), и там выкалывания на скорости 3/5 и 5/6 не равномерные.
andyp
Цитата(des00 @ Mar 20 2015, 12:33) *
я понял по другому, что 15 это период решетки 2^4-1 (как 7 как у 2^3-1), и там выкалывания на скорости 3/5 и 5/6 не равномерные.


15 - период полиномов-генераторов, кратные длины запрещены из-за цикрулярности решетки кода. Ты просто не сможешь найти одинаковое начальное и конечное состояние кодера, чтобы получить циркулярную решетку - там вопрос упирается в существование инверсии для матрицы (I + G^k), k - длина блока. Про выкалывания уже говорили вроде. Равномерные возможны, только если числитель не делит период полиномов.
des00
Цитата(andyp @ Mar 20 2015, 17:58) *
15 - период полиномов-генераторов, кратные длины запрещены из-за цикрулярности решетки кода. Ты просто не сможешь найти одинаковое начальное и конечное состояние кодера, чтобы получить циркулярную решетку - там вопрос упирается в существование инверсии для матрицы (I + G^k), k - длина блока. Про выкалывания уже говорили вроде. Равномерные возможны, только если числитель не делит период полиномов.

Всё так. Мой пост был к тому, что они не скрывают "фичу" кодера с такими скоростями, тогда как в доках на декодеры типа wimax/dvb вопрос использования подобных скоростей обходится.
andyp
Цитата(des00 @ Mar 20 2015, 13:24) *
Всё так. Мой пост был к тому, что они не скрывают "фичу" кодера с такими скоростями, тогда как в доках на декодеры типа wimax/dvb вопрос использования подобных скоростей обходится.


Конечно, текст стандарта - не идеал. Люди ж пишут. В WiMax "правильные" кодовые блоки получаются благодаря алгоритму объединения слотов (явно там не указано, почему кратность 7 - табу). Icoding тоже, впрочем, не написал, почему у них блок должен быть кратен байту wink.gif. Скорее всего, используют цикл рандомизации в интерливере длиной 4. Мало того, вдруг у них где-нибудь в дизайне интерливера или выкалывания залет (про то и другое они вообще не пишут и проверить шансов нет)? Увидеть это можно будет только на определенной скорости и длине блока. Моделей, пускай и закрытых, они тоже вроде бы не дают, чтобы свои скорости и длины попробовать (хотя, могу и ошибаться).
des00
Возник тут у меня вопрос, из класса вопросов "нутром чувствую что литр, а доказать не могу" (с). Итак :
1. возьмем созвездие BPSK с точками 1+1i и -1-1i. Его мощность равна 2. Мягкое решение по такому созвездию будем считать как LLR = re + im
2. возьмем комплексный генератор AWGN шума. Получим SNR = 0дб, для этого сделаем мощность шума равной 2. Сложим с сигналом из пункта 1.
Для такой системы будет EbN0 = EsNo - 10*log10(1) = SNR - 10*log10(1) = 0дб.

3. возьмем созвездие BPSK с точками sqrt(2) и -sqrt(2). Его мощность равна 2. Мягкое решение по такому созвездию будем считать как LLR = re.
4. возьмем комплексный генератор AWGN шума из первого примера. Сложим с сигналом из пункта 3.
Чему для такой системы будет равно EbN0 ? По идее должно быть тоже самое, но ведь по сути, с этим сигналом мы работаем как с вещественным и отбросили мнимую часть шума. Т.е. уменьшили мощность шума в 2 раза и EbNo не помешало бы подправить. Так как правильно ?
andyp
Цитата(des00 @ Mar 25 2015, 15:47) *
Чему для такой системы будет равно EbN0 ? По идее должно быть тоже самое, но ведь по сути, с этим сигналом мы работаем как с вещественным и отбросили мнимую часть шума. Т.е. уменьшили мощность шума в 2 раза и EbNo не помешало бы подправить. Так как правильно ?


СПМ шума не изменилась от того, что ты повернул созвездие. Энеригия, затраченная на передачу бита тоже не изменилась, следовательно Eb/N0 осталось тем же самым.

Т.е. имеем два случая
1. Имеем два независимых AWGN канала с спм N0, по которым передаем параллельно одно и то же.
2. Сигнал с удвоенной энергетикой передается по AWGN каналу c спм N0.

Отношение Eb/N0 одинаковое. Формулы с картинки странные - не очень понятен конекст - при одинаковой длительности символа и SNR получаем вдвое худшее Es/N0, но при этом передаем двое меньшее количество бит на символ?
des00
Цитата(andyp @ Mar 25 2015, 22:11) *
Отношение Eb/N0 одинаковое. Формулы с картинки странные - не очень понятен конекст - при одинаковой длительности символа и SNR получаем вдвое худшее Es/N0, но при этом передаем двое меньшее количество бит на символ?

Это скан с хелпа матлаба. Смотреть по ключевой фразе "AWGN Сhannel Noise Level" там раздел "Relationship Between EsNo and SNR".

Все началось с простого скрипта :
Код
clear all;

format short;

EbNo = 3;
EsNo = EbNo + 10*log10(1);   % uncoded BPSK
SNR  = EsNo;

Nbits = 1e6;

msg = randi([0:1], 1, Nbits);

tx_symb = (2*msg-1) + 1i*(2*msg-1);
tx_symb1 = sqrt(2)*real(tx_symb);

% rx_symb  = awgn(tx_symb, SNR, 10*log10(2));
% rx_symb1 = awgn(tx_symb1, SNR, 10*log10(2));
rx_symb  = awgn(tx_symb, SNR, 'measured');
rx_symb1 = awgn(tx_symb1, SNR, 'measured');

hd_bits  = ((real(rx_symb) + imag(rx_symb)) >= 0);
hd_bits1 = (rx_symb1 >= 0);

ber = biterr(msg, hd_bits)/Nbits;
ber1 = biterr(msg, hd_bits1)/Nbits;

disp(['ber = ', num2str(ber), ' ber1 = ', num2str(ber1)]);

и вот результат ber = 0.022964 ber1 = 0.078718

если сделать правку
Код
rx_symb1 = awgn(tx_symb1, SNR+3, 'measured');

то результат более ожидаем ber = 0.02301 ber1 = 0.022947
Grizzzly
Для вещественных сигналов (созвездий) нужно добавлять 3 дБ.
Вы должны принимать решение по одномерному созвездию, то есть использовать только одну координату. Поворот не делает созвездие двумерным.

Код
rx_symb  = awgn(tx_symb, SNR+3, 'measured');
rx_symb1 = awgn(tx_symb1, SNR+3, 'measured');
hd_bits  = (real(rx_symb)>= 0);
hd_bits1 = (rx_symb1 >= 0);
serjj
Дело кажется в реализации функции awgn. Добавляю шум вручную:
Код
Ps = 2;
Pn = Ps * 10^(-SNR/10);
noise = randn(1, Nbits)+1j*randn(1, Nbits);
noise = noise * Pn;
Pn_meas = noise*noise'/Nbits;
rx_symb = tx_symb + noise;
rx_symb1 = tx_symb1 + real(noise);


Результат: ber = 0.07943 ber1 = 0.079298

Возможно там делается какая то нормировка.
Grizzzly
Цитата(serjj @ Mar 25 2015, 18:28) *

Нельзя BPSK рассматривать как двумерное созвездие.
Про комплекнсый и вещестыенный шум в справке по AWGN всё написано.
serjj
В функции awgn есть такая проверка
Код
% --- Add the noise
if(isreal(sig))
   opType = 'real';
else
   opType = 'complex';
end


Если в первом примере записать так:
Код
tx_symb = (2*msg-1) + 1i*(2*msg-1);
tx_symb1 = sqrt(2)*real(tx_symb) + 1i*1e-15;


То результаты для обоих созвездий примерно совпадают.

Цитата
Нельзя BPSK рассматривать как двумерное созвездие.

Почему? Это такой же комплексный сигнал как и остальные.
Grizzzly
Цитата(serjj @ Mar 25 2015, 18:40) *
Почему? Это такой же комплексный сигнал как и остальные.

Это одномерный сигнал. В решении участвует только одна координата. Поворот созвездия изменяет только направление измерения.
serjj
Вот в приведенном примере:
Код
hd_bits  = ((real(rx_symb) + imag(rx_symb)) >= 0);

Энергия для решения собирается с обеих координат иначе потеря в энергетике не менее 3 дБ (при условии 100% восстановленной фазы). К bpsk применимы все комплексные мат методы, что и для остальных psk, в т.ч. arg(x), которая не имеет смысла для вещественного/одномерного сигнала. Предлагаю спор о вещественности/материальности/еще-чего-то-там bpsk сигнала закрыть, что бы не засорять тему rolleyes.gif
Grizzzly
Цитата(serjj @ Mar 25 2015, 18:28) *
Результат: ber = 0.07943 ber1 = 0.079298


Для SNR = 3 дБ BER = 0.022964.

Цитата(serjj @ Mar 25 2015, 18:40) *
Если в первом примере записать так:
Код
tx_symb = (2*msg-1) + 1i*(2*msg-1);
tx_symb1 = sqrt(2)*real(tx_symb) + 1i*1e-15;

Вы изначально вещественный сигнал tx_symb1 сделали комплексным, тогда, естественно, в awgn нужно использовать SNR. В случае же вещественного сигнала - (SNR + 3).
Grizzzly
Да, вчера вечером затупил про одномерность повернутого BPSK...
Нашел в архиве статью про добавление белого шума к сигнальным отсчетам. Там как раз про 3 дБ говорится.
Нажмите для просмотра прикрепленного файла
Про различия СПМ - когда N0, а когда N0/2.
А в разделе "Relationship Among Eb/No, Es/No, and SNR Modes" говорится тоже самое, что в статье, только кратко: http://www.mathworks.com/help/comm/ref/awgnchannel.html
serjj
Почитал статью, спасибо. Но меня их подход решительно смутил. Выразили мощность полосового реального сигнала через 0-й отчёт автокорреляционной функции - ок, далее они говорят, что мощность комплексной огибающей на нуле такого сигнала можно выразить через сумму 0-х отчётов автокорреляционных функций квадратур re и im. Тоже нет вопросов. Но потом они удтверждают, что при переходе на комплексное представление сигнала мы имеем (математически) удвоение мощности, для этого они полагают, что максимум АКФ квадратур и АКФ полосового сигнала одинаковы по величине. Но пардонте, как же так?
Вот накида скрипт (взял ЛЧМ для примера) Нажмите для просмотра прикрепленного файла
Из него видно, что при переносе сигнала с ПЧ на ноль энергия делится между квадратурами, так что суммарная энергия не изменяется. Тоже и для шумового процесса: берем действительный шум, умножаем его на комплексную несущую и измеряем мощность полученных re и im компонент комплексного шумового процесса. В скрипте это тоже приведено. Что касается АКФ, получил вот такую картинку:
Нажмите для просмотра прикрепленного файла
Из неё видно, что в lag=0 АКФ полосового сигнала в 2 раза больше АКФ квадратуры.
В общем у меня много вопросов к статье. Получается, что там ищутся объяснения математическим эффектам, которые не проявляются в реальной жизни. Поправте, если я рассуждаю неверно, всегда готов учиться rolleyes.gif
Grizzzly
Да, при чтении меня тоже кое-что там смущало. Надо будет внимательнее посмотреть.
Сейчас просмотрел десяток учебников по Digital Communication, нигде ничего подобно нет. Есть только описание действительного шума с N0/2 и комплексного с N0.
des00
Цитата(Grizzzly @ Mar 25 2015, 23:23) *
Вы должны принимать решение по одномерному созвездию, то есть использовать только одну координату. Поворот не делает созвездие двумерным.

На каком основании именно должен? Есть квадратурный приемник, обработка идет в двух квадратурах. Как я их поверну для принятия решения дело десятое. Могу вообще перевести в полярные координаты и принимать решение по углу.

Цитата(serjj @ Mar 25 2015, 23:28) *
Дело кажется в реализации функции awgn. Добавляю шум вручную:

проверка sum(abs(rx_symb - tx_symb).^2)/Nbits и sum(abs(rx_symb1 - tx_symb1).^2)/Nbits показывает что мощность шума у вас там разная.

Цитата(serjj @ Mar 25 2015, 23:40) *
Если в первом примере записать так:
Код
tx_symb = (2*msg-1) + 1i*(2*msg-1);
tx_symb1 = sqrt(2)*real(tx_symb) + 1i*1e-15;


То результаты для обоих созвездий примерно совпадают.

Результат удивил. похоже что
Цитата
Возможно там делается какая то нормировка.

вы правы.
Grizzzly
Цитата(des00 @ Mar 26 2015, 12:28) *
На каком основании именно должен? Есть квадратурный приемник, обработка идет в двух квадратурах. Как я их поверну для принятия решения дело десятое. Могу вообще перевести в полярные координаты и принимать решение по углу.

С утра понял, что был неправ.
Цитата(des00 @ Mar 26 2015, 12:28) *
Результат удивил. похоже что
Цитата

Возможно там делается какая то нормировка.

вы правы.

Для комплексного сигнала мощность шума делится пополам между квадратурами, а для вещественного она целиком добавляется к нему.
Можно открыть функции awgn и wgn и посмотреть на эту реализацию.
Код
if(strcmp(cplxMode,'complex'))
   y = (sqrt(imp*noisePower/2))*(func(row, col)+1i*func(row, col));
else
   y = (sqrt(imp*noisePower))*func(row, col);
end;

noisePower = sigPower-reqSNR (в дБ) или noisePower = sigPower/reqSNR;
Для ВЕЩЕСТВЕННЫХ сигналов должна быть (noisePower/2), как в данном коде:
http://www.mathworks.com/matlabcentral/fil...tent/bpskAWGN.m

Вообще странно реализована функция awgn, в своё время с этим намучился, понял, что надо добавлять 3 дБ и успокоился, только сейчас так глубоко докопался. В Simulink таких проблем с AWGN Channel нет. Задаю для обычного BPSK Eb/N0 = 3 дБ и получаю BER =~0.025, что ожидаемо. Задаю BPSK с поворотом на 45 градусов против часой стрелки, получаю такой же BER. AWGN Channel правильно распознает типы данных и прибавляет нужный уровень шума.
serjj
Цитата
проверка sum(abs(rx_symb - tx_symb).^2)/Nbits и sum(abs(rx_symb1 - tx_symb1).^2)/Nbits показывает что мощность шума у вас там разная.

Точно. Нужно немного поправить, во первых я неправильно взвешивал шум, нужно так:
Код
noise = randn(1, Nbits)+1j*randn(1, Nbits);
noise = noise * sqrt(Pn/2);

А во-вторых:
Код
rx_symb = tx_symb + noise;
rx_symb1 = tx_symb1 + noise;

Даёт результат:
Код
ber = 0.022872 ber1 = 0.023012

и
Код
>> sum(abs(rx_symb - tx_symb).^2)/Nbits

ans =

    1.0017

>> sum(abs(rx_symb1 - tx_symb1).^2)/Nbits

ans =

    1.0017

В таком случае действительный сигнал tx_symb1 трактуется как комплексный с im=0.

Но вот другой интересный эффект заметил:
Формально, т.к. оба сигнала теперь считаются комплексными к ним должно применяться одно правило принятия решений:
Код
hd_bits  = ((real(rx_symb) + imag(rx_symb)) >= 0);
hd_bits1 = ((real(rx_symb1) + 1*imag(rx_symb1)) >= 0);

Но тогда получается
Код
ber = 0.023051 ber1 = 0.079219

А если второе созвездие предварительно развернуть:
Код
rx_symb1 = rx_symb1 * exp(1i*pi/4);

то получается
Код
ber = 0.02295 ber1 = 0.0228

Как же так?

Кажется нашел ответ на свой вопрос: правило
Код
hd_bits  = ((real(rx_symb) + imag(rx_symb)) >= 0);

Даёт лучший результат при 100% восстановленной фазе, т.е. при когерентном приёме, а в остальных случаях получаются потери вплоть до 3дБ, что соответствует некогерентному приёму. Так ли это?
des00
Цитата(serjj @ Mar 26 2015, 16:46) *
Но вот другой интересный эффект заметил:

Угу, я тоже его заметил. Похоже весь сыр бор вокруг вокруг вот этого
Код
if(strcmp(cplxMode,'complex'))
   y = (sqrt(imp*noisePower/2))*(func(row, col)+1i*func(row, col));
else
   y = (sqrt(imp*noisePower))*func(row, col);
end;

Правда не понятно как тогда быть обработкой "разных" BPSK. Так можно на 3дб ошибиться, а потом считать свой декодер супер-пупер крутым sm.gif
Grizzzly
Цитата(serjj @ Mar 26 2015, 12:53) *
Даёт лучший результат при 100% восстановленной фазе, т.е. при когерентном приёме, а в остальных случаях получаются потери вплоть до 3дБ, что соответствует некогерентному приёму. Так ли это?

Это я вчера так коряво с одномерным созвездием пытался объяснить этот случай rolleyes.gif
Да, теперь нужно знать точно фазу, поскольку используются две координаты.

Цитата(des00 @ Mar 26 2015, 12:53) *
Правда не понятно как тогда быть обработкой "разных" BPSK. Так можно на 3дб ошибиться, а потом считать свой декодер супер-пупер крутым sm.gif

Использовать Simulink, о чем я написал выше 08.gif Кстати, не пробовали использовать вместо awgn объект comm Симулинковского АБГШ? По идее там должно быть всё хорошо.
des00
Цитата(Grizzzly @ Mar 26 2015, 18:01) *
Кстати, не пробовали использовать вместо awgn объект comm Симулинковского АБГШ?

Пока еще нет, на досуге попробую sm.gif
serjj
Цитата
Правда не понятно как тогда быть обработкой "разных" BPSK.

Для BPSK с произвольным поворотом на угол ang от оси Ox правило принятия решения будет:
Код
a = cos(degtorad(ang));
b = sin(degtorad(ang));
hd_bits1 = ((a*real(rx_symb1) + b*imag(rx_symb1)) >= 0);

Это даёт BER порядка 0.023 для любых углов поворота при SNR=3 дБ.
Grizzzly
Провел тщательный эксперимент. biggrin.gif
В MATLAB pskmod для BPSK возвращает комплексные значения вида (+/-1 + j0). Поэтому awgn работает корректно. Ничего добавлять не нужно к SNR.
В Simulink. Создал вместо стандартного BPSK-модулятора свой на блоках умножения на 2 и с вычитанием 1. На выходе вещественные числа. Если задаю в AWGN Eb/N0 = 3 дБ, получаю правильный BER = 0.023. Если SNR = 3 дБ, то неверный BER = 0.07.
Стандартный BPSK-модулятор в Simulink также формирует комплексные значения (+/-1 + j0). Тут всегда верно.
Соглашусь с serjj, лучше всегда прибавлять к сигналу 1j*1e-15, а потом брать вещественную часть. Либо уж стандартной функций pskmod пользоваться. Тогда точно никаких ошибок не будет.
des00
Всем доброго!

Отложил немного турбокоды, ушел в другую сторону стандарта Wimax. Сделал в матлабе эталонную модель LDPC декодера, алгоритм декодирования Normalized Min-Sum и 2-D Normalized Min-Sum. В процессе снятия характеристик, обнаружил один, не очень понятный мне эффект. В приложении матлабовский код bertest а. В главном файле bertest.m есть параметр ERR_MODE = 0. Он может принимать значения 0/1.

Режимы 0/1 отличаются инверсией символов радиоканала и битовой инверсией результатов декодирования при измерении коэффициента ошибок.
Код
.....
        if ERR_MODE == 1
            rx_symb = awgn(tx_symb, SNR, 10*log10(2));
        else
            rx_symb = awgn(-1*tx_symb, SNR, 10*log10(2));
        end  
.....
        if ERR_MODE == 1
            err    = biterr(code(1:Nbits), decode(1:Nbits));        
        else
            err    = biterr(code(1:Nbits), not(decode(1:Nbits)));        
        end

Так вот, качество работы декодера, в разных режимах, существенно отличается. В режиме 1 он работает намного хуже ber где то 10^-2, в режиме 0 ber нулевой.
Полдня не мог понять что же сделано неправильно. Перечитывая на Nый раз статью Optimized Min-Sum Decoding Algorithm for Low Density Parity Check Codes, взгляд упал на описание алгоритма (скрин в приложении). Они в этом алгоритме инвертируют входные метрики и считают инверсные жесткие решения. Пробежался по другой литературе и во многих статьях наблюдается этот эффект.

Проясните что это за эффект ? Логическое обоснование результатов, подсказывает мне что min-sum обладает чем то, вроде постоянного смещения в вычисляемых LLR, и начальная инверсия метрик является чем то вроде коррекции этого смещения. Но в турбокодах же такого нет, или просто я случайно угадал с инверсией?

Спасибо.

ЗЫ. Раз полез в LDPC коды, то название темы изменил на более корректное sm.gif
andyp
Цитата(des00 @ Mar 27 2015, 21:09) *
Так вот, качество работы декодера, в разных режимах, существенно отличается. В режиме 1 он работает намного хуже ber где то 10^-2, в режиме 0 ber нулевой.


Для меня (не знаток LDPC и особенно того LDPC, что в ваймакс) вовсе не очевидно, что инвертированное кодовое слово тоже является кодовым словом. По логике вещей, если с - кодовое слово, то его инверсия - это:
с+ones(1, Nbits/rate).

Для того, чтобы это выполнялось, слово из всех единиц должно быть кодовым. Вот и встает вопрос - выполняется ли ones * H' = 0 для рассматриваемого кода. Закодировал твоим кодером все единицы и НЕ получил кодовое слово из всех единиц, т.е. код как минимум не систематический. Сгенери полную проверочную матрицу и проверь (сумма столбцов (??? может, строк, плохо соображаю) проверочной матрицы должна быть равна zeros).
Maverick
Цитата(des00 @ Mar 27 2015, 20:09) *
Всем доброго!

Отложил немного турбокоды, ушел в другую сторону стандарта Wimax. Сделал в матлабе эталонную модель LDPC декодера, алгоритм декодирования Normalized Min-Sum и 2-D Normalized Min-Sum. В процессе снятия характеристик, обнаружил один, не очень понятный мне эффект. В приложении матлабовский код bertest а. В главном файле bertest.m есть параметр ERR_MODE = 0. Он может принимать значения 0/1.

Режимы 0/1 отличаются инверсией символов радиоканала и битовой инверсией результатов декодирования при измерении коэффициента ошибок.
Код
.....
        if ERR_MODE == 1
            rx_symb = awgn(tx_symb, SNR, 10*log10(2));
        else
            rx_symb = awgn(-1*tx_symb, SNR, 10*log10(2));
        end  
.....
        if ERR_MODE == 1
            err    = biterr(code(1:Nbits), decode(1:Nbits));        
        else
            err    = biterr(code(1:Nbits), not(decode(1:Nbits)));        
        end

Так вот, качество работы декодера, в разных режимах, существенно отличается. В режиме 1 он работает намного хуже ber где то 10^-2, в режиме 0 ber нулевой.
Полдня не мог понять что же сделано неправильно. Перечитывая на Nый раз статью Optimized Min-Sum Decoding Algorithm for Low Density Parity Check Codes, взгляд упал на описание алгоритма (скрин в приложении). Они в этом алгоритме инвертируют входные метрики и считают инверсные жесткие решения. Пробежался по другой литературе и во многих статьях наблюдается этот эффект.

Проясните что это за эффект ? Логическое обоснование результатов, подсказывает мне что min-sum обладает чем то, вроде постоянного смещения в вычисляемых LLR, и начальная инверсия метрик является чем то вроде коррекции этого смещения. Но в турбокодах же такого нет, или просто я случайно угадал с инверсией?

Спасибо.

ЗЫ. Раз полез в LDPC коды, то название темы изменил на более корректное sm.gif

но инверсия может декодеру не помочь, а наоборот ухудшить ситуацию с декодированием - не будет декодироваться.
и наоборот.
Лучше для каждого сигнала брать пару-тройку входных данных и пробовать их декодировать с инверсией и без инверсии - соответственно принимать решение изначально инвертировать входные данные или нет.
Намного лучше декодируется 4-5 битные входные данные ("мягкие" входные данные), чем их жесткое соответствие 1/0 (бывает даже в разы)
des00
Цитата(andyp @ Mar 28 2015, 04:11) *
Для того, чтобы это выполнялось, слово из всех единиц должно быть кодовым. Вот и встает вопрос - выполняется ли ones * H' = 0 для рассматриваемого кода. Закодировал твоим кодером все единицы и НЕ получил кодовое слово из всех единиц, т.е. код как минимум не систематический. Сгенери полную проверочную матрицу и проверь (сумма столбцов (??? может, строк, плохо соображаю) проверочной матрицы должна быть равна zeros).

Все чудеснее и чудеснее. Взял CML сорцы и сделал простой тест. Только параметры поставил 2304 1/2 (позже скажу зачем):
Код
plength = 2304;
data = ones(1, plength/2);
[H_rows, H_cols, P] = InitializeWiMaxLDPC(1/2, 2304, []);
codeword = LdpcEncode( data, H_rows, P);
%
code = '1/2';
[Hb, zf, coderate] = get_wimax_ldpc_Hb(code, plength);
code = ldpc_encode(data, Hb, zf);    

disp(['cml ones = ', num2str(length(find(codeword == 1))), ' cml zeros = ', num2str(length(find(codeword == 0)))]);
disp(['my  ones = ', num2str(length(find(codeword == 1))), ' my zeros  = ', num2str(length(find(codeword == 0)))]);
disp(['cml vs my diff = ', num2str(sum(abs(codeword - code)))]);

E = eye(zf);
[c, t] = size(Hb);
H = zeros(c*zf, t*zf);
for row = 1:c
    for col = 1:t
        if Hb(row, col) >= 0
            H(zf*(row-1)+1 : zf*row, zf*(col-1)+1 : zf*col) = ...
                circshift(E,-1*Hb(row,col));
        end
    end    
end

sum_of_rows = zeros(1, c);
for row = 1:c
    sum_of_rows(row) = sum(H(row*zf, :)); % can check only one row per zf-by-zf
end
sum_of_cols = zeros(1, t);
for col = 1:t
    sum_of_cols(col) = sum(H(:,col*zf)); % can check only one col per zf-by-zf
end

disp(['H sum rows = ', num2str(sum_of_rows)]);
disp(['H sum cols = ', num2str(sum_of_cols)]);

disp(['cml check = ', num2str(H(1,:)*codeword')]);
disp(['cml inv check = ', num2str(H(1,:)*not(codeword'))]);

disp(['my check = ', num2str(H(1,:)*codeword')]);
disp(['my inv check = ', num2str(H(1,:)*not(codeword'))]);

вот результат его работы:
Код
cml ones = 1920 cml zeros = 384
my  ones = 1920 my zeros  = 384
cml vs my diff = 0
H sum rows = 6  7  7  6  6  7  6  6  7  6  6  6
H sum cols = 3  3  6  3  3  6  3  6  3  6  3  6  3  2  2  2  2  2  2  2  2  2  2  2
cml check = 6
cml inv check = 0
my check = 6
my inv check = 0

1/2 2304 взял по причине того, что нашел в книге рисунок матрицы такого кода. Он в приложении. Приведу первую строку и первый столбец проверочной матрицы:
Код
find(H(1,:)) = 191         266         824         948        1160        1249
find(H(:,1))' = 324         853        1110

Совсем не то что приведено в книге, в других книгах точно такой же рисунок (похоже списывали друг у друга).

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

Цитата(Maverick @ Mar 28 2015, 04:20) *
но инверсия может декодеру не помочь....

в обсуждаемом коде мягкое решение без квантования. Инверсия в канале это поворот созвездия QPSK на 180 градусов.

Цитата(des00 @ Mar 28 2015, 22:51) *
Вот как то у меня теперь шаблон линейных кодов немного взрывается, после результатов

Залез в сорцы CML, кодируют они так
Код
    for (i=0;i<kldpc;i++){
        c_in[i]=u[i]; // my: systematic bits
    }
    for (i=0;i<mldpc;i++){
        c_in[kldpc+i]=0; // my: parity bits
    }

    sum=0;
    for(i=0;i<mldpc;i++){ // my: mldpc - parity bit length
        for(k=1;k<=wid_Hrows;k++){ // my: wid_Hrows - H rows number
            if(H_rows[i+mldpc*(k-1)]!=0){
                count=(int)H_rows[i+mldpc*(k-1)];
                x[i]=((int)c_in[count-1])^((int)x[i]);
            }
        }
        c_in[kldpc+i]=x[i]^sum; /* Differential encoding */
        sum=c_in[kldpc+i];
    }

Ничего неожиданного, классический расчет битов четности, а нули в потоке образуются похоже в тех рядах где 7 единиц sm.gif

UPD. Шаблон разрывает по причине того, что не могу понять почему проверка проходит на инверсных битах.
des00
Цитата(des00 @ Mar 28 2015, 23:13) *
UPD. Шаблон разрывает по причине того, что не могу понять почему проверка проходит на инверсных битах.

Отвечаю сам себе. Потому что кто-то(ну т.е. я) лошпет sm.gif
1. Математика там должна быть по модулю 2.
2. Проверять надо весь вектор, а не один бит.

Правильный код проверки
Код
check     = mod(H*codeword', 2);
inv_check = mod(H*not(codeword'), 2);

disp(['cml check = ', num2str(sum(check))]);
disp(['cml inv check = ', num2str(sum(inv_check))]);

check     = mod(H*code', 2);
inv_check = mod(H*not(code'), 2);

disp(['my check = ', num2str(sum(check))]);
disp(['my inv check = ', num2str(sum(inv_check))]);

и результат
Код
cml ones = 1920 cml zeros = 384
my  ones = 1920 my zeros  = 384
cml vs my diff = 0
H sum rows = 6  7  7  6  6  7  6  6  7  6  6  6
H sum cols = 3  3  6  3  3  6  3  6  3  6  3  6  3  2  2  2  2  2  2  2  2  2  2  2
cml check = 0
cml inv check = 384
my check = 0
my inv check = 384

т.е. все работает правильно. Это возвращает к первоначальному вопросу из поста №142:
Почему декодер, в котором инвертированы метрики (умножены на -1) и декодируются инверсные биты работает лучше. Ну и на скрине статьи указано что делать нужно так sm.gif
andyp
Цитата(des00 @ Mar 28 2015, 20:55) *
Почему декодер, в котором инвертированы метрики (умножены на -1) и декодируются инверсные биты работает лучше. Ну и на скрине статьи указано что делать нужно так sm.gif


Если ты правильно сформировал матрицу (а похоже, что это так), то вектор-столбец, являющийся суммой по модулю два столбцов проверочной матрицы выглядит так - см картинку

Он явно не нулевой, а это означает, что декодер будет работать по разному, в зависимости от знаков входных данных

Теперь по статье.

Разберемся с работой чек ноды в LDPC декодере. Пусть мы имеем простейшую чек-ноду с двумя входами, между которыми вычисляется xor, чтобы получить значение чек-бита.

В этом случае, чек бит равен единице, если входы разные и 0, если они одинаковые. Для вероятностей получаем:

p_c(1) = p_1(1) * p_2(0) + p_1(0) * p_2(1); p_c(0) = p_1(1) * p_2(1) + p_1(0) * p_2(0);

Рассмотрим отношение p_c(1)/p_c(0). Разделим числитель и знаметатель на p_1(0) * p_2(0) и получим:

p_c(1)/p_c(0) = (exp(L1) + exp(L2))/(1+exp(L1)*exp(L2))


L1, L2 - LLR первого и второго битов. p_1(1)/p_1(0) = exp(L1); p_2(1)/p_2(0) = exp(L2)

Далее, используем следующее соотношение:

exp(L) = (1+tanh(L/2))/(1-tanh(L/2)) - это собственно следует из определения tanh

После подстановки и скучного приведения слагаемых получаем

p_c(1)/p_c(0) = (1- tanh(L1/2)*tanh(L2/2))/(1 + tanh(L1/2)*tanh(L2/2))

О волшебство! получили инверсию того, что используется для чек-ноды в статье. Следовательно, в статье для чек-нод получают инверсное соотношение

p_c(0)/p_c(1)

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

Для variable node соотношения будут иметь тот же вид, что и в статье, но делаем вывод, что декодер работает в терминах инверсных LLR (ln(p(0)/p(1))). Именно из-за этого и инвертируют входные LLR.
Если ты используешь инверсный маппинг, то получаешь инверсные LLR и твой декодер начинает работать правильно.

Как-то так.
des00
Цитата(andyp @ Mar 29 2015, 05:03) *
Теперь по статье.
.....
После подстановки и скучного приведения слагаемых получаем
.....

Математику уже затем учить надо, что она ум в порядок приводит (с) Ломоносов.
Все вывел, посмотрел что к чему, как то не подумал в эту сторону sad.gif. Причем маппинг в статье как у меня один в один. Спасибо большое!
Mogwaika
+ интересный факт, при вычислении llr если выбрать неправильную дисперсию шума, sum-product работает ужасно, а вот min-sum, которому не важен коэффициент при llr-ах работает нормально.
Dr.Alex
Цитата(Mogwaika @ Apr 1 2015, 13:14) *
+ интересный факт, при вычислении llr если выбрать неправильную дисперсию шума, sum-product работает ужасно, а вот min-sum, которому не важен коэффициент при llr-ах работает нормально.

"Ужасно" и "нормально" это в децибеллах (до Шеннона) сколько?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.