Robochameleon  v1.0
error_counter_miguel.m
1 function [ber,ser,ber_block,ser_block,blockmap,err_bits,totalbits,err_symb,totalsymb,ORIG_SYMBOLS, RX_SYMBOLS] = error_counter_v7b(RECEIVED_DATA,REFERENCE_DATA,param)
2 
3 
4 %% Param check
5 if ~isvector(REFERENCE_DATA)
6  error('Reference data must be a vector.');
7 end
8 
9 %% Get parameters
10 L_block_s = param.L; % Error counter block length, symbols; set to inf for one block
11 M = param.M;
12 coding = param.coding;
13 ber_th = 0.1; % BER threshold above which contribution of a block is rejected
14 D_tx_b = REFERENCE_DATA(:)';
15 [~,demap] = constmap('QAM',M, coding);
16 demap=demap(:,1);
17 N_demap = size(demap,2);
18 log2M_ = log2M(M);
19 L_rx_s = size(RECEIVED_DATA,1);
20 
21 %% Variable initialization
22 ORIG_SYMBOLS = zeros(size(RECEIVED_DATA),'uint16');
23 RX_SYMBOLS = zeros(size(RECEIVED_DATA),'uint16');
24 L_tx_s = size(D_tx_b,2);
25 L_block_s = min(L_block_s,L_rx_s); % In case of L_block = inf
26 N_loop = round(L_rx_s/L_block_s); % Number of error counter loop iterations
27 [c,P] = constref('QAM',M); % Generate reference constellation for symbol decisions
28 c = c/sqrt(P);
29 decision = @sd_kmeans; % Symbol decision function: hd_euclid, sd_kmeans
30 
31 err_bits = nan(1,N_loop);
32 err_symb = nan(1,N_loop);
33 totalsymb = repmat(L_block_s,1,N_loop-1);
34 totalsymb = [totalsymb L_rx_s-sum(totalsymb)];
35 totalbits = log2M_*totalsymb; % Total number of bits
36 
37 % Repeat tx data to account for possible wrap-around in the rx data.
38 % Take maximum of first and last block length to take into account
39 % possible variation in the last block length.
40 N_tx = ceil(max(totalsymb(1),totalsymb(end))/(L_tx_s-1))+1;
41 D_tx_b_rep = repmat(D_tx_b,1,N_tx);
42 
43 fprintf(1,'Error counter: %d block(s).\n',N_loop);
44 %% Error counter loop
45 idx_markers = [0 cumsum(totalsymb)];
46 for i=1:N_loop % For each block
47  idx = idx_markers(i)+1:idx_markers(i+1); % Sliding data indices
48  D_tx_b_ref = false(totalsymb(i),log2M_); % Create transposed for faster column access
49  rx_symbols = decision(RECEIVED_DATA(idx),c); % Make decision on the received signal
50  delay = nan(1,N_demap);
51  rx_bits = symb2bits(rx_symbols,M); % Convert to bits
52  rx_bits = rx_bits'; % Transpose for faster column access
53  err_bits(i) = 0;
54  for k=1:log2M_ % For each column (no. of columns == log2M)
55  tmp = sumbitxor(D_tx_b_rep,rx_bits(:,k)); % Check BER
56  [tmp_badbits(1), tmp_idx(1)] = min(tmp); % not negated
57  [tmp_badbits(2), tmp_idx(2)] = max(tmp); % negated
58  tmp_badbits(2) = totalsymb(i) - tmp_badbits(2);
59  [badbits_, which] = min(tmp_badbits);
60  delay(k) = tmp_idx(which);
61  err_bits(i) = err_bits(i) + badbits_;
62  % Construct original bit sequence
63  D_tx_b_ref(:,k) = logical(which - 1 - D_tx_b_rep(delay(k)+(0:totalsymb(i)-1)));
64  end
65  D_tx_b_ref = D_tx_b_ref';
66  ORIG_SYMBOLS(idx) = bits2symb(D_tx_b_ref, M);
67  RX_SYMBOLS(idx) = rx_symbols;
68 
69  rx_bits = symb2bits(rx_symbols,M); % Convert to bits
70 
71  ber_map = sparse(xor(D_tx_b_ref,rx_bits)); % BER error map
72  ser_map = logical(sum(ber_map,1)); % SER error map
73 
74  err_symb(i) = nnz(ser_map); % Number of symbol errors
75  %if err_bits(i)/totalbits(i) > ber_th
76  fprintf([num2str(err_bits(i)) '|']);
77 end
78 fprintf(1,'\n');
79 
80 ber_block = err_bits./totalbits;
81 blockmap = ber_block<.1;
82 if any(blockmap==0)
83  disp(['Excluded ' num2str(sum(blockmap==0)) ' blocks accounting for ' num2str(sum(err_bits(~blockmap))) ' errors']);
84 end
85 ber = sum(err_bits(blockmap))/sum(totalbits(blockmap));
86 ser_block = err_symb./totalsymb;
87 ser = sum(err_symb(blockmap))/sum(totalsymb(blockmap));
function hd_euclid(in X, in c)
Euclidean metric hard decision digital demodulation.