📄 turbo_decode.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 + -