📄 sviternd.m
字号:
function [sys, x0, str, ts] = sviternd(t, x, u, flag, code_param, tran_func, leng, tran_prob, plot_flag);
%SVITERND SIMULINK file for convolution decoding using viterbi algorithm.
% This file is designed to be used in a SIMULINK S-Function block.
% The function requires the system inputs
% code_param = [N, K, M, num_state, num_std_sta]; % prepared by simviter
% tran_func = [A, B; C, D]; % prepared by simviter
% leng % memory length
% tran_prob % transfer probability
% % when it is not a three row matrix, take the code as hard decision one.
% plot_flag % should plot or not.
% % when it is not a positive integer, don't plot.
% % when it is a positive integer, keep the plot have the time length
% % as required.
% This function keeps a number of discrete-time states:
% figure number. -Inf: to be opened; 0 not need to plot; positive: handle
% figure posit. Current figure position.
% trace_num. current trace number.
% trace_flag. flag to indicate that computation is not under leng.
% stater. variable in keeping the very beinging of state.
% trace. a LENG-by-NUM_STD_STA matrix storage the traces.
% solut. a LENG-by-NUM_STD_STA matrix storage the possible msg.
% expense. a 2-by-NUM_STD_STA matrix storage the expense.
%
% Wes Wang
% Copyright (c) 1995-96 by The MathWorks, Inc.
% expense_flag == 0 when tran_prob IS NOT a three row matrix.
% In this case, all variable in this functions are integers.
% expense_flag == 0 when tran_prob IS a three row matrix.
% In this case, tran_prob, expense and some expense related
% variables are float, such as local_expense, right_exp, tmp etc.
% All others are interfer.
% The calculation C * cur_sta + D * inp are binary computation.
% this is a version of no-draw.
if (flag == 2) % refresh discrete-time states
% the major processing routine.
if u(length(u)) < .2
% in case of no signal, no processing.
return;
end;
% otherwise, there is a signal, have to process.
%x = [0; 0; 0; 0; starter; trace(:); solut(:); store_code; expense(:); y];
% | | | | | | | | | \- output
% \ \ \ \ \ \ \ \ \- weight, expense
% \ \ \ \ \start \-state \-decode \- code_storage
% \ \ \ \-trace_flag
% \ \ \-trace_num
% \ \-fig_position, keep for plot m-files.
% \-figure handle, keep for plot m-files.
% pre-process, assign parameters.
% the last input is the trigger signal. The others are the codeword input
u = u(:)';
% codeword length
N = code_param(1);
% message length
K = code_param(2);
% transfer function memory length
M = code_param(3);
% state number
num_state = code_param(4);
% STD state number
num_std_sta = code_param(5);
% pre-process, assign parameters.
% the current version uses only C and D. A and B will be used in the future
A = tran_func(1:num_state, 1:num_state);
B = tran_func(1:num_state, num_state+1:num_state+K);
C = tran_func(num_state+1:num_state+N, 1:num_state);
D = tran_func(num_state+1:num_state+N, num_state+1:num_state+K);
% pre-process, determine the location
[n_tran_prob, m_tran_prob] = size(tran_prob);
if n_tran_prob == 3
expense_flag = 1; % expense flag == 0; BSC code. == 1, with TRAN_PROB.
else
expense_flag = 0;
end;
% varaibles to record the weight trace back to the first state.
% the column number is the state number - 1.
% the first line is the previous. The second line is the current.
% pre-process, determine the location
nn_code = num_std_sta * N * 1000;
starter = x(5);
trace = [];
solut = [];
store_code = [];
% make the point of meaningful variabe to the storage variable x.
for i = 1 : leng
trace = [trace; x((i-1)*num_std_sta+6 : i*num_std_sta+5)'];
solut = [solut; x((i+leng-1)*num_std_sta+6 : (i+leng) * num_std_sta + 5)'];
store_code = [store_code; x(2*leng*num_std_sta+(i-1)*N+6 : 2*leng*num_std_sta+i*N+5)'];
end;
expense = [x(2*leng*num_std_sta+leng*N+6:(2*leng+1)*num_std_sta+leng*N+5)';
x((2*leng+1)*num_std_sta+leng*N+6:(2*leng+2)*num_std_sta+leng*N+5)'];
K2 = 2^K;
trace_num = x(3) + 1;
trace_flag = x(4);
if (trace_flag == 0) & (trace_num == leng)
trace_flag = 1;
end;
%clean-up spaces.
trace_pre = rem(trace_num - 2 + leng, leng) + 1;
trace(trace_num, :) = -ones(1, num_std_sta);
solut(trace_num, :) = zeros(1, num_std_sta);
store_code(trace_num,:) = u(1:N);
% fill up trace and solut
if (trace_flag == 0) & (trace_num == 1)
pre_state = starter + 1;
else
pre_state = find(trace(trace_pre, :) >= 0);
end;
% loop in calculating the expense
for j = 1 : length(pre_state)
jj = pre_state(j) - 1; % index number - 1 is the state.
cur_sta = de2bi(jj, num_state)';
% find the expense region
if expense_flag
for num_N = 1 : N
expen_work(num_N) = max(find(tran_prob(1,:) <= u(num_N)));
end;
end;
% update the state and calculate the expense
for num_k = 1 : K2
inp = de2bi(num_k - 1, K)';
out = rem(C * cur_sta + D * inp,2);
% X = A x + Bu to be added here.
nex_sta = [inp; cur_sta(1 : num_state - K)];
nex_sta_de = bi2de(nex_sta') + 1;
if expense_flag
% find the expense by the transfer probability
expen_0 = find(out' <= 0.5);
expen_1 = find(out' > 0.5);
local_expense = sum([tran_prob(2,expen_work(expen_0)) 0])...
+sum([tran_prob(3,expen_work(expen_1)) 0]);
else
local_expense = sum(rem(u(1:N) + out', 2));
end;
if trace(trace_num, nex_sta_de) < 0
% nothing happened yet. Fill all information.
% previous state.
trace(trace_num, nex_sta_de) = jj;
% input information.
solut(trace_num, nex_sta_de) = num_k - 1;
% weighting/expense
expense(2, nex_sta_de) = local_expense;
else
% something happended before. Take a comparison.
replace_flag = 0;
if expense_flag
if (local_expense + expense(1, jj+1)) > (expense(2, nex_sta_de) + expense(1, trace(trace_num, nex_sta_de)+1))
replace_flag = 1;
end;
else
if (local_expense + expense(1, jj+1)) < (expense(2, nex_sta_de) + expense(1, trace(trace_num, nex_sta_de)+1))
replace_flag = 1;
end;
end;
if replace_flag
% make a replacement other wise do nothing
expense(2, nex_sta_de) = local_expense;
solut(trace_num, nex_sta_de) = num_k - 1;
trace(trace_num, nex_sta_de) = jj;
end;
end;
end;
end;
% rearrange the first line of expense.
tmp = expense(1,:);
for j = 1 : num_std_sta
if trace(trace_num, j) >= 0
expense(1,j) = expense(2,j) + tmp(trace(trace_num, j)+1);
end;
end;
% decision making.
if trace_flag
% strike out the unnecessary.
for j_k = 1 : leng - 1
j = rem(trace_num - j_k + leng, leng) + 1;
j_pre = rem(trace_num - j_k - 1 + leng, leng) + 1;
pre_state = find(trace(j_pre, :) >= 0);
for num_k = 1 : length(pre_state)
jj = pre_state(num_k) - 1;
% in case of a state has not been continued, it will be strike out.
if isempty(find(trace(j, :) == jj))
trace(j_pre, pre_state(num_k)) = -1;
end;
end;
end;
% detect the converged result. eliminate a memory space.
trace_eli = rem(trace_num, leng) + 1;
trace_eli_non_z = find(trace(trace_eli,:) >= 0);
if length(trace_eli_non_z) > 1
% need to make a decision here.
% take the one with the complete path has the best expense.
if expense_flag
right_exp = find(expense(1, :) == max(expense(1,:)));
else
right_exp = find(expense(1, :) == min(expense(1,:)));
end;
right_exp = right_exp(1) - 1;
for j_k = 1 : leng - 1
% trace from trace_num to trace_eli
tmp = rem(trace_num - j_k + leng, leng) + 1;
right_exp = trace(tmp, right_exp + 1);
end;
trace_eli_non_z = right_exp + 1;
tmp = find(trace(trace_eli, :) ~= -1);
tmp1 = find(tmp == trace_eli_non_z);
tmp(tmp1) = [];
for j_k = 1 : leng-1
% clean the path which is derived from trace_non_z
tmp1 = tmp;
tmp = [];
index_tmp = rem(trace_eli + j_k - 1, leng) + 1;
for j_j = 1 : length(tmp1)
tmp = [tmp find(trace(index_tmp, :) == tmp1(j_j)-1)];
end;
trace(index_tmp, tmp) = -ones(1, length(tmp));
end;
if expense_flag
expense(1, tmp) = -ones(1, length(tmp)) * nn_code;
else
expense(1, tmp) = ones(1, length(tmp)) * nn_code;
end;
end;
inp = de2bi(solut(trace_eli, trace_eli_non_z), K);
cur_sta = de2bi(starter, num_state);
out = rem(C * cur_sta' + D * inp', 2);
if expense_flag
% find the expense by the transfer probability
for num_N = 1 : N
expen_work(num_N) = max(find(tran_prob(1,:) <= store_code(trace_eli,num_N)));
end;
expen_0 = find(out' <= 0.5);
expen_1 = find(out' > 0.5);
local_expense = sum([tran_prob(2,expen_work(expen_0)) 0])...
+sum([tran_prob(3,expen_work(expen_1)) 0]);
else
local_expense = sum(rem(store_code(trace_eli,:) + out', 2));
end;
ind_exp = find(expense(1,:) ~= nn_code);
starter = trace_eli_non_z - 1;
output = [inp(:); local_expense];
else %(if trace_flag)
output = zeros(K+1, 1);
end; %(if trace_flag)
trace = trace';
solut = solut';
expense = expense';
store_code = store_code';
trace_num = rem(trace_num, leng);
sys = [0; 0; trace_num; trace_flag; starter; trace(:); solut(:); store_code(:); expense(:); output];
elseif flag == 3 % output
% if there is a trigger signal, output the new calculation
% otherwise keep the old one.
if u(length(u)) > 0.2
K = code_param(2);
len_x = length(x);
sys = x(len_x - K: len_x);
end;
elseif flag == 0
N = code_param(1);
K = code_param(2);
M = code_param(3);
num_state = code_param(4);
num_std_sta = code_param(5);
[n_tran_prob, m_tran_prob] = size(tran_prob);
if n_tran_prob == 3
expense_flag = 1; % expense flag == 0; BSC code. == 1, with TRAN_PROB.
else
expense_flag = 0;
end;
% veraible to record the weight trace back to the first state.
% the column number is the state number - 1.
% the first line is the previous. The second line is the current.
nn_code = num_std_sta * N * 1000;
if expense_flag
expense = [-ones(1, num_std_sta) * nn_code; zeros(1, num_std_sta)];
else
expense = [ones(1, num_std_sta) * nn_code; zeros(1, num_std_sta)];
end;
expense(1,1) = 0;
% the column number is the state + 1.
% the contents is the state it transfered from.
% the starter is always single number.
starter = 0;
% a fixed length
trace = zeros(leng, num_std_sta);
% the solution in each of the transfer as above.
% ith row is the transition input (msg) from (i-1)th row of trace to ith row
% of trace. When i = 1, the transfer is from starter to trace.
solut = zeros(leng, num_std_sta);
if plot_flag > 0
x0 = -Inf;
else
x0 = 0;
end;
y = zeros(K+1, 1);
store_code = zeros(leng*N, 1);
expense = expense';
% add output storage.
x0 = [x0; 0; 0; 0; starter; trace(:); solut(:); store_code; expense(:); y];
% | | | | | | | | | \- output
% \ \ \ \ \ \ \ \ \- weight, expense
% \ \ \ \ \start \-state \-decode \- code_storage
% \ \ \ \-trace_flag
% \ \ \-trace_num
% \ \-fig_position
% \-figure handle
sys = [0; length(x0); K+1; N+1; 0; 0; 1];
ts = [-1, 0];
elseif flag == 9
sys = [];
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -