📄 sovai.m
字号:
function [ out, lli ] = sovaI( msg, llr, trl, win, Lc )
global sim_consts;
% some parameters:
INF = 9e9; % infinity
enc = sim_consts.enci; % encoder parameters
len = length( llr ) / enc.k; % 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( enc.stat, win+1 ) -INF; % path metric buffer
metr( 1,1 ) = 0; % initial state => (0,0)
surv = zeros( enc.stat, win+1 ); % survivor state buffer
inpt = zeros( enc.stat, win+1 ); % survivor input buffer (dec. output)
diff = zeros( enc.stat, win+1 ); % path metric difference
comp = zeros( enc.stat, win+1 ); % competitor state buffer
inpc = zeros( enc.stat, win+1 ); % competitor input buffer
out = zeros( size(llr) ) + NaN; % hard output (bits)
sft = zeros( size(llr) ) + INF; % soft output (sign with reliability)
% 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*enc.n:-1:(i-1)*enc.n+1 ); % msg portion to be processed (reversed)
llb = llr( (i-1)+1:i ); % SOVA: llr portion to be processed
metr( :,Nxt ) = -INF -INF ; % (2*) helps in initial stages (!!!)
%% forward recursion:
for s = 1:enc.stat,
for j = 1:enc.ksym,
nxt = enc.next.states( s, j ); % state after transition
bin = enc.next.binout( s,:,j ); % transition output (encoder)
% mtr = bin*buf' + metr( s,Cur ); % transition metric
% mtr = mtr ...
% + enc.bininp( j )*(llb*enc.r)'; % SOVA
mtr = llb * enc.bininp( j ) + 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
metr( nxt,Nxt ) = mtr; % store the metric
surv( nxt,Nxt ) = s; % store the survival state
inpt( nxt,Nxt ) = j-1; % store the survival input
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
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
inp = inpt( sur, clc(j) ); % current bit-decoder output (encoder input)
out( b ) = inp; % store the hard output
tmp = clc( j );
cmp = comp( sur, tmp ); % SOVA: competitor state (previous)
inc = inpc( sur, tmp ); % SOVA: competitor bit output
dif = diff( sur, tmp ); % SOVA: corresp. path metric difference
srv = surv( sur, tmp ); % SOVA: temporary survivor path state
for k = j+1:win+1, % check all buffer bits srv and cmp paths
if( inp ~= inc ),
tmp = dif;
idx = b - ( (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
end
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
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:
out = (2*out-1) .* sft;
lli = out - llr - msg(1:enc.n:size(msg,2));
% out = sft;
return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -