Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Помехоустойчивое кодирование в телекоммуникационных системах. Практикум

.pdf
Скачиваний:
0
Добавлен:
07.09.2026
Размер:
2 Мб
Скачать
☆
51
endfunction.
Сохраните функцию в отдельный файл и назовите его modulator.
Далее в файле main следует вызвать функцию модулятора:
qam_sym = modulator(bits, M);
После этого моделируется АБГШ канал связи с помощью функции
chan_sym = awgn(qam_sym,SNR,'measured');
где 'measured' обозначает измерение мощности сигнала при наложении на него шума. Если оставить функцию без этого аргумента, мощность сигнала будет считаться равной 1 Вт.
Алгоритм демодуляции следует реализовать в отдельной функции demodulator с входами r_sym, M и выходом r_bits по аналогии с модуляцией. Если M=2 (BPSK) демодуляция может быть реализована как простое пороговое устройство:
r_bits = r_sym>0;
В случае, если элемент вектора r_sym больше нуля, в соответствующий ему элемент вектора r_bits будет записана логическая единица, в противном случае – логический ноль.
Вызовите функцию demodulator
r_bits = demodulator(chan_sym, M);
Биты на выходе демодулятора поступают на блок расчета контрольной суммы в приемнике (для этого используется тот же алгоритм и та же функция, как и в передатчике):
crc_r = crc_gen (r_bits_crc);
После этого проверяется, равна ли контрольная сумма нулю, если нет, то к счетчику ошибок пакетов добавляется 1:
if sum(crc_r) ~= 0
err = err+1;
endif
На этом итерация по передаче одного пакета заканчивается.
После выполнения N итераций необходимо рассчитать значение
BLER(k):
BLER(k) = err/N;
end
На этом итерация глобального цикла snr_i заканчивается. Последним этапом является построение в логарифмическом масштабе зависимостей BLER от SNR:
semilogy(SNR(1):SNR(2), BLER)
Оси графиков можно подписать следующим образом.
xlabel('SNR');
ylabel('BLER');
Для построения двух графиков в одном графическом окне нужно между
соответствующими функциями построения записать команду
hold on
Следующим этапом работы скрипта является расчет количества ошибок, который можно реализовать следующим образом
52
length(find(de2bi(bits) – de2bi(r_bits))),
функция de2bi переводит символы в двоичный вид (биты), find ищет ненулевые элементы (различающиеся биты при вычитании не будут равны нулю), а length считает их количество. Если после вызываемой функции не ставить символ «;», то результат выполнения функции будет выводиться в командную строку.
Последним этапом работы скрипта будет вывод сигнального созвездия на входе приемника (после канала)
scatterplot(chan_sym).
Запустить скрипт можно нажав на кнопку «Сохранить и выполнить/продолжить» на панели инструментов выше текстового редактора, либо нажав F5 на клавиатуре.
Рисунок 7.2 – Запуск скрипта
Результатом работы всей модели будет график зависимости BLER от
SNR.
Количество ошибок будет выведено в командную строку. Изменяйте индекс модуляции, отношение сигнал-шум, чтобы пронаблюдать сигнальное созвездие для разных модуляций и количество битовых ошибок при различных сценариях работы (добейтесь появления большого числе ошибок). Определите связь между разбросом точек на сигнальное созвездие и появлением ошибок.
Основной частью работы будет реализация декодера Витерби. Создайте функцию декодера Витерби и назовите ее conv_decoder,
выходное значение decoded_bits, входное bits.
Прежде всего задайте переменную N, которая соответствует длине декодированного сообщения (половине длины кодированного):
N = length(bits)/2;
Далее, создайте массив в строках которого будут записаны узлы решетчатой диаграммы:
nodes = [ 0 0;
1 0;
0 1;
1 1];
Далее, создайте массив со связями, в строки (соответствующие узлам) которого запишите номера узлов в предыдущем такте, с которыми соединен текущий узел:
connects = [ 1 3
1 3
2 4
2 4];
53
Создайте следующий массив, который соответствует выходным значениям, формируемым при прохождении через ветвь, указанную в предыдущем массиве:
in_values = [ [0 0], [1 1]
[1 1], [0 0] [1 0], [0 1]
[0 1],[1 0] ];
Обратите внимание, что здесь создается массив размером 4,4.
Далее, объявляем пустой вектор, в котором будем хранить значения метрик:
metrics= zeros(4,1);
Поскольку исходное состояние регистра 00, для иных состояний искусственно завышаем метрику и тем самым делаем их менее вероятными:
metrics(2:4)= 2;
В данном случае задается значение 2, но может быть указано любое другое.
Также задаем массив путей:
way=ones(4,1);
Каждый такт этот вектор будет увеличиваться в 2 раза (превратится в матрицу размером 4 на n, где n – номер такта).
После этого в цикле от 1 до N начинаем анализировать входной вектор закодированных битов:
for i = 1:N
Выделяем текущий дибит:
dibit = bits(2*(i-1)+1:2*i);
И анализируем каждый из узлов в цикле от 1 до 4:
for k = 1:4
Считаем веса для каждой входящей в узел ветви:
ves(k,1) = sum(xor(in_values(k,1:2), dibit)); ves(k,2) = sum(xor(in_values(k,3:4), dibit));
Новая метрика для этого узла – наименьшая из двух входящих. А каждая из входящих равна сумме метрики связанного предыдущего узла и веса ветви. Выбираем наименьшую, записываем ее в вектор новых метрик (metrics_new) и сохраняем путь в обновленный вектор:
if metrics(connects(k,1)) + ves(k,1) < metrics(connects(k,2)) + ves(k,2)
way_new(k,1:i) = [way(connects(k,1),1:i-1),connects(k,1)];
metrics_new(k,1) = metrics(connects(k,1)) + ves(k,1);
else
way_new(k,1:i) = [way(connects(k,2),1:i-1),connects(k,2)];
metrics_new(k,1) = metrics(connects(k,2)) + ves(k,2);
end
Это основной шаг алгоритма, связанный с обновлениями метрик и отбрасыванием наименее вероятных путей. Тщательно проанализируйте его.
На этом итерация для всех четырех заканчивается. Далее, записываем обновленные вектора метрик и путей в текущие:
54
metrics = metrics_new; way = way_new;
И далее рассматриваем следующий дибит.
На этом основной цикл заканчивается. Находим номер минимальной метрики:
[~,num_min] = min(metrics);
И считаем, что он соответствует верному пути, который также обновляем. Первое значение вектора way отбрасывается (т.к. оно соответствует моменту до первого такта), а в последнюю позицию записываем номер текущего узла нашего пути.
way_min = [way(num_min,2:end) num_min];
Правильная последовательность исходных битов определяется как значение в левом разряде узла в каждой итерации (там находятся входные биты в n+1 такте):
for i=1:N decoded_bits(1,i) = nodes(way_min(i),1);
end
Реализуйте модель, построенную по схеме, приведенной на рисунке 6.1. Моделирование проведите для SNR в диапазоне от 0 до 15 дБ. Постройте графики зависимостей BER (SNR). Подробное описание реализации этой части работы приведено в методичке, посвященной кодированию повторением. Сравните помехоустойчивость системы связи со сверточных кодированием с некодированной передачей и с кодированием повторением.
4 Дополнительное задание для самостоятельной работы
1. При реализации декодера Витерби, описанной выше, в памяти
хранится массив путей 4 на N. Однако за счет того, что наименее вероятные пути отбрасываются, к последней итерации большая часть первых путей для всех четырех узлов будет совпадать, и таким образом, длину этого массива можно сократить. Реализуйте такое сокращение для сохранения в памяти не более путей глубиной не более 10.
2. Сделайте универсальный декодер Витерби со входными
аргументами bits, L (длина кодового ограничения) и G1, G2 (векторы связи).
5 Контрольные вопросы
1. Как рассчитываются веса путей на решетчатой диаграмме?
2. Каким образом отбрасываются наименее вероятные пути
на решетчатой диаграмме?
3. Как, зная путь, восстановить исходную последовательность битов?
4. Как связаны количество узлов древовидной диаграммы и длина
сдвигового регистра?
55
Листинг основной работы:
Файл main.m
clc clear all close all
M = 2;
N = 1000;
SNR = [0 20];
k = 0;
for snr_i = SNR(1):SNR(2) k = k+1
bits = randi([0 M-1],N,1); coded_bits = conv_coder (bits);
qam_sym = modulator(coded_bits, M); chan_sym = awgn(qam_sym,snr_i,'measured'); r_bits = demodulator(chan_sym, M); decoded_bits = conv_decoder (r_bits);
ber_coded(k) = (length(find(de2bi(bits) – de2bi(decoded_bits))))/(N*log2(M)); end
semilogy(SNR(1):SNR(2), ber_coded) xlabel('SNR');
ylabel('BER'); hold on
Файл conv_decoder.m
function decoded_bits = conv_decoder (bits) N = length(bits)/2;
nodes = [ 0 0;
1 0;
0 1;
1 1];
connects = [ 1 3
1 3
2 4
2 4];
in_values = [ [0 0], [1 1]
[1 1], [0 0]
[1 0], [0 1]
[0 1],[1 0] ];
metrics= zeros(4,1);
metrics(2:4)= 2;
way=ones(4,1);
for i = 1:N
dibit = bits(2*(i-1)+1:2*i); for k = 1:4
ves(k,1) = sum(xor(in_values(k,1:2), dibit));
ves(k,2) = sum(xor(in_values(k,3:4), dibit));
56
if metrics(connects(k,1)) + ves(k,1) < metrics(connects(k,2)) + ves(k,2)
way_new(k,1:i) = [way(connects(k,1),1:i-1),connects(k,1)]; metrics_new(k,1) = metrics(connects(k,1)) + ves(k,1);
else
way_new(k,1:i) = [way(connects(k,2),1:i-1),connects(k,2)]; metrics_new(k,1) = metrics(connects(k,2)) + ves(k,2);
end end
metrics = metrics_new;
way = way_new;
end
[~,num_min] = min(metrics);
way_min = [way(num_min,2:end) num_min];
for i=1:N
decoded_bits(1,i) = nodes(way_min(i),1); end
endfunction
57
Практические задания к разделу 1 ПРИНЦИПЫ ПОМЕХОУСТОЙЧИВОГО КОДИРОВАНИЯ
1.1 Сообщения источника, имеющего алфавит с объемом К=32,
кодируются двоичным блочным кодом. Число разрядов в каждой кодовой комбинации n=8. Какое число информационных и проверочных символов содержится в каждой кодовой комбинации? Сколько разрешенных и запрещенных комбинаций в используемом коде?
1.2. По условию задачи 1.1 определить избыточность и относительную
скорость кода.
1.3. Первичный непрерывный сигнал путем дискретизации во времени и квантования по уровню превращается в импульсную последовательность с числом уровней К=128. Каждый уровень квантования сигнала кодируемого равномерным 10-разрядным двоичным кодом. Чему равна избыточность и относительная скорость кода? Как изменятся избыточность и относительная скорость кода, если число разрядов в кодовой комбинации уменьшить на 2? Увеличить на 2?
1.4. Алфавит с объемом K=256 кодируется 15-разрядным равномерным двоичным кодом. Чему равна избыточность и относительная скорость кода?
1.5. Комбинации n-разрядного двоичного блочного кода содержат k информационных символов. Определите долю обнаруживаемых таким видом ошибок из всех возможных ошибок.
1.6. Для кода из предыдущей задачи определите долю исправляемых ошибок. При каком условии код может применяться в качестве исправляющего?
1.7. Определить избыточность и относительную скорость для кодов по следующим данным:
1) m=2, n=7, К=32; 2) m=2, n=6, К=16; 3) m=З, n=4, К=27; 4) m=3, n=5, К=81.
1.8. Определите долю обнаруживаемых исправляемых ошибок для двоичных кодов по следующим данным
1) n=5, k=4; 2) n=7, k=4; 3) n=15, k=11; 4) n=21, k=10.
1.9. Определить долю обнаруживаемых ошибок для кода, каждая комбинация которого содержит всего один избыточный символ (n=k+1).
1.10. Определить минимальное кодовое расстояние, необходимое для обнаружения тройной ошибки.
1.11. Ошибки какой кратности может исправлять код, для которого
мин
?
1.12. Определить
мин
для кодов: а) обнаруживающего тройную и исправляющего двойную ошибки; б) обнаруживающего пятикратную и исправляющего тройную ошибки.
1.13. Показать, что код с расстоянием
мин
позволяет обнаружить о
мин
  ошибок и исправить и
мин
   ошибок.
58
1.14. Каждые 100 символов двоичного источника кодируются двоичной
последовательностью, содержащей n=126 кодовых символов. Определить
избыточность кода
к
. Найти вероятность правильного декодирования
кодовой комбинации в канале с независимыми ошибками, если
мин

вероятность ошибочной регистрации кодового символа , а
декодирование осуществляется по минимуму расстояния по Хеммингу.
1.15. Символы двоичного источника A и В кодируются избыточным 3-
разрядным двоичным кодом
мин
. Составить таблицу возможных
состояний на выходе декодера при декодировании минимуму расстояния по Хеммингу в нестертых символах:
• с исправлением стираний и обнаружением ошибок;
• с исправлением ошибок и стираний;
• с обнаружением ошибок и исправлением ошибок и стираний.
59
Практические задания к разделу 2 ЛИНЕЙНЫЕ ДВОИЧНЫЕ БЛОЧНЫЕ КОДЫ
2.1. Двоичный код, предназначенный для кодирования восьми
сообщений, содержит кодовые комбинации:


Является ли данный код линейным? Найти избыточность кода и

.
2.2. Построить систематический код (7, 4), предназначенный для
кодирования сообщений двоичного источника, имеющие объем К = 24
символов показать, что
мин
такого кода равно 3.
2.3. Для систематического кода (7, 4) из предыдущей задачи построить
производящую и проверочную матрицы.
2.4. Построить линейный код (7, 4) по заданной производящей матрице

󰈏
󰈏
По производящей матрице составить правило формирования
проверочных разрядов. Составить проверочную матрицу.
2.5. Линейный код (7, 4) построен по матрице
󰈑
󰈑
Составить проверочную матрицу и показать процесс исправления
ошибок в произвольном разряде корректирующего кода, информационная часть которого представляет собой 4-разрядные комбинации примитивного двоичного кода.
2.6. Для кода, заданного в задаче 2.4, составить таблицу синдромов и
показать, каким ошибочным разрядам они соответствуют.
2.7. Составить таблицу синдромов одиночных ошибок для кода (7.4) из
задачи 2.5 и показать, каким ошибочным разрядам они соответствуют.
2.8. Убедиться в том, что в кодовых комбинациях 1000111, 0111010,
1101001, 0000000, принадлежащих коду из задания 2.4, может быть исправлена ошибка в любом информационном разряде.
2.9. Найти комбинации кода (7, 3), двойственному коду (7, 4), заданному
производящей матрицей из задачие 2.5
2.10. Сравнить с точки зрения способности исправления одиночных
ошибок линейные коды, заданные производящей матрицей:
60

󰈑
󰈑
󰈑
󰈑

󰈑
󰈑
󰈑
󰈑
Какой из кодов реализуется более простыми средствами?
2.11. Показать, что код, заданный производящей матрицей

󰈑
󰈑
󰈑
󰈑
󰈑
󰈑
.
исправляет одиночные ошибки в произвольной кодовой комбинации;
2.12. Для кода (7, 4) из задачи 2.2. построить комбинации двойственного
кода (7,3).
2.13. Решить задачу 2.10. для кодов, заданных производящими
матрицами

󰈑
󰈑
󰈑
󰈑

󰈑
󰈑
󰈑
󰈑
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]