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)
5 if ~isvector(REFERENCE_DATA)
6 error('Reference data must be a vector.');
10 L_block_s = param.L; % Error counter block length, symbols; set to inf for one block
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);
17 N_demap = size(demap,2);
19 L_rx_s = size(RECEIVED_DATA,1);
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
29 decision = @sd_kmeans; % Symbol decision function:
hd_euclid, sd_kmeans
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
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);
43 fprintf(1,'Error counter: %d block(s).\n',N_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
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)));
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;
69 rx_bits = symb2bits(rx_symbols,M); % Convert to bits
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
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)) '|']);
80 ber_block = err_bits./totalbits;
81 blockmap = ber_block<.1;
83 disp(['Excluded ' num2str(sum(blockmap==0)) ' blocks accounting for ' num2str(sum(err_bits(~blockmap))) ' errors']);
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.