www.pudn.com > mimo-code.rar > detect.m, change:2003-06-09,size:4985b
function varargout = detect(sig_down,dlt,slt,ch_coefs,varargin)
%DETECT Multidimensional data detector.
% D_E = DETECT(S,DLT,SLT,ALPHA) performs the maximum likelihood
% sequence estimation (MLSE) i.e. Viterbi algorithm on the received
% signal and returns the data estimations. The look-up tables DLT and
% SLT are used together with the external function BRMET which is
% called during the computation to evaluate branch metric ALPHA
% includes a channel complex path fadings.
%
% [DATA_EST,STATE_EST] = DETECT(...) also returns a matrix including
% the track with most probable path in the code trellis. This matrix is
% required when the decoding process suppose to be displayed with
% DISPTRELL function.
%
% [D_E,S_E] = DETECT(...,'PropertyName',PropertyValue,...)
%
% Detect Property List
%
% Echo 'on' | {'off'}
%
% See also BRMET, DISPTRELL, MFILTER.
% Copyright 2001-2003 Kamil Anis, anisk@feld.cvut.cz
% Dept. of Radioelectronics,
% Faculty of Electrical Engineering
% Czech Technical University in Prague
% $Revision: 2.1 $ $Date: 2003/1/16 17:33:28 $
% --
% <additional stuff goes here>
global ECHO TIMING
name = 'DETECT';
[idt,tag] = iecho(name);
nopts = length(varargin) / 2;
opts = reshape(varargin,[2 nopts])';
ord1 = strmatch('Echo',opts(:,1));
% Echo
if ~isempty(ord1) % first check whether local option exists
value1 = opts{ord1,2};
switch value1
case 'on'
ech = 1;
case 'off'
ech = 0;
otherwise
disp(' ');
disp([tag,'Invalid option for Echo property.']);
disp([idt,'Possible values are ''on''|{''off''}.']);
disp(' ');
ech = 0;
end
else
if ~isempty(ECHO) % than check whether global option exists
switch ECHO
case 'on'
ech = 1;
case 'off'
ech = 0;
otherwise
disp(' ');
disp([tag,'Invalid option for Echo property.']);
disp([idt,'Possible values are ''on''|{''off''}.']);
disp(' ');
ech = 0;
end
else % if there are no settings use the defaults
ech = 0; % default value
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% BODY BEGIN %%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if ech
disp(' ');
disp([tag,'Performing data detection. This may take a while.']);
disp([idt,'Please wait...']);
end
[step_final,space_dim,frames] = size(sig_down);
[s,md,foo] = size(dlt);
load qam16.txt;
if ~TIMING % disable timing when running performance measurement
tic;
end
for k = 1:frames
% running multi-dimensional Viterbi algorithm
% make all starting paths unprobable except for the correct one
metric(1,2:s) = realmax;
for l = 1:step_final
for j = 1:s % current j
% finding all previous states s_pre leads to current sate j
[s_pre,foo] = find(slt == j);
% determining a pair position relevant to the state j
% {1,2,3,4,5,6,7,8} -> {1,2,3,4,1,2,3,4}
pos = mod(j - 1,md) + 1;
% picking-up the pairs corresponding to each of s_pre states
data_test = dlt(s_pre,pos,:);
data_test = reshape(data_test,[md space_dim]);
% mapping pairs to appropriate constellation
if md == 16 % 16QAM
for r = 1:space_dim
k1(:,r) = qam16(data_test(:,r) + 1,1);
k2(:,r) = qam16(data_test(:,r) + 1,2);
end
q_test = (2 * k1 - md - 1) - i * (2 * k2 - md - 1);
else % 4,8PSK
expr = i * 2 * pi / md;
q_test = exp(expr * data_test);
end
% evaluating branch metric
metric_d = brmet(sig_down(l,:,k),q_test,ch_coefs(:,:,k));
% adds the data_test metrices to the previous states
metric_md = metric(l,s_pre)' + metric_d;
% choosing a metric with lowest accumulated value
[metric_min,metric_pos] = min(metric_md);
% and storing it's value to the matrix of metrices
metric(l + 1,j) = metric_min;
% creates a states matrix of s_pre (with lowest metric)
vit_state(l + 1,j) = s_pre(metric_pos);
% creates a matrix of appropriate data_test
vit_data(l + 1,j) = pos - 1;
end
end
% finding the best path at the trellis end
[foo,state_best] = min(metric(end,:));
state_est(step_final + 1) = state_best;
% back tracking
for l = step_final:-1:1
state_est(l) = vit_state(l + 1,state_est(l + 1));
data_est(l,:,k) = vit_data(l + 1,state_est(l + 1));
end
end
if ~TIMING
totaltime = toc;
else
totaltime = 0;
end
varargout = {data_est,state_est};
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% BODY END %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if ech
hour = round(totaltime / 3600);
mins = round(totaltime / 60);
secs = mod(totaltime,60);
str1 = num2str(frames * step_final * s);
str2 = sprintf('%1d',hour);
str3 = sprintf('%1d',mins);
str4 = sprintf('%1.1f',secs);
disp([idt,'Total decoding complexity -> ',str1,' steps.']);
disp([idt,'Total elapsed time -> ',str2,' hrs, ',str3,' min, ',str4,...
' sec.']);
disp(' ');
end