Many changes
This commit is contained in:
@@ -34,17 +34,22 @@ classdef MLSE < handle
|
||||
|
||||
end
|
||||
|
||||
function signalclass = process(obj,signalclass)
|
||||
function [signalclass_hd,signalclass_sd] = process(obj,signalclass,ref_symbolclass)
|
||||
|
||||
data_in = signalclass.signal;
|
||||
data_ref = ref_symbolclass.signal;
|
||||
|
||||
data_out = obj.process_(data_in);
|
||||
[data_out_hd,data_out_sd] = obj.process_(data_in,data_ref);
|
||||
|
||||
signalclass.signal = data_out;
|
||||
signalclass_hd = signalclass;
|
||||
signalclass_hd.signal = data_out_hd;
|
||||
|
||||
signalclass_sd = signalclass;
|
||||
signalclass_sd.signal = data_out_sd;
|
||||
|
||||
end
|
||||
|
||||
function data_out = process_(obj,data_in)
|
||||
function [VITERBI_ESTIMATION_SYMBOLS,soft_decisions] = process_(obj,data_in,data_ref)
|
||||
|
||||
|
||||
% remove unnecessary zeros at start of impulse response to keep
|
||||
@@ -58,6 +63,17 @@ classdef MLSE < handle
|
||||
obj.DIR = [0 obj.DIR];
|
||||
end
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%%%%%% PREPARATIONS %%%%%%%%
|
||||
|
||||
%%%% Separate the equalized signal into the respective levels based on the actually transmitted level
|
||||
constellation = unique(data_ref);
|
||||
decisionLevels = (constellation(1:end-1) + constellation(2:end)) / 2;
|
||||
tx_bits = PAMmapper(numel(constellation),0).demap(data_ref);
|
||||
|
||||
|
||||
% impulse respnse i.e. [0.5, 1.0000]
|
||||
obj.DIR = flip(obj.DIR);
|
||||
|
||||
% RMS normalization of input data
|
||||
@@ -77,6 +93,7 @@ classdef MLSE < handle
|
||||
% Calculate all possible input symbols for the desired impulse
|
||||
% response. Row number is the index of the previous state,
|
||||
% column number is the index of the next state
|
||||
% noise free received == branch metrics
|
||||
noise_free_received = zeros(length(states),length(states));
|
||||
count_row = 1;
|
||||
count_col = 1;
|
||||
@@ -101,127 +118,302 @@ classdef MLSE < handle
|
||||
end
|
||||
end
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%%%%% FORWARD PASS %%%%%
|
||||
|
||||
|
||||
%
|
||||
% %% Optimized
|
||||
% % Preallocate and initialize variables
|
||||
% data_out = NaN(size(data_in)); % output vector
|
||||
% sum_path_metrics_res = zeros(length(states), length(data_in));
|
||||
% path_idx = zeros(length(states), length(data_in));
|
||||
%
|
||||
% % Precompute repmat size
|
||||
% num_states = length(states);
|
||||
% num_signals = numel(noise_free_received);
|
||||
%
|
||||
% % First trellis path (initialize)
|
||||
% sum_path_metrics = zeros(num_states, num_states);
|
||||
% path_metrics = (abs(data_in(1) - noise_free_received)).^2; % Use broadcasting instead of repmat
|
||||
% sum_path_metrics = sum_path_metrics + path_metrics; % Compute initial path metrics
|
||||
%
|
||||
% [sum_path_metrics_res(:,1), path_idx(:,1)] = min(sum_path_metrics, [], 2); % Best path for first step
|
||||
%
|
||||
% % Preallocate path_metrics and sum_path_metrics to avoid reallocating in each loop
|
||||
% path_metrics = zeros(num_states, num_signals);
|
||||
%
|
||||
% % Loop over remaining trellis paths
|
||||
% for n = 2:length(data_in)
|
||||
% % Avoid reallocation of sum_path_metrics, reuse the same matrix and update
|
||||
% previous_sum_path_metrics = sum_path_metrics_res(:,n-1).'; % Transpose once for broadcasting
|
||||
% sum_path_metrics = repmat(previous_sum_path_metrics, num_states, 1); % Avoid dynamic resizing
|
||||
%
|
||||
% % Calculate path metrics using broadcasting
|
||||
% path_metrics = (abs(data_in(n) - noise_free_received)).^2; % Avoid repmat
|
||||
%
|
||||
% % Update sum path metrics
|
||||
% sum_path_metrics = sum_path_metrics + path_metrics;
|
||||
%
|
||||
% % Find the best path for each state and store results
|
||||
% [sum_path_metrics_res(:,n), path_idx(:,n)] = min(sum_path_metrics, [], 2);
|
||||
% end
|
||||
%
|
||||
% %% Traceback
|
||||
% ideal_path = NaN(1, length(data_in)+1); % Preallocate ideal path
|
||||
% [~, ideal_path(length(data_in)+1)] = min(sum_path_metrics_res(:,length(data_in))); % Start from final state
|
||||
%
|
||||
% % Trace back through trellis
|
||||
% for h = length(data_in):-1:1
|
||||
% ideal_path(h) = path_idx(ideal_path(h+1),h); % Follow the best path back
|
||||
% end
|
||||
%
|
||||
% % Extract the output indices
|
||||
% idx_out = ideal_path(2:end);
|
||||
% Initialize the output vector
|
||||
pm = zeros(length(states),length(states));
|
||||
bm_fw = zeros(length(states),length(states),length(data_in));
|
||||
|
||||
% Forward Recursion (FSM Computation)
|
||||
for n = 1:length(data_in)
|
||||
|
||||
|
||||
bm = abs(data_in(n) - noise_free_received).^2;
|
||||
pm = pm + bm;
|
||||
[pm_survivor_fw(:,n),pm_survivor_fw_idx(:,n)] = min(pm,[],2); % choose lowest path metric as new state
|
||||
pm = repmat(pm_survivor_fw(:,n).',length(states),1); % update pm (chosen state to 2nd dimension -> FROM state)
|
||||
|
||||
bm_fw(:,:,n) = bm;
|
||||
|
||||
% OLD
|
||||
% initilaize the output vector
|
||||
data_out = NaN(size(data_in));
|
||||
|
||||
sum_path_metrics = zeros(length(states),length(states));
|
||||
|
||||
% first trellis path
|
||||
% euclidian distance as path metric
|
||||
path_metrics = (abs(repmat(data_in(1),size(noise_free_received)) - noise_free_received)).^2;
|
||||
sum_path_metrics = sum_path_metrics + path_metrics; % calculation of all possible sum path metrics
|
||||
[sum_path_metrics_res(:,1),path_idx(:,1)] = min(sum_path_metrics,[],2); % find the best path to each state, store sum path metric and predecessor for each state
|
||||
|
||||
% remaining trellis paths
|
||||
for n = 2:length(data_in)
|
||||
sum_path_metrics = repmat(sum_path_metrics_res(:,n-1).',length(states),1);
|
||||
% path_metrics = (repmat(data_in(n),size(noise_free_received)) - noise_free_received).^2;%.*prob_mat;
|
||||
path_metrics = (abs(repmat(data_in(n),size(noise_free_received)) - noise_free_received)).^2;
|
||||
sum_path_metrics = sum_path_metrics + path_metrics;
|
||||
[sum_path_metrics_res(:,n),path_idx(:,n)] = min(sum_path_metrics,[],2);
|
||||
end
|
||||
|
||||
%% trace back
|
||||
ideal_path = NaN(1,length(data_in)+1);
|
||||
% find ideal trellis path by going through the trellis
|
||||
% backwards
|
||||
[~,ideal_path(length(data_in)+1)] = min(sum_path_metrics_res(:,length(data_in)));
|
||||
% we can now get the best path as min
|
||||
best_fw_path = NaN(1,length(data_in)+1);
|
||||
|
||||
% find ideal trellis path by going through the trellis backwards
|
||||
[~,best_fw_path(length(data_in)+1)] = min(pm_survivor_fw(:,length(data_in)));
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%%%%% BACKWARD PASS %%%%%
|
||||
|
||||
% Initialize the output vector
|
||||
pm = zeros(length(states),length(states));
|
||||
pm_survivor_bw = zeros(length(states),length(data_in)+1);
|
||||
pm_survivor_bw_idx = zeros(length(states),length(data_in)+1);
|
||||
bm_bw = zeros(length(states),length(states),length(data_in)+1);
|
||||
|
||||
% starting with the state that has the lowest sum path
|
||||
% metric, follow the stored information about the
|
||||
% predecessor
|
||||
for h = length(data_in):-1:1
|
||||
ideal_path(h) = path_idx(ideal_path(h+1),h);
|
||||
|
||||
best_fw_path(h) = pm_survivor_fw_idx(best_fw_path(h+1),h);
|
||||
|
||||
bm = abs(data_in(h) - noise_free_received).^2;
|
||||
pm = pm + bm.';
|
||||
[pm_survivor_bw(:,h),pm_survivor_bw_idx(:,h)] = min(pm,[],2); % choose lowest path metric as new state
|
||||
pm = repmat(pm_survivor_bw(:,h).',length(states),1); % update pm (chosen state to 2nd dimension -> FROM state)
|
||||
|
||||
bm_bw(:,:,h) = bm;
|
||||
|
||||
end
|
||||
|
||||
idx_out = ideal_path(2:length(data_in)+1);
|
||||
VITERBI_ESTIMATION_IDX(1:length(data_in)) = first_sym(best_fw_path(2:end));
|
||||
VITERBI_ESTIMATION_SYMBOLS(1:length(data_in)) = constellation(best_fw_path(2:end));
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%%%%% FORWARD PASS %%%%%
|
||||
|
||||
%calc the log probabilities (llp's)
|
||||
|
||||
for k = 2:length(data_in)
|
||||
|
||||
fsm = repmat(pm_survivor_fw(:,k-1)',[length(states),1]); %pm_survivor_fw size: length(states)xlength(sequence)
|
||||
bm = bm_fw(:,:,k); %bm_fw size: length(states)xlength(states)xlength(sequence)
|
||||
bsm = repmat(pm_survivor_bw(:,k)',[length(states),1]); %pm_survivor_bw size: length(states)xlength(sequence)+1
|
||||
|
||||
llp(:,k) = min(fsm+bm+bsm,[],2);
|
||||
|
||||
end
|
||||
|
||||
% directly decide based on lowest LLP index
|
||||
[~,llp_based_state_seq]=min(llp);
|
||||
LLP_EST(1:length(data_in)) = constellation(llp_based_state_seq);
|
||||
rx_bits = PAMmapper(numel(constellation),0).demap(LLP_EST');
|
||||
[~,~,ber_llp,~] = calc_ber(rx_bits,tx_bits,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
||||
fprintf('LLP BER : %.2e \n',ber_llp);
|
||||
% [~,~,ber_llp,~] = calc_ber(circshift(rx_bits,1),tx_bits,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
||||
% fprintf('LLP BER +1: %.2e \n',ber_llp);
|
||||
% [~,~,ber_llp,~] = calc_ber(circshift(rx_bits,-1),tx_bits,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
||||
% fprintf('LLP BER -1: %.2e \n',ber_llp);
|
||||
|
||||
%%%% DECIDE based on Viterbi traceback
|
||||
rx_bits = PAMmapper(numel(constellation),0).demap(VITERBI_ESTIMATION_SYMBOLS');
|
||||
[~,~,ber_viterbi,~] = calc_ber(rx_bits,tx_bits,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
||||
fprintf('Viterbi BER: %.2e \n',ber_viterbi);
|
||||
% [~,~,ber_viterbi,~] = calc_ber(circshift(rx_bits,1),tx_bits,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
||||
% fprintf('Viterbi BER: %.2e \n',ber_viterbi);
|
||||
|
||||
% directly decide based on the FW path metrics
|
||||
[~,fw_direct_state_seq]=min(pm_survivor_fw);
|
||||
FW_EST(1:length(data_in)) = constellation(fw_direct_state_seq);
|
||||
rx_bits = PAMmapper(numel(constellation),0).demap(FW_EST');
|
||||
[~,~,ber_fw,~] = calc_ber(rx_bits,tx_bits,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
||||
fprintf('FW BER: %.2e \n',ber_fw);
|
||||
|
||||
% directly decide based on the BW path metrics
|
||||
[~,bw_direct_state_seq]=min(pm_survivor_bw);
|
||||
BW_EST(1:length(data_in)) = constellation(bw_direct_state_seq(2:end));
|
||||
rx_bits = PAMmapper(numel(constellation),0).demap(BW_EST');
|
||||
[~,~,ber_bw,~] = calc_ber(rx_bits,tx_bits,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
||||
fprintf('BW BER: %.2e \n',ber_bw);
|
||||
% [~,~,ber_viterbi,~] = calc_ber(circshift(rx_bits,1),tx_bits,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
||||
% fprintf('BW BER: %.2e \n',ber_viterbi);
|
||||
% [~,~,ber_viterbi,~] = calc_ber(circshift(rx_bits,-1),tx_bits,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
||||
% fprintf('BW BER: %.2e \n',ber_viterbi);
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
tx_symbolpos = zeros(numel(constellation),length(data_ref));
|
||||
est_symbolpos = zeros(numel(constellation),length(data_ref));
|
||||
for lvl = 1:numel(constellation)
|
||||
tx_symbolpos(lvl,data_ref==constellation(lvl)) = 1;
|
||||
est_symbolpos(lvl,VITERBI_ESTIMATION_IDX==first_sym(lvl)) = 1;
|
||||
est_symbolpos_llm(lvl,llp_based_state_seq==lvl) = 1;
|
||||
end
|
||||
|
||||
est_symbolpos= logical(est_symbolpos);
|
||||
tx_symbolpos = logical(tx_symbolpos);
|
||||
est_symbolpos_llm = logical(est_symbolpos_llm);
|
||||
|
||||
figure(299);clf;hold on;
|
||||
llp_filt = NaN(length(states),length(data_in));
|
||||
llp_ = llp - min(llp,[],1);
|
||||
for c = 2%:numel(constellation)
|
||||
for c2 = 1:3%numel(constellation)
|
||||
|
||||
if obj.duobinary_output
|
||||
%use duobinary encoder, output is already scaled inside this
|
||||
%one
|
||||
data_out = Duobinary().encode(first_sym(idx_out));
|
||||
idx = est_symbolpos_llm(c,:);
|
||||
llp_filt(c2,idx) = (llp(c2,idx));
|
||||
|
||||
plotidx = 2:200000;
|
||||
scatter(plotidx,llp_filt(c2,plotidx),1,'o','LineWidth',1,'DisplayName',sprintf('LLP of Symbol %d | %d was transmitted',c2,c));
|
||||
|
||||
else
|
||||
%
|
||||
data_out(1:length(data_in)) = first_sym(idx_out);
|
||||
% scale to rms = 1 using the standard sqrt() expressions
|
||||
if obj.M == 4
|
||||
data_out = data_out./sqrt(5);
|
||||
elseif obj.M == 6
|
||||
data_out = data_out./sqrt(10);
|
||||
elseif obj.M == 8
|
||||
data_out = data_out./sqrt(21);
|
||||
end
|
||||
end
|
||||
|
||||
% Assume llp is a 4 x N matrix (4 PAM-4 symbols, N time steps)
|
||||
[numSymbols, numTimeSteps] = size(llp);
|
||||
P_symbols = zeros(numSymbols, numTimeSteps); % To hold the soft output probabilities
|
||||
|
||||
for k = 1:numTimeSteps
|
||||
|
||||
% Compute the exponentials. (Use -llp_shifted if llp's are costs.)
|
||||
exponents = -llp_(:, k);
|
||||
|
||||
% Normalize to form a probability vector.
|
||||
P_symbols(:, k) = exponents / sum(exponents);
|
||||
end
|
||||
|
||||
% Optionally, if you prefer a single soft output value per symbol (an expectation),
|
||||
% define your PAM-4 constellation levels, e.g.:
|
||||
soft_output = sum(P_symbols .* constellation, 1); % 1 x N vector of soft outputs
|
||||
|
||||
|
||||
%%%% BITWISE LLR's ??? %%%%%
|
||||
figure(100);
|
||||
clf
|
||||
hold on
|
||||
title('LLR between inner and outer bits')
|
||||
bitmapping = PAMmapper(numel(constellation),0).demap(constellation);
|
||||
for bp = 1:size(bitmapping,2)
|
||||
pos_bitone = find(bitmapping(:,bp)==1);
|
||||
pos_bitzero = find(bitmapping(:,bp)~=1);
|
||||
|
||||
llr_bits(bp,:) = min(llp(pos_bitone,:),[],1) - min(llp(pos_bitzero,:),[],1);
|
||||
|
||||
subplot(size(bitmapping,2),1,bp)
|
||||
scatter(1:length(data_ref),llr_bits(bp,:),1,'.');
|
||||
end
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
% From: Log-Likelihood Probabilities LLP --> To: Log-Likelihood Ratios LLR
|
||||
for s = 1:length(states)-1
|
||||
llr(s,:) = llp_(s,:) - llp_(s+1,:); % subtract llp's of successive const. points to get llr's
|
||||
end
|
||||
|
||||
% Build Sets of LLR's that contain only those values at
|
||||
% timepoint k, where the symbols:
|
||||
% a) were actually transmitted: set "S"
|
||||
% b) were decoded by viterbi: set "SC"
|
||||
S = NaN(length(states)-1,length(data_in));
|
||||
SC = NaN(length(states)-1,length(data_in));
|
||||
|
||||
llp_inf = llp_;
|
||||
llp_inf(llp_==0) = Inf;
|
||||
[~,scnd_idx] = min(llp_inf,[],1) ;
|
||||
for s = 1:length(states)-1
|
||||
|
||||
%%% SET "S"
|
||||
% find all time indices k, where const point s was actually transmitted
|
||||
indice = tx_symbolpos(s,:)==1;
|
||||
S(s,indice) = llr(s,indice);
|
||||
%calc mean of all llr's where symbol s was transmitted
|
||||
K(s,1) = mean(S(s,indice),'omitnan');
|
||||
|
||||
% find all time indices k, where const. point s+1 was actually transmitted
|
||||
indice_plusone = tx_symbolpos(s+1,:)==1;
|
||||
S(s,indice_plusone) = llr(s,indice_plusone);
|
||||
K(s,2) = mean(S(s,indice_plusone),'omitnan');
|
||||
|
||||
|
||||
%%% SET "SC"
|
||||
% find all time indices k, where symbol s was decoded
|
||||
% idx: find positions in time where a symbol s was decoded
|
||||
idx = est_symbolpos_llm(s,:);
|
||||
% idx 2: find positions where the strongest competitor is
|
||||
% s+1, i.e. the second best llp is at s+1
|
||||
idx2 = scnd_idx == s+1;
|
||||
SC(s,idx&idx2) = llr(s,idx&idx2);
|
||||
KC(s,1) = mean(SC(s,idx&idx2),'omitnan');
|
||||
|
||||
% find all time indices k, where symbol s+1 was decoded
|
||||
% idx: find positions in time where a symbol s+1 was decoded
|
||||
idx = est_symbolpos_llm(s+1,:);
|
||||
idx2 = scnd_idx == s;
|
||||
% idx 2: find positions where the strongest competitor is
|
||||
% s, i.e. the second best llp is at s
|
||||
SC(s,idx&idx2) = llr(s,idx&idx2);
|
||||
KC(s,2) = mean(SC(s,idx&idx2),'omitnan');
|
||||
|
||||
% scale the sets, using the average (?) of the
|
||||
llrcn(s,:) = SC(s,:) * ( constellation(s+1)-constellation(s) ) ./ ( K(s,2)-K(s,1)) + decisionLevels(s);
|
||||
|
||||
end
|
||||
|
||||
figure(111)
|
||||
title("Bla")
|
||||
clf
|
||||
for s = 1:length(states)-1
|
||||
figure(1111)
|
||||
hold on
|
||||
title(sprintf('llrcn = llp %d - llp %d',s, s+1,s, s+1));
|
||||
scatter(1:length(llrcn),llrcn(s,:),1,'.');
|
||||
|
||||
|
||||
% STUFENARTIGE LLR'S UND LLP'S %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
figure(111)
|
||||
|
||||
subplot(1,length(states),s)
|
||||
hold on
|
||||
title(sprintf('llr = llp %d - llp %d \n SC=llr(tx sym = %d or %d)',s, s+1,s, s+1));
|
||||
scatter(1:length(llr),llr(s,:),1,'.');
|
||||
scatter(1:length(SC),SC(s,:),1,'.');
|
||||
yline([K(s,1),K(s,2)]);
|
||||
low = min(min(llr));
|
||||
hi = max(max(llr));
|
||||
ylim([low,hi]);
|
||||
|
||||
subplot(1,length(states),length(states))
|
||||
hold on
|
||||
scatter(1:length(llr),llr(s,:),1,'.');
|
||||
ylim([low,hi]);
|
||||
|
||||
|
||||
% HISTOGRAMME %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
figure(112)
|
||||
subplot(length(states),1,s)
|
||||
hold on
|
||||
title(sprintf('histogram of llr; between const point %d - %d',s, s+1));
|
||||
histogram(llrcn(s,:),10000,'EdgeAlpha',0)
|
||||
% histogram(SC(s,:),10000,'EdgeAlpha',0)
|
||||
xlim([-20, 20]);
|
||||
subplot(length(states),1,length(states))
|
||||
hold on
|
||||
histogram(llrcn(s,:),10000,'EdgeAlpha',0)
|
||||
% histogram(SC(s,:),10000,'EdgeAlpha',0)
|
||||
% xlim([-20, 20]);
|
||||
|
||||
end
|
||||
|
||||
softdecisions = mean(llrcn,1,'omitnan');
|
||||
|
||||
distance = abs(VITERBI_ESTIMATION_SYMBOLS-llrcn);
|
||||
[win_cost,win_idx] = min(distance,[],1);
|
||||
|
||||
for i = 1:length(data_in)
|
||||
soft_decisions(i) = llrcn(win_idx(i),i);
|
||||
end
|
||||
|
||||
soft_decisions = max(llrcn,[],1);
|
||||
|
||||
showLevelHistogram(soft_decisions,data_ref)
|
||||
|
||||
figure()
|
||||
% scatter(1:length(data_in),VITERBI_ESTIMATION_SYMBOLS,1,'.');
|
||||
scatter(1:length(data_in),soft_decisions,1,'.');
|
||||
|
||||
|
||||
MLM_ESTIMATION(1:length(data_in)) = PAMmapper(numel(constellation),0).quantize(soft_decisions)';
|
||||
rx_bits = PAMmapper(numel(constellation),0).demap(MLM_ESTIMATION');
|
||||
[~,~,ber_mlm,~] = calc_ber(rx_bits,tx_bits,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
||||
fprintf('MLM BER: %.2e \n',ber_mlm);
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
methods (Access=private)
|
||||
% Cant be seen from outside! So put all your functions here that can/
|
||||
% shall not be called from outside
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user