📄 sovao.m
字号:
function [ out, lle ] = sovaO( msg, llr, win)
global sim_consts;
enco = sim_consts.enco; % encoder parameters
% some parameters:
INF = 9e9; % infinity
len = fix(length(llr)/enco.n); % number of decoding steps (total)
win = min( [ win, len ] ); % trim the buffer if msg is short
old = NaN; % to remember the last survivor
% allocate memory for the trellis:
metr = zeros( enco.stat, win+1 ) -INF; % path metric buffer
metr( 1,1 ) = 0; % initial state => (0,0)
surv = zeros( enco.stat, win+1 ); % survivor state buffer
inpt = zeros( enco.stat, win+1 ); % survivor input buffer (dec. output)
diff = zeros( enco.stat, win+1 ); % path metric difference
comp = zeros( enco.stat, win+1 ); % competitor state buffer
inpc = zeros( enco.stat, win+1 ); % competitor input buffer
outt = zeros( enco.stat, win+1, enco.n ); % survivor out buffer
outc = zeros( enco.stat, win+1, enco.n ); % competitor out buffer
out = zeros( fix(size(llr)*enco.r )) + NaN; % hard output (bits)
sft = zeros( size(llr) ) + INF; % soft output (sign with reliability)
vout = zeros(size(msg));
% decode all the bits:
for i = 1:len,
% indices + precalcuations:
Cur = mod( i-1, win+1 ) +1; % curr trellis (cycl. buf) position
Nxt = mod( i, win+1 ) +1; % next trellis (cycl. buf) position
buf = msg( i*enco.n:-1:(i-1)*enco.n+1 ); % msg portion to be processed (reversed)
llb = llr( i*enco.n:-1:(i-1)*enco.n+1 ); % SOVA: llr portion to be processed
metr( :,Nxt ) = -INF -INF; % (2*) helps in initial stages (!!!)
%% forward recursion:
for s = 1:enco.stat,
for j = 1:enco.ksym,
nxt = enco.next.states( s, j ); % state after transition
bin = enco.next.binout( s,:,j ); % transition output (encoder)
mtr = bin * llb' + bin * buf' ; % transition metric
mtr = mtr + metr( s,Cur ); % SOVA
if( metr( nxt,Nxt ) < mtr ),
diff( nxt,Nxt ) = 0.5 * ( mtr - metr( nxt,Nxt )); % SOVA
comp( nxt,Nxt ) = surv( nxt,Nxt ); % SOVA
inpc( nxt,Nxt ) = inpt( nxt,Nxt ); % SOVA
outc( nxt, Nxt, :) = outt( nxt, Nxt, :); % SOVA
metr( nxt,Nxt ) = mtr; % store the metric
surv( nxt,Nxt ) = s; % store the survival state
inpt( nxt,Nxt ) = j-1; % store the survival input
outt( nxt,Nxt,:) = fliplr(bin); % store the survival output
else
dif = 0.5 * ( metr( nxt,Nxt ) - mtr );
if( dif <= diff( nxt,Nxt ) )
diff( nxt,Nxt ) = dif; % SOVA
comp( nxt,Nxt ) = s; % SOVA
inpc( nxt,Nxt ) = j-1; % SOVA
outc( nxt,Nxt,:) = fliplr(bin); % SOVA
end
end
end
end
%% trace backwards:
if( i < win ), continue; end; % proceed if the buffer has been filled;
[ mtr, sur ] = max( metr( :,Nxt ) ); % find the intitial state (max metric)
b = i; % temporary bit index
clc = mod( Nxt-[1:win], win+1 ) +1; % indices in a 'cyclic buffer' operation
for j = 1:win, % for all the bits in the buffer
tmp = clc( j );
inp = inpt( sur, tmp ); % current bit-decoder output (encoder input)
outp(1:enco.n) = outt( sur, tmp,: ); % current bit-decoder input (encoder output)
t = [ enco.k*(b-1)+1:enco.k*b ]; % compute the index
out( t ) = enco.inp( inp+1,: ); % store the hard output
vout( (b-1)*enco.n+1:b*enco.n) = outp; % store the hard output of encoder's output
inc = inpc( sur, tmp ); % SOVA: competitor bit output
dif = diff( sur, tmp ); % SOVA: corresp. path metric difference
ouc(1:enco.n) = outc( sur, tmp,:); % SOVA: competitor bit output
srv = surv( sur, tmp ); % SOVA: temporary survivor path state
cmp = comp( sur, tmp ); % SOVA: competitor state (previous)
for k = j+1:win+1, % check all buffer bits srv and cmp paths
for ( m = 1:enco.n)
if ( outp( m ) ~= ouc( m ) )
tmp = dif ;
idx = ( b-1-((k-1)-j))*enco.n+m; % calculate index: [enc.k*(b-(k-1)+j-1)+1:enc.k*(b-(k-1)+j)]
sft( idx ) = min( sft(idx), tmp ); % update LLRs for bits that are different
end
end
% tmp = (outp==ouc)*INF+(outp~=ouc)*dif; % for each different bit store the new dif
% idx = ((b-1)*enco.n+1:b*enco.n) - enco.n*( (k-1)-j ); % calculate index: [enc.k*(b-(k-1)+j-1)+1:enc.k*(b-(k-1)+j)]
% sft( idx ) = min( sft(idx), tmp ); % update LLRs for bits that are different
if( srv == cmp ), break; end; % stop if surv and comp merge (no need to continue)
if( k == win+1 ), break; end; % stop if the end (otherwise: error)
if ( k ~= win+1 ),
tmp = clc( k );
inp = inpt( srv, tmp ); % previous surv bit
inc = inpt( cmp, tmp ); % previous comp bit
srv = surv( srv, tmp ); % previous surv state
cmp = surv( cmp, tmp ); % previous comp state
ouc(1:enco.n) = outt( cmp, tmp,:); % SOVA: competitor bit output
outp(1:enco.n) = outt( srv, tmp,:); % current bit-decoder input (encoder output)
end
end
sur = surv( sur, clc(j) ); % state for the previous surv bit
b = b - 1; % update bit index
end
end
% provide soft output with +/- sign:
lle = vout.*sft - llr - msg;
return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -