⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 turbo_decode.m

📁 Turbo coding algorithm
💻 M
字号:
function [seqout, alpha] = turbo_decode(seqin, len, key, puncture, gnum, dec_alg, nb_iters)
% [seqout, alpha] = turbo_decode(seqin, len, key [, puncture, gnum, dec_alg, nb_iters])
%
% Decode turbo code encoded codewords.
%
% Input:
%   'seqin'    : input codeword, in {<0, >=0} form (soft decoding);
%                should be normalized in interval [-1,1].
%   'len'      : length of original sequence.
%   'key'      : seed to use for pseudo-random interleaving during decoding.
%   'puncture' : 1 to use the puncturer, giving rate 1/2; 0 otherwise, giving rate 1/3 (default).
%   'gnum'     : generator polynom, 1 (default), 2 or 3.
%   'dec_alg'  : decoding algorithm: 1 for logmapo decoder (default), 2 for sova0 decoder.
%   'nb_iters' : maximum number of iterations (defalut: 5).
%
% Output:
%   'seqout'   : output decoded sequence, in {0,1} form;
%                note: {<0,>=0} is mapped to {0,1}
%   'alpha'    : used pseudo-random interleaving.

% ltot1 = numbits in seqin+2

if exist('key') ~= 1 | isempty(key)
    key = 1;
end

if exist('puncture') ~= 1 | isempty(puncture)
   puncture = 0;
end

if exist('gnum') ~= 1 | isempty(gnum)
   gnum = 1;
end

if gnum == 1
    g = [ 1 1 1; 1 0 1 ];
elseif gnum == 2
    g = [1 1 0 1; 1 1 1 1];
elseif gnum == 3
    g = [1 1 1 1 1; 1 0 0 0 1];
else
    error(sprintf('invalid generator polynom selection: %d, should be 1 to 3', gnum));
end

if exist('dec_alg') ~= 1 | isempty(dec_alg)
   dec_alg = 1;
end

if ~ismember(dec_alg, [1 2])
    error(sprintf('invalid decoding method: %d, should be 1 or 2', dec_alg));
end

if exist('nb_iters') ~= 1 | isempty(nb_iters)
   nb_iters = 5;
end
nb_iters = max(nb_iters, 1);

% Input sequence full length and sub-sequences length
%
full_len = len(1);
if length(len) > 1
    sub_len = len(2);
else
    sub_len = full_len;
end

full_len = max(full_len, 1);
if sub_len <= 0
    sub_len = full_len;
end
sub_len  = min(sub_len, full_len);

% Otherwise Turbo decode
%
old_state = rand('state');

if (sub_len < full_len)
    fprintf('turbo decoding .');
    nl = 0;
end

[n, K] = size(g);
m      = K - 1;
rate   = (~(~puncture))*[2 4] + (~puncture)*[3 6];

EbN0db = 10;
en     = 10^(EbN0db/10); % convert Eb/N0 
L_c    = 4*en*(1/rate(1)); % reliability value of the channel

seqout = [];
alpha  = [];
k = 1;
n = 0;
for p = 1:sub_len:full_len
    currlen = min(full_len-p+1, sub_len);
    if p == 1 | currlen < sub_len
        codelen = rate(1)*currlen + rate(2);
        L_total = currlen + m;
    end

    rand('state',key);
    [temp, al] = sort(rand(1,L_total)); % random interleaver
    yk = demultiplex(seqin(k:k+codelen-1), al, ~puncture); % demultiplex to get input for decoder 1 and 2
    
    L_e   = [];
    L_a   = [];
    L_all = [];
    xhat  = [];
    
    % scale the received bits      
    rec_s = 0.5*L_c*yk; %%##%%
    % initialize extrinsic information      
    L_e(1:L_total) = zeros(1,L_total);
    
    for iter = 1:nb_iters
        % Decoder one
        L_a(al) = L_e;  % a priori info. 
        if dec_alg == 1
            L_all = logmapo(rec_s(1,:), g, L_a, 1);    % complete info.
        else   
            L_all = sova0(rec_s(1,:), g, L_a, 1);      % complete info.
        end   
        L_e = L_all - 2*rec_s(1,1:2:2*L_total) - L_a;  % extrinsic info.
        
        % Decoder two         
        L_a = L_e(al);  % a priori info.
        if dec_alg == 1
            L_all = logmapo(rec_s(2,:), g, L_a, 2);    % complete info.  
        else
            L_all = sova0(rec_s(2,:), g, L_a, 2);      % complete info. 
        end
        L_e = L_all - 2*rec_s(2,1:2:2*L_total) - L_a;  % extrinsic info.
   
        % Estimate the info. bits        
        xhat(al) = (sign(L_all)+1)/2;
    end % iter
    
    seqout = [seqout xhat(1:end-m)];
    alpha  = [alpha; [al zeros(1,size(alpha,2)-length(al))]];
    
    k = k + codelen;
    n = n + 1;
    
    if sub_len < full_len
        fprintf('.');
        if nl >= 80
            fprintf('\n');
            nl = 0;
        else
            nl = nl + 1;
        end
    end
end

if sub_len < full_len
    fprintf('\n');
end

rand('state', old_state);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -