vitdec

Сверточное декодирование двоичных данных с помощью алгоритма Viterbi

Синтаксис

decoded = vitdec(code,trellis,tblen,opmode,dectype)
decoded = vitdec(code,trellis,tblen,opmode,'soft',nsdec)
decoded = ... vitdec(code,trellis,tblen,opmode,dectype,puncpat)
decoded = ... vitdec(code,trellis,tblen,opmode,dectype,puncpat,eraspat)
decoded = ... vitdec(...,'cont',...,initmetric,initstates,initinputs)
[decoded,finalmetric,finalstates,finalinputs] = ... vitdec(...,'cont',...)

Описание

decoded = vitdec(code,trellis,tblen,opmode,dectype) декодирует векторный code использование алгоритма Viterbi. Структура MATLAB® trellis задает сверточный энкодер, который произвел code; формат trellis описан в Описании Решетки Сверточного кода и страницы с описанием для istrellis функция. code содержит один или несколько символов, каждый из которых состоит из log2(trellis.numOutputSymbols) биты. Каждый символ в векторном decoded состоит из log2(trellis.numInputSymbols) биты. tblen положительный целочисленный скаляр, который задает traceback глубину. Если уровень кода является 1/2, типичным значением для tblen приблизительно пять раз продолжительность ограничения кода.

opmode указывает на режим работы декодера и его предположения о работе соответствующего энкодера. Выбор находится в приведенной ниже таблице.

Значения Входа opmode

ЗначениеЗначение
'cont' Энкодер принят, чтобы запуститься во все-нулевом состоянии. Декодер прослеживает от состояния с лучшей метрикой. Задержка, равная tblen символы протекают, прежде чем первый декодируемый символ появляется в выходе. Этот режим является соответствующим, когда вы неоднократно вызываете эту функцию и хотите сохранить непрерывность между последовательными вызовами. Смотрите непрерывные синтаксисы режима работы ниже.
'term'Энкодер принят, чтобы и запуститься и закончиться во все-нулевом состоянии, которое верно для синтаксиса по умолчанию convenc функция. Декодер прослеживает от все-нулевого состояния. Этот режим не подвергается никакой задержке. Этот режим является соответствующим когда незакодированное сообщение (то есть, вход к convenc) имеет достаточно нулей в конце, чтобы заполнить все регистры памяти энкодера. Если энкодер имеет k введите потоки и вектор продолжительности ограничения constr (использование полиномиального описания энкодера), “достаточно” означает k*max(constr-1).
'trunc' Энкодер принят, чтобы запуститься во все-нулевом состоянии. Декодер прослеживает от состояния с лучшей метрикой. Этот режим не подвергается никакой задержке. Этот режим является соответствующим, когда вы не можете принять энкодер, законченный во все-нулевом состоянии и когда вы не хотите сохранять непрерывность между последовательными вызовами этой функции.

Для 'term' и 'trunc' режим, traceback глубина (tblen) должно быть положительное значение целочисленного скаляра, не больше, чем количество вводимых символов в code.

dectype указывает на тип решения, которое декодер принимает и влияет на тип данных, которые декодер ожидает в code. Выбор находится в приведенной ниже таблице.

Значения Входа dectype

ЗначениеЗначение
'unquant'code содержит действительные входные значения, где 1 представляет логический нуль, и-1 представляет логическую единицу.
'hard' code содержит значения двоичного входа.
'soft'Для декодирования мягкого решения используйте синтаксис ниже. nsdec требуется для декодирования мягкого решения.

Синтаксис для мягкого декодирования решения

decoded = vitdec(code,trellis,tblen,opmode,'soft',nsdec) декодирует векторный code использование декодирования мягкого решения. code состоит из целых чисел между 0 и 2^nsdec-1, где 0 представляет самый уверенный 0 и 2^nsdec-1 представляет самый уверенный 1. Существующая реализация функциональности поддерживает до 13 битов квантования, означая nsdec может быть установлен до 13. Для ссылки 3 бита квантования на приблизительно 2 дб лучше, чем декодирование трудного решения.

Синтаксис для проколов и стираний

decoded = ... vitdec(code,trellis,tblen,opmode,dectype,puncpat) обозначает, что вход проколол code, где puncpat вектор шаблона прокола, и где 0s указывают на проколотые биты во входном коде.

decoded = ... vitdec(code,trellis,tblen,opmode,dectype,puncpat,eraspat) позволяет вектор шаблона стирания, eraspat, быть заданным для входа code, где 1s указывают на соответствующие стирания. eraspat и code должен иметь ту же длину. Если прокалывание не используется, задайте puncpat быть []. В eraspat вектор, 1s указывают на стирания во входном коде.

Дополнительные синтаксисы для непрерывного режима работы

Непрерывный режим работы позволяет вам сохранить информацию внутреннего состояния декодера для использования в последующем вызове этой функции. Повторные вызовы этой функции полезны, если ваши данные разделены в серию меньших векторов, которые вы обрабатываете в цикле, например.

decoded = ... vitdec(...,'cont',...,initmetric,initstates,initinputs) совпадает с более ранними синтаксисами, за исключением того, что декодер запускается со своих метрик состояния, traceback состояния и входные параметры traceback, заданные initmetric, initstates, и initinputs, соответственно. Каждое вещественное число в initmetric представляет метрику начального состояния соответствующего состояния. initstates и initinputs совместно задайте начальную букву traceback память о декодере; оба - trellis.numStates- tblen матрицы. initstates состоит из целых чисел между 0 и trellis.numStates-1. Если схематичный энкодер имеет больше чем один входной поток, сдвиговый регистр, который получает первый входной поток, обеспечивает младшие значащие биты в initstates, в то время как сдвиговый регистр, который получает последний входной поток, обеспечивает старшие значащие биты в initstates. Векторный initinputs состоит из целых чисел между 0 и trellis.numInputSymbols-1. Чтобы использовать значения по умолчанию во всех последних трех аргументах, задайте их как [],[],[].

[decoded,finalmetric,finalstates,finalinputs] = ... vitdec(...,'cont',...) совпадает с более ранними синтаксисами, за исключением того, что итоговые три выходных аргумента возвращают метрики состояния, traceback состояния и входные параметры traceback, соответственно, в конце процесса декодирования. finalmetric вектор с trellis.numStates элементы, которые соответствуют метрикам конечного состояния. finalstates и finalinputs оба матрицы размера trellis.numStates- tblen. Элементы finalstates имейте тот же формат как те из initstates.

Матрицы Traceback

t th столбец P 1 показывает t - 1th временной шаг утверждает, учитывая входные параметры, перечисленные во входной матрице. Например, значение в i th строка показывает состояние во время t-1 что переходы к i-1 состояние во время t. Вход, требуемый для этого изменения состояния, дан в i th строку t th столбец входной матрицы.

P 1 выход является состояниями traceback матрицы. Это [количество состояний x traceback длина] матрица. Следующий пример использует (7,5), уровень 1/2 код. Этому коду легко следовать:

t = poly2trellis (3, [7 5]);
k = log2 (t.numInputSymbols);
обменивайтесь сообщениями = [1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0];
код = convenc (сообщение, t); tblen = 15; [d1 m1 p1 in1] =vitdec (код (1:end/2), t, tblen, 'продолжение следует', 'трудно')

m1 =

     0     3     2     3
p1 =

     0     1     1     0     0     1     1     0     0     1     1     0     0     1     1
     2     3     3     2     2     3     3     2     2     3     3     2     2     3     3
     0     1     1     0     0     1     1     0     0     1     1     0     0     1     1
     2     3     3     2     2     3     3     2     2     3     3     2     2     3     3
in1 =

     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0
     1     1     1     1     1     1     1     1     1     1     1     1     1     1     1
     1     1     1     1     1     1     1     1     1     1     1     1     1     1     1

В этом примере сообщение заставляет состояния энкодера следовать за следующей последовательностью:

0 2 3 1 / 0 2 3 1 / ...

Поскольку лучшим состоянием является 0 (индекс столбца самой маленькой метрики в m 1 - 1), traceback матрица начинает с 0 состояния, рассмотрение первой строки (0состояние th) последнего столбца P 1, ([1; 3; 1; 3]), который является 1. Это указывает на 1 для предыдущего состояния.

Затем traceback матрица проверяет in1 ([0; 0; 1; 1]), который указывает на 0 для входа. Вторая строка (1-е состояние) 14-го столбца P 1 ([1; 3; 1; 3]), 3. Это указывает на 3 для предыдущего состояния.

traceback матрица проверяет in1 ([0; 0; 1; 1]), который указывает, что вход был 0. Четвертая строка (3-е состояние) 13-го столбца P 1 ([0; 2; 0; 2]), 2. Это указывает на 2 для предыдущего состояния.

traceback матрица проверяет in1 ([0; 0; 1; 1]), который указывает, входом был 1. Третья строка (2-е состояние) 12-го столбца P 1 ([0; 2; 0; 2]), 0. Это указывает на 0 для предыдущего состояния.

traceback матрица проверяет in1 ([0; 0; 1; 1]), который указывает, входом был 1. Первая строка (0th состояние) 11-го столбца P 1 ([1; 3; 1; 3]), 1. Это указывает на 1 для предыдущего состояния. Затем матрица проверяет in1 ([0; 0; 1; 1]), который указывает на 0 для входа.

Чтобы определить лучшее состояние в течение данного времени, используйте m 1. Самый маленький номер в m 1 представляет лучшее состояние.

Примеры

свернуть все

В этом примере показано, как создать сверточный код с помощью convenc функционируйте и как декодировать его с помощью vitdec.

Кодирование

Задайте решетку.

t = poly2trellis([4 3],[4 5 17;7 4 2]);

Закодируйте вектор из единиц.

x = ones(100,1);
code = convenc(x,t);

Декодирование

Задайте решетку.

t = poly2trellis([4 3],[4 5 17;7 4 2]);

Закодируйте вектор из единиц.

code = convenc(ones(100,1),t);

Установите traceback длину для декодирования и декодируйте использование vitdec.

tb = 2;
decoded = vitdec(code,t,tb,'trunc','hard');

Проверьте, что декодируемые данные являются вектором из 100 единиц.

isequal(decoded,ones(100,1))
ans = logical
   1

Этот пример выполняет немного симуляции коэффициента ошибок для ссылки, которая использует 16-QAM модуляцию уровень 2/3 сверточный код.

Установите порядок модуляции и вычислите количество битов на символ.

M = 16;
k = log2(M);

Сгенерируйте случайные двоичные данные.

dataIn = randi([0 1],100000,1);

Задайте сверточную решетку кодирования для уровня 2/3 код.

tPoly = poly2trellis([5 4],[23 35 0; 0 5 13]);
codeRate = 2/3;

Convolutionally кодируют входные данные.

codeword = convenc(dataIn,tPoly);

Измените закодированный вектор-столбец в матрицу, имеющую k столбцы. Затем преобразуйте бинарную матрицу в целочисленный вектор-столбец.

codewordMat = reshape(codeword,length(codeword)/k,k);
txSym = bi2de(codewordMat);

Примените 16-QAM модуляцию к закодированным символам.

txSig = qammod(txSym,M);

Преобразуйте Eb/No на 10 дБ в эквивалентное отношение сигнал-шум. Передайте сигнал через канал AWGN.

EbNo = 10;
snr = EbNo + 10*log10(k*codeRate);
rxSig = awgn(txSig,snr,'measured');

Демодулируйте полученный сигнал.

demodSig = qamdemod(rxSig,M);

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

demodSigMat = de2bi(demodSig,k);
demodSigBinary = demodSigMat(:);

Установите traceback глубину Декодера Витерби.

traceBack = 16;

Декодируйте двоичный файл демодулируемый сигнал при помощи Декодера Витерби, действующего в непрерывном режиме завершения.

dataOut = vitdec(demodSigBinary,tPoly,traceBack,'cont','hard');

Вычислите задержку через декодер и вычислите статистику битовой ошибки.

decDelay = 2*traceBack;
[numErrors,ber] = biterr(dataIn(1:end-decDelay),dataOut(decDelay+1:end))
numErrors = 26
ber = 2.6008e-04

Сравните BER с незакодированным BER.

berUncoded = berawgn(EbNo,'qam',M);
berUncoded/ber
ans = 6.7446

Сверточный код уменьшает BER приблизительно на фактор 4.

Оцените производительность частоты ошибок по битам (BER) для Декодеров Витерби трудного решения и мягкого решения в AWGN. Сравните производительность с той из незакодированной 64-QAM ссылки.

Установите параметры симуляции.

clear; close all
rng default
M = 64;                 % Modulation order
k = log2(M);            % Bits per symbol
EbNoVec = (4:10)';       % Eb/No values (dB)
numSymPerFrame = 1000;   % Number of QAM symbols per frame

Инициализируйте векторы результатов BER.

berEstSoft = zeros(size(EbNoVec)); 
berEstHard = zeros(size(EbNoVec));

Установите структуру решетки и traceback длину для уровня 1/2, продолжительность ограничения 7, сверточный код.

trellis = poly2trellis(7,[171 133]);
tbl = 32;
rate = 1/2;

Основные циклы обработки выполняют эти шаги:

  • Сгенерируйте двоичные данные.

  • Convolutionally кодируют данные.

  • Примените модуляцию QAM к символам данных. Задайте модульную среднюю степень для переданного сигнала.

  • Передайте модулируемый сигнал через канал AWGN.

  • Демодулируйте полученный сигнал с помощью трудного решения и аппроксимируйте методы LLR. Задайте модульную среднюю степень для полученного сигнала.

  • Viterbi декодируют сигналы, использующие трудно и неквантованные методы.

  • Вычислите количество битовых ошибок.

while цикл продолжает обрабатывать данные, пока с или 100 ошибками не сталкиваются или 1e7, биты передаются.

for n = 1:length(EbNoVec)
    % Convert Eb/No to SNR
    snrdB = EbNoVec(n) + 10*log10(k*rate);
    % Noise variance calculation for unity average signal power.
    noiseVar = 10.^(-snrdB/10);
    % Reset the error and bit counters
    [numErrsSoft,numErrsHard,numBits] = deal(0);
    
    while numErrsSoft < 100 && numBits < 1e7
        % Generate binary data and convert to symbols
        dataIn = randi([0 1],numSymPerFrame*k,1);
        
        % Convolutionally encode the data
        dataEnc = convenc(dataIn,trellis);
        
        % QAM modulate
        txSig = qammod(dataEnc,M,'InputType','bit','UnitAveragePower',true);
        
        % Pass through AWGN channel
        rxSig = awgn(txSig,snrdB,'measured');
        
        % Demodulate the noisy signal using hard decision (bit) and
        % soft decision (approximate LLR) approaches.
        rxDataHard = qamdemod(rxSig,M,'OutputType','bit','UnitAveragePower',true);
        rxDataSoft = qamdemod(rxSig,M,'OutputType','approxllr', ...
            'UnitAveragePower',true,'NoiseVariance',noiseVar);
        
        % Viterbi decode the demodulated data
        dataHard = vitdec(rxDataHard,trellis,tbl,'cont','hard');
        dataSoft = vitdec(rxDataSoft,trellis,tbl,'cont','unquant');
        
        % Calculate the number of bit errors in the frame. Adjust for the
        % decoding delay, which is equal to the traceback depth.
        numErrsInFrameHard = biterr(dataIn(1:end-tbl),dataHard(tbl+1:end));
        numErrsInFrameSoft = biterr(dataIn(1:end-tbl),dataSoft(tbl+1:end));
        
        % Increment the error and bit counters
        numErrsHard = numErrsHard + numErrsInFrameHard;
        numErrsSoft = numErrsSoft + numErrsInFrameSoft;
        numBits = numBits + numSymPerFrame*k;

    end
    
    % Estimate the BER for both methods
    berEstSoft(n) = numErrsSoft/numBits;
    berEstHard(n) = numErrsHard/numBits;
end

Отобразите предполагаемые твердые и мягкие данные о BER на графике. Постройте теоретическую производительность для незакодированного 64-QAM канала.

semilogy(EbNoVec,[berEstSoft berEstHard],'-*')
hold on
semilogy(EbNoVec,berawgn(EbNoVec,'qam',M))
legend('Soft','Hard','Uncoded','location','best')
grid
xlabel('Eb/No (dB)')
ylabel('Bit Error Rate')

Как ожидалось мягкое декодирование решения приводит к лучшим результатам.

Ограничения

Для того, чтобы улучшать производительность кода C/C++, сгенерированного MATLAB, целостность и проверки скорости отклика должны быть отключены прежде, чем запустить codegen функция. Смотрите Конструктивные соображения кода MATLAB для Генерации кода (Simulink) для получения дополнительной информации.

Например, учитывая следующую функцию:

function y = vitdec_hard(x,t,tb)
%# codegen

y = vitdec(x,t,tb,'trunc','hard');

Выполните эти команды для оптимальной производительности.

cf = coder.config;
cf.IntegrityChecks = false;
cf.ResponsivenessChecks = false;
codegen('vitdec_hard','-args',{x,coder.Constant(t),tb})

Закодированные данные, x, структура решетки, t, и traceback длина, tb, должен быть задан в базовом рабочем пространстве.

Ссылки

[1] Кларк, G. C. Младший и J. Затвор Каин., кодирование с коррекцией ошибок для цифровой связи, Нью-Йорка, нажатия пленума, 1981.

[2] Gitlin, Ричард Д., Иеремия Ф. Хейз, и Стивен Б. Вайнштейн, Дэта-Коммуникэйшнс-Принкиплс, Нью-Йорк, пленум, 1992.

[3] Хеллер, J. A. и я. М. Джейкобс, “Viterbi, Декодирующий для Спутника и Космической связи”, Транзакции IEEE на Коммуникационной технологии, Издании COM-19, октябрь 1971, стр 835–848.

[4] Yasuda, Y., и. al., “Высокий показатель проколол сверточные коды для мягкого решения декодирование Viterbi”, Транзакции IEEE на Коммуникациях, издании COM-32, № 3, стр 315–319, март 1984.

[5] Haccoun, D. и G. Начните, “Высокий показатель проколол сверточные коды для Viterbi и последовательного декодирования”, Транзакции IEEE на Коммуникациях, издании 37, № 11, стр 1113–1125, ноябрь 1989.

[6] G. Начните, et.al., “Дальнейшие результаты на высоком показателе прокололи сверточные коды для Viterbi и последовательного декодирования”, Транзакции IEEE на Коммуникациях, издании 38, № 11, стр 1922–1928, ноябрь 1990.

Расширенные возможности

Генерация кода C/C++
Генерация кода C и C++ с помощью MATLAB® Coder™.

Смотрите также

| |

Представлено до R2006a