ML Equalizer works now.
Not yet perfectly integrated into all the routines
This commit is contained in:
@@ -1,13 +1,41 @@
|
|||||||
classdef ML_MLSE < handle
|
classdef ML_MLSE < handle
|
||||||
% Implementation of plain and simple FFE.
|
% ALGORITHM DESCRIBED IN:
|
||||||
% 1) Training mode (stable performance when you use NLMS)
|
% W. Lanneer and Y. Lefevre, “Machine Learning-Based Pre-Equalizers for
|
||||||
% 2) Decision directed mode
|
% Maximum Likelihood Sequence Estimation in High-Speed PONs,”
|
||||||
%
|
% in 2023 31st European Signal Processing Conference
|
||||||
%LMS: mu in order of 0.0001 for acceptable convergence speed
|
|
||||||
%NLMS: mu in order of 0.01 for acceptable convergence speed
|
% Further ML Refs:
|
||||||
%RLS: mu is lambda -> 0.99 -> 1 (has a strong dependency on this! use a loop to find out best values)
|
% https://machinelearningmastery.com/cross-entropy-for-machine-learning/
|
||||||
%
|
% https://docs.pytorch.org/docs/stable/generated/torch.nn.CrossEntropyLoss.html
|
||||||
% FFE("epochs_tr",5,"epochs_dd",2,"len_tr",2^13,"mu_dd",mu_dd,"mu_tr",mu_tr,"order",25,"sps",2,"decide",0, "adaption",adaption_method(adaption),"dd_mode",use_dd_mode);
|
|
||||||
|
% The central idea is to overcome the (white-) noise assumption within the previously described
|
||||||
|
% Viterbi algorithm, more precisely a closed-loop optimization is proposed that finds a suitable
|
||||||
|
% filter-set to directly compute the branch metrics c_k (s,s^' ). These can directly be used to
|
||||||
|
% carry out the conventional Viterbi algorithm. The system consists of S^L S=F linear FIR filters,
|
||||||
|
% combined with one bias coefficient respectively. These filters take the received input samples to
|
||||||
|
% compute the branch metrics estimates (c_k ) ̂(s,s^' ) according toThe central idea is to overcome
|
||||||
|
% the (white-) noise assumption within the previously described Viterbi algorithm, more precisely
|
||||||
|
% a closed-loop optimization is proposed that finds a suitable filter-set to directly compute the
|
||||||
|
% branch metrics c_k (s,s^' ). These can directly be used to carry out the conventional Viterbi
|
||||||
|
% algorithm. The system consists of S^L S=F linear FIR filters, combined with one bias coefficient
|
||||||
|
% respectively. These filters take the received input samples to compute the branch metrics
|
||||||
|
% estimates. Finally, the usual Viterbi is carried out...
|
||||||
|
|
||||||
|
% Recommended Settings and some findings:
|
||||||
|
|
||||||
|
% Requires many training epochs. According to ML people, 100,200 or
|
||||||
|
% even up to 1000 epochs are normal for ML-convergence
|
||||||
|
|
||||||
|
% The mu parameter _can_ be adaptive - using the cross entropy and when
|
||||||
|
% analyzing the isolated training it looks very promisig. However, is
|
||||||
|
% later use I found this is not as stable as a fixed learning rate.
|
||||||
|
% mu = 0.1 worked good for me
|
||||||
|
|
||||||
|
% Longer orders/ filter length are not always better. For me order=11
|
||||||
|
% was good.
|
||||||
|
|
||||||
|
% Delay factor (delta) is good when the order is also increased. With
|
||||||
|
% order = 11, a delta of =4 shows good results
|
||||||
|
|
||||||
properties
|
properties
|
||||||
sps % usually 2
|
sps % usually 2
|
||||||
@@ -24,6 +52,8 @@ classdef ML_MLSE < handle
|
|||||||
mu_dd %weight update in dd mode
|
mu_dd %weight update in dd mode
|
||||||
epochs_dd
|
epochs_dd
|
||||||
|
|
||||||
|
adaptive_mu
|
||||||
|
|
||||||
constellation
|
constellation
|
||||||
|
|
||||||
L %viterbi memory length
|
L %viterbi memory length
|
||||||
@@ -50,11 +80,13 @@ classdef ML_MLSE < handle
|
|||||||
w
|
w
|
||||||
|
|
||||||
% --- New: fast state lookup ---
|
% --- New: fast state lookup ---
|
||||||
|
true_to_state_idx
|
||||||
state_dict % containers.Map: key(sequence)->state index
|
state_dict % containers.Map: key(sequence)->state index
|
||||||
key_fmt = '%.8g_'; % key format for sequence strings
|
key_fmt = '%.8g_'; % key format for sequence strings
|
||||||
nSym % |constellation|
|
nSym % |constellation|
|
||||||
|
|
||||||
ber = []
|
ber = []
|
||||||
|
ce = ones(1,1);
|
||||||
end
|
end
|
||||||
|
|
||||||
methods
|
methods
|
||||||
@@ -72,6 +104,8 @@ classdef ML_MLSE < handle
|
|||||||
options.mu_dd = 1e-5;
|
options.mu_dd = 1e-5;
|
||||||
options.epochs_dd = 5;
|
options.epochs_dd = 5;
|
||||||
|
|
||||||
|
options.adaptive_mu = 1;
|
||||||
|
|
||||||
options.delta = 0;
|
options.delta = 0;
|
||||||
options.traceback_depth = 1024;
|
options.traceback_depth = 1024;
|
||||||
|
|
||||||
@@ -180,11 +214,12 @@ classdef ML_MLSE < handle
|
|||||||
X_viterbi = X_viterbi.logbookentry(lbdesc); % append to logbook
|
X_viterbi = X_viterbi.logbookentry(lbdesc); % append to logbook
|
||||||
end
|
end
|
||||||
|
|
||||||
function [y,y_vit] = equalize(obj,x,d,mu,epochs,N,training)
|
function [y,y_ref] = equalize(obj,x,d,mu,epochs,N,training)
|
||||||
% ==============================================================
|
% ==============================================================
|
||||||
% FFE + Whitening + ML-Based Branch Metric Estimation + Viterbi
|
% FFE + Whitening + ML-Based Branch Metric Estimation + Viterbi
|
||||||
% ==============================================================
|
% ==============================================================
|
||||||
debug = 1;
|
debug = 1;
|
||||||
|
showPlots = 1;
|
||||||
|
|
||||||
% --- Input padding and preallocation
|
% --- Input padding and preallocation
|
||||||
y = zeros(N,1);
|
y = zeros(N,1);
|
||||||
@@ -200,7 +235,8 @@ classdef ML_MLSE < handle
|
|||||||
v_tilde = zeros(1,obj.nFeasible);
|
v_tilde = zeros(1,obj.nFeasible);
|
||||||
pred = zeros(nSymbols, obj.nStates, 'uint32');
|
pred = zeros(nSymbols, obj.nStates, 'uint32');
|
||||||
pm_sto = nan(obj.nStates, nSymbols,'like',pm);
|
pm_sto = nan(obj.nStates, nSymbols,'like',pm);
|
||||||
|
CE_accum = 0;
|
||||||
|
|
||||||
|
|
||||||
%%% START IDX
|
%%% START IDX
|
||||||
if training
|
if training
|
||||||
@@ -210,7 +246,7 @@ classdef ML_MLSE < handle
|
|||||||
start_sample = 1;
|
start_sample = 1;
|
||||||
end_sample = start_sample + (ceil(N/obj.sps)-1)*obj.sps;
|
end_sample = start_sample + (ceil(N/obj.sps)-1)*obj.sps;
|
||||||
else
|
else
|
||||||
start_sample = 1;
|
start_sample = 1;%obj.len_tr;
|
||||||
end_sample = N;
|
end_sample = N;
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -251,34 +287,72 @@ classdef ML_MLSE < handle
|
|||||||
% ===== Gradient update (Algorithm 1) =====
|
% ===== Gradient update (Algorithm 1) =====
|
||||||
|
|
||||||
if 1 %training
|
if 1 %training
|
||||||
% previous "to" becomes current "from" (shift-register)
|
% --- allocate storage once
|
||||||
true_from_state_idx = true_to_state_idx;
|
if epoch == 1 && symbol == 1
|
||||||
|
obj.true_to_state_idx = ones(ceil(N/obj.sps),1,'uint32');
|
||||||
% --- Build current "to" state from ABSOLUTE symbol index
|
|
||||||
if sym_idx >= obj.L
|
|
||||||
curr_seq = d(sym_idx-obj.L+1 : sym_idx); % [d_k-L+1 ... d_k]
|
|
||||||
key_to = obj.seq_key(flip(curr_seq)); % -> [d_k ... d_k-L+1]
|
|
||||||
if isKey(obj.state_dict, key_to)
|
|
||||||
true_to_state_idx = obj.state_dict(key_to);
|
|
||||||
else
|
|
||||||
% Fall back safely (should not happen with proper constellation)
|
|
||||||
true_to_state_idx = true_from_state_idx;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
% Not enough history yet for a full L-symbol state
|
|
||||||
% keep previous 'to' and 'from'
|
|
||||||
true_to_state_idx = true_to_state_idx;
|
|
||||||
true_from_state_idx = true_from_state_idx;
|
|
||||||
end
|
end
|
||||||
|
|
||||||
% Dirac delta over correct extended transition (from,to)
|
% --- previous "to" becomes current "from"
|
||||||
|
if symbol > 1
|
||||||
|
true_from_state_idx = obj.true_to_state_idx(symbol-1);
|
||||||
|
else
|
||||||
|
true_from_state_idx = 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
% --- compute or reuse "to" state
|
||||||
|
if epoch == 1
|
||||||
|
% only compute in first epoch
|
||||||
|
if sym_idx >= obj.L
|
||||||
|
key_to = obj.seq_key(flip(d(sym_idx-obj.L+1 : sym_idx)));
|
||||||
|
if isKey(obj.state_dict, key_to)
|
||||||
|
obj.true_to_state_idx(symbol) = obj.state_dict(key_to);
|
||||||
|
else
|
||||||
|
obj.true_to_state_idx(symbol) = true_from_state_idx;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
obj.true_to_state_idx(symbol) = true_from_state_idx;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
% --- reuse cached state from second epoch onward
|
||||||
|
true_to_state_idx = obj.true_to_state_idx(symbol);
|
||||||
|
|
||||||
|
% --- ensure valid (from,to)
|
||||||
dirac = zeros(obj.nFeasible,1);
|
dirac = zeros(obj.nFeasible,1);
|
||||||
dirac(obj.valid_from_idx==true_from_state_idx & ...
|
mask = obj.valid_from_idx==true_from_state_idx & ...
|
||||||
obj.valid_to_idx ==true_to_state_idx) = 1;
|
obj.valid_to_idx ==true_to_state_idx;
|
||||||
|
if any(mask)
|
||||||
|
dirac(mask) = 1;
|
||||||
|
else
|
||||||
|
idx = find(obj.valid_from_idx==true_from_state_idx,1,'first');
|
||||||
|
dirac(idx) = 1;
|
||||||
|
obj.true_to_state_idx(symbol) = obj.valid_to_idx(idx);
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
% softmax over -v_tilde (numerically safe shift)
|
% softmax over -v_tilde (numerically safe shift)
|
||||||
p = exp(-(v_tilde - max(v_tilde)));
|
v_shift = -(v_tilde - min(v_tilde)); % shift to small positive numbers
|
||||||
p = p./(sum(p)+eps);
|
v_shift = min(v_shift, 100); % clamp exponent argument (≈ exp(50)=3e21)
|
||||||
|
expv = exp(v_shift);
|
||||||
|
p = expv ./ (sum(expv) + eps);
|
||||||
|
|
||||||
|
% for logging only:
|
||||||
|
CE_symbol(symbol) = -log(p(dirac==1) + eps);
|
||||||
|
|
||||||
|
if sym_idx > obj.L
|
||||||
|
CE_smooth(symbol) = 0.01*CE_symbol(symbol) + 0.99*CE_smooth(symbol-1);
|
||||||
|
else
|
||||||
|
if epoch > 1
|
||||||
|
CE_smooth(symbol) = obj.ce(end); %use ce from last epoch or =1 for very first round?!
|
||||||
|
else
|
||||||
|
CE_smooth(symbol) = CE_symbol(symbol);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
CE_accum = CE_symbol(symbol) + CE_accum;
|
||||||
|
|
||||||
|
|
||||||
% gradient term (t - p)
|
% gradient term (t - p)
|
||||||
dmp = (dirac - p)'; % 1×nFeasible
|
dmp = (dirac - p)'; % 1×nFeasible
|
||||||
@@ -288,10 +362,14 @@ classdef ML_MLSE < handle
|
|||||||
|
|
||||||
% Start updates only when the ABSOLUTE symbol index has ≥ L history
|
% Start updates only when the ABSOLUTE symbol index has ≥ L history
|
||||||
if sym_idx >= obj.L
|
if sym_idx >= obj.L
|
||||||
|
if obj.adaptive_mu
|
||||||
|
mu_eff = CE_smooth(sym_idx);
|
||||||
|
mu_eff = max(min(mu_eff, 0.2), 1e-4);
|
||||||
|
else
|
||||||
|
mu_eff = mu;
|
||||||
|
end
|
||||||
|
|
||||||
|
obj.w = obj.w - mu_eff .* dL_Dw; % (Nf+1)×nFeasible
|
||||||
obj.w = obj.w - ones(size(dL_Dw,1),1).*mu .* dL_Dw; % (Nf+1)×nFeasible
|
|
||||||
% obj.w = obj.w - mu * dL_Dw; % (Nf+1)×nFeasible
|
|
||||||
end
|
end
|
||||||
|
|
||||||
% if debug && epoch > 2
|
% if debug && epoch > 2
|
||||||
@@ -335,42 +413,69 @@ classdef ML_MLSE < handle
|
|||||||
viterbi_path(n-1) = pred(n, viterbi_path(n));
|
viterbi_path(n-1) = pred(n, viterbi_path(n));
|
||||||
end
|
end
|
||||||
|
|
||||||
y_vit = obj.first_sym(viterbi_path);
|
y_ref = d(start_symbol:end);
|
||||||
y = obj.first_sym(viterbi_path);
|
y = obj.first_sym(viterbi_path);
|
||||||
|
|
||||||
if debug %&& training
|
if debug && training
|
||||||
sym_start = start_symbol;
|
sym_start = start_symbol;
|
||||||
sym_end = start_symbol + symbol - 1;
|
sym_end = start_symbol + symbol - 1;
|
||||||
ref_slice = d(sym_start : sym_end);
|
ref_slice = d(sym_start : sym_end);
|
||||||
err = sum(y ~= ref_slice(1:numel(y)));
|
err = sum(y ~= ref_slice(1:numel(y)));
|
||||||
|
|
||||||
ref_bits = PAMmapper(obj.S,0).demap(ref_slice);
|
try
|
||||||
eq_bits = PAMmapper(obj.S,0).demap(y);
|
ref_bits = PAMmapper(obj.S,0).demap(ref_slice);
|
||||||
[~, ~, ber, ~] = calc_ber(ref_bits, eq_bits, "skip_front", 10, "skip_end", 10, "returnErrorLocation", 1);
|
eq_bits = PAMmapper(obj.S,0).demap(y);
|
||||||
fprintf('Epoch: %d - BER: %.1e \n',epoch, ber);
|
[~, ~, ber, ~] = calc_ber(ref_bits, eq_bits, "skip_front", 10, "skip_end", 10, "returnErrorLocation", 1);
|
||||||
|
fprintf('Epoch: %d - BER: %.1e \n',epoch, ber);
|
||||||
obj.ber(epoch) = ber;
|
obj.ber(epoch) = ber;
|
||||||
|
catch
|
||||||
|
ser = err./length(y);
|
||||||
|
fprintf('Epoch: %d - SER: %.1e \n',epoch, ser);
|
||||||
|
end
|
||||||
|
|
||||||
% ser = err./length(y);
|
obj.ce(epoch) = CE_accum./symbol;
|
||||||
% fprintf('Epoch: %d - SER: %.1e \n',epoch, ser);
|
|
||||||
|
|
||||||
figure(10);
|
if showPlots
|
||||||
subplot(2,2,1:2);
|
figure(10);clf
|
||||||
heatmap(obj.w);
|
subplot(3,2,1:2);
|
||||||
title('Filter')
|
heatmap(obj.w);
|
||||||
|
title('Filter')
|
||||||
subplot(2,2,3);
|
|
||||||
v_tildemat = NaN(obj.nStates, obj.nStates);
|
subplot(3,2,3);
|
||||||
v_tildemat(obj.valid) = v_tilde; % log-domain scores
|
v_tildemat = NaN(obj.nStates, obj.nStates);
|
||||||
heatmap(v_tildemat);
|
v_tildemat(obj.valid) = v_tilde; % log-domain scores
|
||||||
title('Path Metrics (v_tilde)')
|
heatmap(v_tildemat);
|
||||||
|
title('Path Metrics (v_tilde)')
|
||||||
subplot(2,2,4);
|
|
||||||
scatter(1:symbol,pm_sto,1,'.')
|
subplot(3,2,4);
|
||||||
% plot(1:symbol,pm_sto,'LineStyle','none')
|
scatter(1:symbol,pm_sto,1,'.')
|
||||||
title('Path Metric Winners')
|
title('Path Metric Winners')
|
||||||
|
|
||||||
drawnow
|
subplot(3,2,5);hold on
|
||||||
|
scatter(1:symbol,CE_symbol,1,'.');
|
||||||
|
scatter(1:symbol,CE_smooth,1,'.')
|
||||||
|
title('Cross Entropy')
|
||||||
|
|
||||||
|
subplot(3,2,6); hold on
|
||||||
|
|
||||||
|
% Left y-axis: Cross Entropy (linear)
|
||||||
|
yyaxis left
|
||||||
|
scatter(1:length(obj.ce), obj.ce, 10, 's', 'filled')
|
||||||
|
ylabel('Cross Entropy')
|
||||||
|
|
||||||
|
% Right y-axis: BER (logarithmic)
|
||||||
|
yyaxis right
|
||||||
|
scatter(1:length(obj.ber), obj.ber, 10, 'd', 'filled')
|
||||||
|
set(gca, 'YScale', 'log')
|
||||||
|
ylabel('BER (log scale)')
|
||||||
|
|
||||||
|
xlim([1, epochs])
|
||||||
|
xlabel('Epoch')
|
||||||
|
title('Cross Entropy // BER')
|
||||||
|
grid on
|
||||||
|
|
||||||
|
drawnow
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ classdef MLSE < handle
|
|||||||
|
|
||||||
elseif trellis_state_mode == 2 %simply use the states from the ref signal (should be a robust option)
|
elseif trellis_state_mode == 2 %simply use the states from the ref signal (should be a robust option)
|
||||||
|
|
||||||
obj.trellis_states = reshape(unique(data_ref),size(obj.trellis_states));
|
obj.trellis_states = reshape(unique(data_ref),1,length(unique(data_ref)));
|
||||||
|
|
||||||
elseif trellis_state_mode == 3 %use_statistical_levels
|
elseif trellis_state_mode == 3 %use_statistical_levels
|
||||||
|
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ classdef Metricstruct
|
|||||||
SNR (1,1) double {mustBeNumeric} = NaN
|
SNR (1,1) double {mustBeNumeric} = NaN
|
||||||
SNR_level (:,1) double {mustBeNumeric} = []
|
SNR_level (:,1) double {mustBeNumeric} = []
|
||||||
STD (1,1) double {mustBeNumeric} = NaN
|
STD (1,1) double {mustBeNumeric} = NaN
|
||||||
STD_level (:,1) double {mustBeNumeric, mustBeNonnegative} = []
|
STD_level (:,1) double = []
|
||||||
STDrx (1,1) double {mustBeNumeric} = NaN
|
STDrx (1,1) double {mustBeNumeric} = NaN
|
||||||
STDrx_level (:,1) double {mustBeNumeric, mustBeNonnegative} = []
|
STDrx_level (:,1) double = []
|
||||||
EVM (1,1) double {mustBeNumeric} = NaN
|
EVM (1,1) double {mustBeNumeric} = NaN
|
||||||
EVM_level (:,1) double {mustBeNumeric} = []
|
EVM_level (:,1) double {mustBeNumeric} = []
|
||||||
|
|
||||||
|
|||||||
@@ -1,251 +1,251 @@
|
|||||||
% Script, that shows the data management routine :-)
|
% Script, that shows the data management routine :-)
|
||||||
|
|
||||||
loadExistingWareHouse = 0;
|
loadExistingWareHouse = 0;
|
||||||
|
|
||||||
if loadExistingWareHouse
|
if loadExistingWareHouse
|
||||||
|
|
||||||
[file, path] = uigetfile();
|
[file, path] = uigetfile();
|
||||||
wh = load([path filesep file]);
|
wh = load([path filesep file]);
|
||||||
wh = wh.wh;
|
wh = wh.wh;
|
||||||
wh.showInfo;
|
wh.showInfo;
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
% 1) Define all your parameters, best practice directly constructs a
|
% 1) Define all your parameters, best practice directly constructs a
|
||||||
% structure
|
% structure
|
||||||
|
|
||||||
params = struct;
|
params = struct;
|
||||||
|
|
||||||
params.l = [2,10];
|
params.l = [2,10];
|
||||||
|
|
||||||
params.dispersion = [0];
|
params.dispersion = [0];
|
||||||
|
|
||||||
params.sgm = [0];
|
params.sgm = [0];
|
||||||
|
|
||||||
% params.pol = ["YXYXYXYX","YXXYYXXY","YYYYYYYY"];
|
% params.pol = ["YXYXYXYX","YXXYYXXY","YYYYYYYY"];
|
||||||
params.pol = ["alternated","paired","copolarized"];
|
params.pol = ["alternated","paired","copolarized"];
|
||||||
|
|
||||||
params.p_in = [3];
|
params.p_in = [3];
|
||||||
|
|
||||||
params.p_out = [-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2];
|
params.p_out = [-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2];
|
||||||
|
|
||||||
params.pmd = [0.1];
|
params.pmd = [0.1];
|
||||||
|
|
||||||
params.gamma = [0.0023];
|
params.gamma = [0.0023];
|
||||||
|
|
||||||
params.realization = [1:20];
|
params.realization = [1:20];
|
||||||
|
|
||||||
params.numchannels = [16];
|
params.numchannels = [16];
|
||||||
|
|
||||||
params.center_wavelength = floor([getSweepWavelengths(35, 50e9, 1310)] .* 1000) ./ 1000 ;
|
params.center_wavelength = floor([getSweepWavelengths(35, 50e9, 1310)] .* 1000) ./ 1000 ;
|
||||||
params.center_wavelength = [1285 1287 1290 1292 1295];
|
params.center_wavelength = [1285 1287 1290 1292 1295];
|
||||||
params.center_wavelength = 1310;
|
params.center_wavelength = 1310;
|
||||||
|
|
||||||
params.channelspacing = [400e9];
|
params.channelspacing = [400e9];
|
||||||
|
|
||||||
params.random_zdw = [0];
|
params.random_zdw = [0];
|
||||||
|
|
||||||
%wh = warehouse :-)
|
%wh = warehouse :-)
|
||||||
wh = DataStorage(params);
|
wh = DataStorage(params);
|
||||||
|
|
||||||
wh.showInfo;
|
wh.showInfo;
|
||||||
|
|
||||||
wh.addStorage("ber");
|
wh.addStorage("ber");
|
||||||
|
|
||||||
wh.addStorage("totalBer");
|
wh.addStorage("totalBer");
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
%2) Simulate a bunch of data - TO BE IMPLEMENTED HERE - for now use scripts
|
%2) Simulate a bunch of data - TO BE IMPLEMENTED HERE - for now use scripts
|
||||||
%from Sebastian
|
%from Sebastian
|
||||||
|
|
||||||
%3) Once the simulation folder is around, specifiy path and analyze dirs
|
%3) Once the simulation folder is around, specifiy path and analyze dirs
|
||||||
|
|
||||||
path = uigetdir('C:\Users\Silas\Documents\MATLAB\Raw_Cluster_Simulations');
|
path = uigetdir('C:\Users\Silas\Documents\MATLAB\Raw_Cluster_Simulations');
|
||||||
|
|
||||||
allMat = getAllFilesInFolder(path,'.mat');
|
allMat = getAllFilesInFolder(path,'.mat');
|
||||||
allErr = getAllFilesInFolder(path,'.err');
|
allErr = getAllFilesInFolder(path,'.err');
|
||||||
|
|
||||||
%allMat = dir([path filesep '*.mat']);
|
%allMat = dir([path filesep '*.mat']);
|
||||||
|
|
||||||
%allErr = dir([path filesep '*.err']);
|
%allErr = dir([path filesep '*.err']);
|
||||||
|
|
||||||
if numel(allMat) == 0
|
if numel(allMat) == 0
|
||||||
warning('You defined an empty folder. Could not locate any .mat file.')
|
warning('You defined an empty folder. Could not locate any .mat file.')
|
||||||
else
|
else
|
||||||
fprintf('%-20s', 'Err Files:'); fprintf('%-12s', num2str(numel(allErr))); fprintf('\n');
|
fprintf('%-20s', 'Err Files:'); fprintf('%-12s', num2str(numel(allErr))); fprintf('\n');
|
||||||
fprintf('%-20s', 'Mat Files:'); fprintf('%-12s', num2str(numel(allMat))); fprintf('\n');
|
fprintf('%-20s', 'Mat Files:'); fprintf('%-12s', num2str(numel(allMat))); fprintf('\n');
|
||||||
fprintf('%-20s', 'Missing Mat Files:'); fprintf('%-12s', num2str(numel(allErr)-numel(allMat))); fprintf('\n');
|
fprintf('%-20s', 'Missing Mat Files:'); fprintf('%-12s', num2str(numel(allErr)-numel(allMat))); fprintf('\n');
|
||||||
end
|
end
|
||||||
|
|
||||||
%4) Now load that data
|
%4) Now load that data
|
||||||
|
|
||||||
f = waitbar(0,'Please wait...');
|
f = waitbar(0,'Please wait...');
|
||||||
cnt = 0;
|
cnt = 0;
|
||||||
|
|
||||||
for num = 1:numel(allMat)
|
for num = 1:numel(allMat)
|
||||||
|
|
||||||
fileName = allMat(num).name;
|
fileName = allMat(num).name;
|
||||||
fileFolder = allMat(num).path;
|
fileFolder = allMat(num).path;
|
||||||
fileExt = allMat(num).ext;
|
fileExt = allMat(num).ext;
|
||||||
%
|
%
|
||||||
matFile = load([fileFolder filesep fileName fileExt]);
|
matFile = load([fileFolder filesep fileName fileExt]);
|
||||||
matFile = matFile.loop_data;
|
matFile = matFile.loop_data;
|
||||||
|
|
||||||
% ____________________________________
|
% ____________________________________
|
||||||
% FIND THE DATAPOINT CURRENTLY LOADED
|
% FIND THE DATAPOINT CURRENTLY LOADED
|
||||||
zdw = 1310;
|
zdw = 1310;
|
||||||
|
|
||||||
channelplan = "symmetric";
|
channelplan = "symmetric";
|
||||||
|
|
||||||
channelspacing = str2double(strrep(regexp(fileName,'(_chsp)+([\d]*)','match'),'_chsp','')).*1e9;
|
channelspacing = str2double(strrep(regexp(fileName,'(_chsp)+([\d]*)','match'),'_chsp','')).*1e9;
|
||||||
|
|
||||||
numchannels = str2double(strrep(regexp(fileName,'(ch)+(_)+([\d]*)','match'),'ch_',''));
|
numchannels = str2double(strrep(regexp(fileName,'(ch)+(_)+([\d]*)','match'),'ch_',''));
|
||||||
|
|
||||||
center_wavelength = str2double(insertAfter(strrep(regexp(fileName,'(lambda)+([\d]*)','match'),'lambda',''),4,'.'));
|
center_wavelength = str2double(insertAfter(strrep(regexp(fileName,'(lambda)+([\d]*)','match'),'lambda',''),4,'.'));
|
||||||
|
|
||||||
center_wavelength = floor(center_wavelength * 1000) / 1000;
|
center_wavelength = floor(center_wavelength * 1000) / 1000;
|
||||||
|
|
||||||
if center_wavelength == 2192
|
if center_wavelength == 2192
|
||||||
continue
|
continue
|
||||||
end
|
end
|
||||||
|
|
||||||
center_wavelength = 1310;
|
center_wavelength = 1310;
|
||||||
|
|
||||||
random_zdw = str2double(strrep(regexp(fileName,'(rzwd)+([\d])','match'),'rzwd',''));
|
random_zdw = str2double(strrep(regexp(fileName,'(rzwd)+([\d])','match'),'rzwd',''));
|
||||||
|
|
||||||
l = str2double(strrep(regexp(fileName,'([L])+(_)+([\d]*)','match'),'L_',''));
|
l = str2double(strrep(regexp(fileName,'([L])+(_)+([\d]*)','match'),'L_',''));
|
||||||
|
|
||||||
d = str2double(strrep(regexp(fileName,'([D])+(_)+([\d]*)','match'),'D_',''));
|
d = str2double(strrep(regexp(fileName,'([D])+(_)+([\d]*)','match'),'D_',''));
|
||||||
|
|
||||||
if d == 0
|
if d == 0
|
||||||
sgm = false;
|
sgm = false;
|
||||||
else
|
else
|
||||||
sgm = true;
|
sgm = true;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
if numel(regexp(fileName,'(YYYY)','match')) > 1
|
if numel(regexp(fileName,'(YYYY)','match')) > 1
|
||||||
pol = "copolarized";
|
pol = "copolarized";
|
||||||
elseif numel(regexp(fileName,'(YXXY)','match')) > 1
|
elseif numel(regexp(fileName,'(YXXY)','match')) > 1
|
||||||
pol = "paired";
|
pol = "paired";
|
||||||
elseif numel(regexp(fileName,'(YXYX)','match')) > 1
|
elseif numel(regexp(fileName,'(YXYX)','match')) > 1
|
||||||
pol = "alternated";
|
pol = "alternated";
|
||||||
else
|
else
|
||||||
pol = "copolarized";
|
pol = "copolarized";
|
||||||
end
|
end
|
||||||
|
|
||||||
p_in = str2double(strrep(regexp(fileName,'(pow_)+([-,\d]{1})','match'),'pow_',''));
|
p_in = str2double(strrep(regexp(fileName,'(pow_)+([-,\d]{1})','match'),'pow_',''));
|
||||||
|
|
||||||
pmd = 0.1;
|
pmd = 0.1;
|
||||||
|
|
||||||
gamma = 0.0023;
|
gamma = 0.0023;
|
||||||
|
|
||||||
realiz = str2double(strrep(regexp(fileName,'(r)+([-,\d]{1,3})','match'),'r',''));
|
realiz = str2double(strrep(regexp(fileName,'(r)+([-,\d]{1,3})','match'),'r',''));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
% ____________________________________
|
% ____________________________________
|
||||||
% Get the information you want from current file
|
% Get the information you want from current file
|
||||||
rop=[];
|
rop=[];
|
||||||
ber = [];
|
ber = [];
|
||||||
for pow = 2:12
|
for pow = 2:12
|
||||||
|
|
||||||
module_number = '';
|
module_number = '';
|
||||||
for p = 1:11 %11 because there are 11 ROP branches in model
|
for p = 1:11 %11 because there are 11 ROP branches in model
|
||||||
|
|
||||||
% get ROP
|
% get ROP
|
||||||
if p == 1
|
if p == 1
|
||||||
p_out = matFile.dp_optatten_para.atten;
|
p_out = matFile.dp_optatten_para.atten;
|
||||||
else
|
else
|
||||||
p_out = matFile.("dp_optatten__"+(p)+"_para").atten;
|
p_out = matFile.("dp_optatten__"+(p)+"_para").atten;
|
||||||
end
|
end
|
||||||
|
|
||||||
p_out = round(p_out-10*log10(numel(matFile.config.parameters.common.wavelengthPlan)));
|
p_out = round(p_out-10*log10(numel(matFile.config.parameters.common.wavelengthPlan)));
|
||||||
|
|
||||||
for c = 1:numel(matFile.config.parameters.common.wavelengthPlan)
|
for c = 1:numel(matFile.config.parameters.common.wavelengthPlan)
|
||||||
|
|
||||||
ber(c) = matFile.("prms_compare_wdm__"+(p+1)+"_out"){1,c}.ber;
|
ber(c) = matFile.("prms_compare_wdm__"+(p+1)+"_out"){1,c}.ber;
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
totalBer = matFile.("prms_compare_wdm__"+(p+1)+"_out"){1,end}.totalBer;
|
totalBer = matFile.("prms_compare_wdm__"+(p+1)+"_out"){1,end}.totalBer;
|
||||||
|
|
||||||
if totalBer > 0.2 && channelspacing == 400e9 && pol == "alternated"
|
if totalBer > 0.2 && channelspacing == 400e9 && pol == "alternated"
|
||||||
disp("stopping here");
|
disp("stopping here");
|
||||||
pause;
|
pause;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
% ____________________________________
|
% ____________________________________
|
||||||
% Add value to warehouse at the correct position
|
% Add value to warehouse at the correct position
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
wh.addValueToStorage(ber,'ber',l,d,sgm,pol,p_in,p_out,pmd,gamma,realiz,numchannels, center_wavelength,channelspacing,random_zdw);
|
wh.addValueToStorage(ber,'ber',l,d,sgm,pol,p_in,p_out,pmd,gamma,realiz,numchannels, center_wavelength,channelspacing,random_zdw);
|
||||||
wh.getStoValue('ber',l,d,sgm,pol,p_in,p_out,pmd,gamma,realiz,numchannels, center_wavelength,channelspacing,random_zdw);
|
wh.getStoValue('ber',l,d,sgm,pol,p_in,p_out,pmd,gamma,realiz,numchannels, center_wavelength,channelspacing,random_zdw);
|
||||||
wh.addValueToStorage(totalBer,'totalBer',l,d,sgm,pol,p_in,p_out,pmd,gamma,realiz,numchannels,center_wavelength,channelspacing,random_zdw);
|
wh.addValueToStorage(totalBer,'totalBer',l,d,sgm,pol,p_in,p_out,pmd,gamma,realiz,numchannels,center_wavelength,channelspacing,random_zdw);
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
waitbar(num/numel(allMat),f,'Loading your data');
|
waitbar(num/numel(allMat),f,'Loading your data');
|
||||||
end
|
end
|
||||||
|
|
||||||
close(f)
|
close(f)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
% 4) Hey! the warehouse is here and (hopefully) filled with data :-)
|
% 4) Hey! the warehouse is here and (hopefully) filled with data :-)
|
||||||
|
|
||||||
% Create a save dialog
|
% Create a save dialog
|
||||||
defaultDir = 'C:\Users\Silas\Documents\MATLAB\Raw_Cluster_Simulations\';
|
defaultDir = 'C:\Users\Silas\Documents\MATLAB\Raw_Cluster_Simulations\';
|
||||||
defaultExt = '*.mat';
|
defaultExt = '*.mat';
|
||||||
[filename, pathname] = uiputfile(fullfile(defaultDir, defaultExt),'', 'wh.mat');
|
[filename, pathname] = uiputfile(fullfile(defaultDir, defaultExt),'', 'wh.mat');
|
||||||
|
|
||||||
% Check if the user pressed Cancel
|
% Check if the user pressed Cancel
|
||||||
if isequal(filename, 0) || isequal(pathname, 0)
|
if isequal(filename, 0) || isequal(pathname, 0)
|
||||||
disp('Save operation canceled.');
|
disp('Save operation canceled.');
|
||||||
else
|
else
|
||||||
% Save the variable to the selected file
|
% Save the variable to the selected file
|
||||||
save(fullfile(pathname, filename), 'wh');
|
save(fullfile(pathname, filename), 'wh');
|
||||||
disp(['Variable "wh" saved to: ', fullfile(pathname, filename)]);
|
disp(['Variable "wh" saved to: ', fullfile(pathname, filename)]);
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function matFileStructArray = getAllFilesInFolder(folderPath,extension)
|
function matFileStructArray = getAllFilesInFolder(folderPath,extension)
|
||||||
% Get a list of all files in the current folder
|
% Get a list of all files in the current folder
|
||||||
currentFolderFiles = dir(fullfile(folderPath, '*'));
|
currentFolderFiles = dir(fullfile(folderPath, '*'));
|
||||||
|
|
||||||
% Exclude '.' and '..' directories
|
% Exclude '.' and '..' directories
|
||||||
currentFolderFiles = currentFolderFiles(~ismember({currentFolderFiles.name}, {'.', '..'}));
|
currentFolderFiles = currentFolderFiles(~ismember({currentFolderFiles.name}, {'.', '..'}));
|
||||||
|
|
||||||
% Initialize the structure array for .mat files
|
% Initialize the structure array for .mat files
|
||||||
matFileStructArray = struct('path', {}, 'name', {}, 'ext', {});
|
matFileStructArray = struct('path', {}, 'name', {}, 'ext', {});
|
||||||
|
|
||||||
% Loop over each file in the current folder
|
% Loop over each file in the current folder
|
||||||
for i = 1:length(currentFolderFiles)
|
for i = 1:length(currentFolderFiles)
|
||||||
currentFile = currentFolderFiles(i);
|
currentFile = currentFolderFiles(i);
|
||||||
|
|
||||||
% Check if the current item is a file and has a .mat extension
|
% Check if the current item is a file and has a .mat extension
|
||||||
if ~currentFile.isdir && endsWith(currentFile.name, extension, 'IgnoreCase', true)
|
if ~currentFile.isdir && endsWith(currentFile.name, extension, 'IgnoreCase', true)
|
||||||
% If it's a .mat file, add it to the structure array
|
% If it's a .mat file, add it to the structure array
|
||||||
[matFileStructArray(end + 1).path,matFileStructArray(end+1).name, matFileStructArray(end+1).ext] = fileparts(fullfile(folderPath, currentFile.name));
|
[matFileStructArray(end + 1).path,matFileStructArray(end+1).name, matFileStructArray(end+1).ext] = fileparts(fullfile(folderPath, currentFile.name));
|
||||||
elseif currentFile.isdir
|
elseif currentFile.isdir
|
||||||
% If it's a directory, recursively call the function
|
% If it's a directory, recursively call the function
|
||||||
subfolderPath = fullfile(folderPath, currentFile.name);
|
subfolderPath = fullfile(folderPath, currentFile.name);
|
||||||
subfolderMatFiles = getAllFilesInFolder(subfolderPath,extension);
|
subfolderMatFiles = getAllFilesInFolder(subfolderPath,extension);
|
||||||
|
|
||||||
% Add .mat files from the subfolder to the structure array
|
% Add .mat files from the subfolder to the structure array
|
||||||
matFileStructArray = [matFileStructArray, subfolderMatFiles];
|
matFileStructArray = [matFileStructArray, subfolderMatFiles];
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -1,250 +1,250 @@
|
|||||||
% Script, that shows the data management routine :-)
|
% Script, that shows the data management routine :-)
|
||||||
|
|
||||||
loadExistingWareHouse = 0;
|
loadExistingWareHouse = 0;
|
||||||
|
|
||||||
if loadExistingWareHouse
|
if loadExistingWareHouse
|
||||||
|
|
||||||
[file, path] = uigetfile();
|
[file, path] = uigetfile();
|
||||||
wh = load([path filesep file]);
|
wh = load([path filesep file]);
|
||||||
wh = wh.wh;
|
wh = wh.wh;
|
||||||
wh.showInfo;
|
wh.showInfo;
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
% 1) Define all your parameters, best practice directly constructs a
|
% 1) Define all your parameters, best practice directly constructs a
|
||||||
% structure
|
% structure
|
||||||
|
|
||||||
params = struct;
|
params = struct;
|
||||||
|
|
||||||
params.l = [2, 10];
|
params.l = [2, 10];
|
||||||
|
|
||||||
params.dispersion = [0, 3];
|
params.dispersion = [0, 3];
|
||||||
|
|
||||||
params.sgm = [0, 1];
|
params.sgm = [0, 1];
|
||||||
|
|
||||||
% params.pol = ["YXYXYXYX","YXXYYXXY","YYYYYYYY"];
|
% params.pol = ["YXYXYXYX","YXXYYXXY","YYYYYYYY"];
|
||||||
params.pol = ["alternated","paired","copolarized"];
|
params.pol = ["alternated","paired","copolarized"];
|
||||||
|
|
||||||
params.p_in = [3];
|
params.p_in = [3];
|
||||||
|
|
||||||
params.p_out = [-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2];
|
params.p_out = [-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2];
|
||||||
|
|
||||||
params.pmd = [0.1];
|
params.pmd = [0.1];
|
||||||
|
|
||||||
params.gamma = [0.0023];
|
params.gamma = [0.0023];
|
||||||
|
|
||||||
params.realization = [1:20];
|
params.realization = [1:20];
|
||||||
|
|
||||||
params.numchannels = [1,2,4,8,16];
|
params.numchannels = [1,2,4,8,16];
|
||||||
|
|
||||||
params.center_wavelength = floor([getSweepWavelengths(35, 50e9, 1310)] .* 1000) ./ 1000 ;
|
params.center_wavelength = floor([getSweepWavelengths(35, 50e9, 1310)] .* 1000) ./ 1000 ;
|
||||||
params.center_wavelength = [1285 1287 1290 1292 1295];
|
params.center_wavelength = [1285 1287 1290 1292 1295];
|
||||||
params.center_wavelength = 1310;
|
params.center_wavelength = 1310;
|
||||||
|
|
||||||
params.channelspacing = [400e9];
|
params.channelspacing = [400e9];
|
||||||
|
|
||||||
params.random_zdw = [0,1];
|
params.random_zdw = [0,1];
|
||||||
|
|
||||||
%wh = warehouse :-)
|
%wh = warehouse :-)
|
||||||
wh = DataStorage(params);
|
wh = DataStorage(params);
|
||||||
|
|
||||||
wh.showInfo;
|
wh.showInfo;
|
||||||
|
|
||||||
wh.addStorage("ber");
|
wh.addStorage("ber");
|
||||||
|
|
||||||
wh.addStorage("totalBer");
|
wh.addStorage("totalBer");
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
%2) Simulate a bunch of data - TO BE IMPLEMENTED HERE - for now use scripts
|
%2) Simulate a bunch of data - TO BE IMPLEMENTED HERE - for now use scripts
|
||||||
%from Sebastian
|
%from Sebastian
|
||||||
|
|
||||||
%3) Once the simulation folder is around, specifiy path and analyze dirs
|
%3) Once the simulation folder is around, specifiy path and analyze dirs
|
||||||
|
|
||||||
path = uigetdir('C:\Users\Silas\Documents\MATLAB\Raw_Cluster_Simulations');
|
path = uigetdir('C:\Users\Silas\Documents\MATLAB\Raw_Cluster_Simulations');
|
||||||
|
|
||||||
allMat = getAllFilesInFolder(path,'.mat');
|
allMat = getAllFilesInFolder(path,'.mat');
|
||||||
allErr = getAllFilesInFolder(path,'.err');
|
allErr = getAllFilesInFolder(path,'.err');
|
||||||
|
|
||||||
%allMat = dir([path filesep '*.mat']);
|
%allMat = dir([path filesep '*.mat']);
|
||||||
|
|
||||||
%allErr = dir([path filesep '*.err']);
|
%allErr = dir([path filesep '*.err']);
|
||||||
|
|
||||||
if numel(allMat) == 0
|
if numel(allMat) == 0
|
||||||
warning('You defined an empty folder. Could not locate any .mat file.')
|
warning('You defined an empty folder. Could not locate any .mat file.')
|
||||||
else
|
else
|
||||||
fprintf('%-20s', 'Err Files:'); fprintf('%-12s', num2str(numel(allErr))); fprintf('\n');
|
fprintf('%-20s', 'Err Files:'); fprintf('%-12s', num2str(numel(allErr))); fprintf('\n');
|
||||||
fprintf('%-20s', 'Mat Files:'); fprintf('%-12s', num2str(numel(allMat))); fprintf('\n');
|
fprintf('%-20s', 'Mat Files:'); fprintf('%-12s', num2str(numel(allMat))); fprintf('\n');
|
||||||
fprintf('%-20s', 'Missing Mat Files:'); fprintf('%-12s', num2str(numel(allErr)-numel(allMat))); fprintf('\n');
|
fprintf('%-20s', 'Missing Mat Files:'); fprintf('%-12s', num2str(numel(allErr)-numel(allMat))); fprintf('\n');
|
||||||
end
|
end
|
||||||
|
|
||||||
%4) Now load that data
|
%4) Now load that data
|
||||||
|
|
||||||
f = waitbar(0,'Please wait...');
|
f = waitbar(0,'Please wait...');
|
||||||
cnt = 0;
|
cnt = 0;
|
||||||
|
|
||||||
for num = 1:numel(allMat)
|
for num = 1:numel(allMat)
|
||||||
|
|
||||||
fileName = allMat(num).name;
|
fileName = allMat(num).name;
|
||||||
fileFolder = allMat(num).path;
|
fileFolder = allMat(num).path;
|
||||||
fileExt = allMat(num).ext;
|
fileExt = allMat(num).ext;
|
||||||
%
|
%
|
||||||
matFile = load([fileFolder filesep fileName fileExt]);
|
matFile = load([fileFolder filesep fileName fileExt]);
|
||||||
matFile = matFile.loop_data;
|
matFile = matFile.loop_data;
|
||||||
|
|
||||||
% ____________________________________
|
% ____________________________________
|
||||||
% FIND THE DATAPOINT CURRENTLY LOADED
|
% FIND THE DATAPOINT CURRENTLY LOADED
|
||||||
zdw = 1310;
|
zdw = 1310;
|
||||||
|
|
||||||
channelplan = "symmetric";
|
channelplan = "symmetric";
|
||||||
|
|
||||||
channelspacing = str2double(strrep(regexp(fileName,'(_chsp)+([\d]*)','match'),'_chsp','')).*1e9;
|
channelspacing = str2double(strrep(regexp(fileName,'(_chsp)+([\d]*)','match'),'_chsp','')).*1e9;
|
||||||
|
|
||||||
numchannels = str2double(strrep(regexp(fileName,'(ch)+(_)+([\d]*)','match'),'ch_',''));
|
numchannels = str2double(strrep(regexp(fileName,'(ch)+(_)+([\d]*)','match'),'ch_',''));
|
||||||
|
|
||||||
center_wavelength = str2double(insertAfter(strrep(regexp(fileName,'(lambda)+([\d]*)','match'),'lambda',''),4,'.'));
|
center_wavelength = str2double(insertAfter(strrep(regexp(fileName,'(lambda)+([\d]*)','match'),'lambda',''),4,'.'));
|
||||||
|
|
||||||
center_wavelength = floor(center_wavelength * 1000) / 1000;
|
center_wavelength = floor(center_wavelength * 1000) / 1000;
|
||||||
|
|
||||||
if center_wavelength == 2192
|
if center_wavelength == 2192
|
||||||
continue
|
continue
|
||||||
end
|
end
|
||||||
|
|
||||||
center_wavelength = 1310;
|
center_wavelength = 1310;
|
||||||
|
|
||||||
random_zdw = str2double(strrep(regexp(fileName,'(rzwd)+([\d])','match'),'rzwd',''));
|
random_zdw = str2double(strrep(regexp(fileName,'(rzwd)+([\d])','match'),'rzwd',''));
|
||||||
|
|
||||||
l = str2double(strrep(regexp(fileName,'([L])+(_)+([\d]*)','match'),'L_',''));
|
l = str2double(strrep(regexp(fileName,'([L])+(_)+([\d]*)','match'),'L_',''));
|
||||||
|
|
||||||
d = str2double(strrep(regexp(fileName,'([D])+(_)+([\d]*)','match'),'D_',''));
|
d = str2double(strrep(regexp(fileName,'([D])+(_)+([\d]*)','match'),'D_',''));
|
||||||
|
|
||||||
if d == 0
|
if d == 0
|
||||||
sgm = false;
|
sgm = false;
|
||||||
else
|
else
|
||||||
sgm = true;
|
sgm = true;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
if numel(regexp(fileName,'(YYYY)','match')) > 1
|
if numel(regexp(fileName,'(YYYY)','match')) > 1
|
||||||
pol = "copolarized";
|
pol = "copolarized";
|
||||||
elseif numel(regexp(fileName,'(YXXY)','match')) > 1
|
elseif numel(regexp(fileName,'(YXXY)','match')) > 1
|
||||||
pol = "paired";
|
pol = "paired";
|
||||||
elseif numel(regexp(fileName,'(YXYX)','match')) > 1
|
elseif numel(regexp(fileName,'(YXYX)','match')) > 1
|
||||||
pol = "alternated";
|
pol = "alternated";
|
||||||
else
|
else
|
||||||
pol = "copolarized";
|
pol = "copolarized";
|
||||||
end
|
end
|
||||||
|
|
||||||
p_in = str2double(strrep(regexp(fileName,'(pow_)+([-,\d]{1})','match'),'pow_',''));
|
p_in = str2double(strrep(regexp(fileName,'(pow_)+([-,\d]{1})','match'),'pow_',''));
|
||||||
|
|
||||||
pmd = 0.1;
|
pmd = 0.1;
|
||||||
|
|
||||||
gamma = 0.0023;
|
gamma = 0.0023;
|
||||||
|
|
||||||
realiz = str2double(strrep(regexp(fileName,'(r)+([-,\d]{1,3})','match'),'r',''));
|
realiz = str2double(strrep(regexp(fileName,'(r)+([-,\d]{1,3})','match'),'r',''));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
% ____________________________________
|
% ____________________________________
|
||||||
% Get the information you want from current file
|
% Get the information you want from current file
|
||||||
rop=[];
|
rop=[];
|
||||||
ber = [];
|
ber = [];
|
||||||
for pow = 2:12
|
for pow = 2:12
|
||||||
|
|
||||||
module_number = '';
|
module_number = '';
|
||||||
for p = 1:11 %11 because there are 11 ROP branches in model
|
for p = 1:11 %11 because there are 11 ROP branches in model
|
||||||
|
|
||||||
% get ROP
|
% get ROP
|
||||||
if p == 1
|
if p == 1
|
||||||
p_out = matFile.dp_optatten_para.atten;
|
p_out = matFile.dp_optatten_para.atten;
|
||||||
else
|
else
|
||||||
p_out = matFile.("dp_optatten__"+(p)+"_para").atten;
|
p_out = matFile.("dp_optatten__"+(p)+"_para").atten;
|
||||||
end
|
end
|
||||||
|
|
||||||
p_out = round(p_out-10*log10(numel(matFile.config.parameters.common.wavelengthPlan)));
|
p_out = round(p_out-10*log10(numel(matFile.config.parameters.common.wavelengthPlan)));
|
||||||
|
|
||||||
for c = 1:numel(matFile.config.parameters.common.wavelengthPlan)
|
for c = 1:numel(matFile.config.parameters.common.wavelengthPlan)
|
||||||
|
|
||||||
ber(c) = matFile.("prms_compare_wdm__"+(p+1)+"_out"){1,c}.ber;
|
ber(c) = matFile.("prms_compare_wdm__"+(p+1)+"_out"){1,c}.ber;
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
totalBer = matFile.("prms_compare_wdm__"+(p+1)+"_out"){1,end}.totalBer;
|
totalBer = matFile.("prms_compare_wdm__"+(p+1)+"_out"){1,end}.totalBer;
|
||||||
|
|
||||||
if totalBer > 0.2 && channelspacing == 400e9 && pol == "alternated"
|
if totalBer > 0.2 && channelspacing == 400e9 && pol == "alternated"
|
||||||
disp("stopping here");
|
disp("stopping here");
|
||||||
pause;
|
pause;
|
||||||
end
|
end
|
||||||
|
|
||||||
% ____________________________________
|
% ____________________________________
|
||||||
% Add value to warehouse at the correct position
|
% Add value to warehouse at the correct position
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
wh.addValueToStorage(ber,'ber',l,d,sgm,pol,p_in,p_out,pmd,gamma,realiz,numchannels, center_wavelength,channelspacing,random_zdw);
|
wh.addValueToStorage(ber,'ber',l,d,sgm,pol,p_in,p_out,pmd,gamma,realiz,numchannels, center_wavelength,channelspacing,random_zdw);
|
||||||
wh.getStoValue('ber',l,d,sgm,pol,p_in,p_out,pmd,gamma,realiz,numchannels, center_wavelength,channelspacing,random_zdw);
|
wh.getStoValue('ber',l,d,sgm,pol,p_in,p_out,pmd,gamma,realiz,numchannels, center_wavelength,channelspacing,random_zdw);
|
||||||
wh.addValueToStorage(totalBer,'totalBer',l,d,sgm,pol,p_in,p_out,pmd,gamma,realiz,numchannels,center_wavelength,channelspacing,random_zdw);
|
wh.addValueToStorage(totalBer,'totalBer',l,d,sgm,pol,p_in,p_out,pmd,gamma,realiz,numchannels,center_wavelength,channelspacing,random_zdw);
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
waitbar(num/numel(allMat),f,'Loading your data');
|
waitbar(num/numel(allMat),f,'Loading your data');
|
||||||
end
|
end
|
||||||
|
|
||||||
close(f)
|
close(f)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
% 4) Hey! the warehouse is here and (hopefully) filled with data :-)
|
% 4) Hey! the warehouse is here and (hopefully) filled with data :-)
|
||||||
|
|
||||||
% Create a save dialog
|
% Create a save dialog
|
||||||
defaultDir = 'C:\Users\Silas\Documents\MATLAB\Raw_Cluster_Simulations\';
|
defaultDir = 'C:\Users\Silas\Documents\MATLAB\Raw_Cluster_Simulations\';
|
||||||
defaultExt = '*.mat';
|
defaultExt = '*.mat';
|
||||||
[filename, pathname] = uiputfile(fullfile(defaultDir, defaultExt),'', 'wh.mat');
|
[filename, pathname] = uiputfile(fullfile(defaultDir, defaultExt),'', 'wh.mat');
|
||||||
|
|
||||||
% Check if the user pressed Cancel
|
% Check if the user pressed Cancel
|
||||||
if isequal(filename, 0) || isequal(pathname, 0)
|
if isequal(filename, 0) || isequal(pathname, 0)
|
||||||
disp('Save operation canceled.');
|
disp('Save operation canceled.');
|
||||||
else
|
else
|
||||||
% Save the variable to the selected file
|
% Save the variable to the selected file
|
||||||
save(fullfile(pathname, filename), 'wh');
|
save(fullfile(pathname, filename), 'wh');
|
||||||
disp(['Variable "wh" saved to: ', fullfile(pathname, filename)]);
|
disp(['Variable "wh" saved to: ', fullfile(pathname, filename)]);
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function matFileStructArray = getAllFilesInFolder(folderPath,extension)
|
function matFileStructArray = getAllFilesInFolder(folderPath,extension)
|
||||||
% Get a list of all files in the current folder
|
% Get a list of all files in the current folder
|
||||||
currentFolderFiles = dir(fullfile(folderPath, '*'));
|
currentFolderFiles = dir(fullfile(folderPath, '*'));
|
||||||
|
|
||||||
% Exclude '.' and '..' directories
|
% Exclude '.' and '..' directories
|
||||||
currentFolderFiles = currentFolderFiles(~ismember({currentFolderFiles.name}, {'.', '..'}));
|
currentFolderFiles = currentFolderFiles(~ismember({currentFolderFiles.name}, {'.', '..'}));
|
||||||
|
|
||||||
% Initialize the structure array for .mat files
|
% Initialize the structure array for .mat files
|
||||||
matFileStructArray = struct('path', {}, 'name', {}, 'ext', {});
|
matFileStructArray = struct('path', {}, 'name', {}, 'ext', {});
|
||||||
|
|
||||||
% Loop over each file in the current folder
|
% Loop over each file in the current folder
|
||||||
for i = 1:length(currentFolderFiles)
|
for i = 1:length(currentFolderFiles)
|
||||||
currentFile = currentFolderFiles(i);
|
currentFile = currentFolderFiles(i);
|
||||||
|
|
||||||
% Check if the current item is a file and has a .mat extension
|
% Check if the current item is a file and has a .mat extension
|
||||||
if ~currentFile.isdir && endsWith(currentFile.name, extension, 'IgnoreCase', true)
|
if ~currentFile.isdir && endsWith(currentFile.name, extension, 'IgnoreCase', true)
|
||||||
% If it's a .mat file, add it to the structure array
|
% If it's a .mat file, add it to the structure array
|
||||||
[matFileStructArray(end + 1).path,matFileStructArray(end+1).name, matFileStructArray(end+1).ext] = fileparts(fullfile(folderPath, currentFile.name));
|
[matFileStructArray(end + 1).path,matFileStructArray(end+1).name, matFileStructArray(end+1).ext] = fileparts(fullfile(folderPath, currentFile.name));
|
||||||
elseif currentFile.isdir
|
elseif currentFile.isdir
|
||||||
% If it's a directory, recursively call the function
|
% If it's a directory, recursively call the function
|
||||||
subfolderPath = fullfile(folderPath, currentFile.name);
|
subfolderPath = fullfile(folderPath, currentFile.name);
|
||||||
subfolderMatFiles = getAllFilesInFolder(subfolderPath,extension);
|
subfolderMatFiles = getAllFilesInFolder(subfolderPath,extension);
|
||||||
|
|
||||||
% Add .mat files from the subfolder to the structure array
|
% Add .mat files from the subfolder to the structure array
|
||||||
matFileStructArray = [matFileStructArray, subfolderMatFiles];
|
matFileStructArray = [matFileStructArray, subfolderMatFiles];
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -1,415 +1,415 @@
|
|||||||
|
|
||||||
|
|
||||||
%automate plots
|
%automate plots
|
||||||
[file, path] = uigetfile("C:\Users\Silas\Documents\MATLAB\Datensätze\Raw_Cluster_Simulations\session_februar_24\wh_mi_nacht.mat");
|
[file, path] = uigetfile("C:\Users\Silas\Documents\MATLAB\Datensätze\Raw_Cluster_Simulations\session_februar_24\wh_mi_nacht.mat");
|
||||||
wh = load([path filesep file]);
|
wh = load([path filesep file]);
|
||||||
wh = wh.wh;
|
wh = wh.wh;
|
||||||
|
|
||||||
% fields = fieldnames(wh.parameter);
|
% fields = fieldnames(wh.parameter);
|
||||||
% for k = 1:numel(fields)
|
% for k = 1:numel(fields)
|
||||||
% oldParam = wh.parameter.(fields{k});
|
% oldParam = wh.parameter.(fields{k});
|
||||||
% % copy over the properties to your new class
|
% % copy over the properties to your new class
|
||||||
% wh.parameter.(fields{k}) = StorageParameter(...
|
% wh.parameter.(fields{k}) = StorageParameter(...
|
||||||
% oldParam.Name, oldParam.values);
|
% oldParam.Name, oldParam.values);
|
||||||
% end
|
% end
|
||||||
%
|
%
|
||||||
|
|
||||||
|
|
||||||
plotJob = struct();
|
plotJob = struct();
|
||||||
width = 350;
|
width = 350;
|
||||||
height = 200;
|
height = 200;
|
||||||
plotJob.Position = [100 100 width 100+height];
|
plotJob.Position = [100 100 width 100+height];
|
||||||
cols = cbrewer2("paired",12);
|
cols = cbrewer2("paired",12);
|
||||||
plotJob.color = cols(1,:);
|
plotJob.color = cols(1,:);
|
||||||
plotJob.l = 2;
|
plotJob.l = 2;
|
||||||
plotJob.ch = 16;
|
plotJob.ch = 16;
|
||||||
plotJob.d = 0;
|
plotJob.d = 0;
|
||||||
plotJob.sgm = 0;
|
plotJob.sgm = 0;
|
||||||
plotJob.pol = "copolarized";
|
plotJob.pol = "copolarized";
|
||||||
plotJob.p_in = 3;
|
plotJob.p_in = 3;
|
||||||
plotJob.gamma = 0.0023;
|
plotJob.gamma = 0.0023;
|
||||||
plotJob.pmd = 0.1;
|
plotJob.pmd = 0.1;
|
||||||
plotJob.channelspacing = 400e9;
|
plotJob.channelspacing = 400e9;
|
||||||
plotJob.randzdw = 0;
|
plotJob.randzdw = 0;
|
||||||
|
|
||||||
|
|
||||||
plotJob.plot_ber_curve = 0;
|
plotJob.plot_ber_curve = 0;
|
||||||
plotJob.plot_3dber_curve = 0;
|
plotJob.plot_3dber_curve = 0;
|
||||||
plotJob.plot_violin = 1;
|
plotJob.plot_violin = 1;
|
||||||
plotJob.plot_wavelength_sweep = 0;
|
plotJob.plot_wavelength_sweep = 0;
|
||||||
plotJob.plot_wavelength_sweep_failure_rate = 0;
|
plotJob.plot_wavelength_sweep_failure_rate = 0;
|
||||||
|
|
||||||
|
|
||||||
plotJob.dataStatArg = 'Lineplot with quartiles';
|
plotJob.dataStatArg = 'Lineplot with quartiles';
|
||||||
plotJob.plotTypeArg = 'Lines';
|
plotJob.plotTypeArg = 'Lines';
|
||||||
plotJob.displayname = 'a';
|
plotJob.displayname = 'a';
|
||||||
plotJob.title = 'title';
|
plotJob.title = 'title';
|
||||||
plotJob.figName = '16 Chann';
|
plotJob.figName = '16 Chann';
|
||||||
plotJob.xAxisLabel = 'ROP per Channel in dBm';
|
plotJob.xAxisLabel = 'ROP per Channel in dBm';
|
||||||
plotJob.yAxisLabel = 'BER';
|
plotJob.yAxisLabel = 'BER';
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
% createbercurves(wh,plotJob)
|
% createbercurves(wh,plotJob)
|
||||||
|
|
||||||
P = [3,6];
|
P = [3,6];
|
||||||
for i = 1:2
|
for i = 1:2
|
||||||
plotJob.p_in = P(i);
|
plotJob.p_in = P(i);
|
||||||
createviolinplots(wh,plotJob);
|
createviolinplots(wh,plotJob);
|
||||||
end
|
end
|
||||||
% createsweepplots(wh,plotJob);
|
% createsweepplots(wh,plotJob);
|
||||||
|
|
||||||
|
|
||||||
%% 1
|
%% 1
|
||||||
function createbercurves(wh,plotJob)
|
function createbercurves(wh,plotJob)
|
||||||
width = 1650;
|
width = 1650;
|
||||||
height = 400;
|
height = 400;
|
||||||
s = 100;
|
s = 100;
|
||||||
e = 100;
|
e = 100;
|
||||||
|
|
||||||
cols = cbrewer2("paired",12);
|
cols = cbrewer2("paired",12);
|
||||||
numRows = 2;
|
numRows = 2;
|
||||||
numCols = 4;
|
numCols = 4;
|
||||||
|
|
||||||
plotJob.figName = '16 Chann_200G';
|
plotJob.figName = '16 Chann_200G';
|
||||||
plotJob.channelspacing = 400e9;
|
plotJob.channelspacing = 400e9;
|
||||||
plotJob.ch = 16;
|
plotJob.ch = 16;
|
||||||
Len = [2,2,2,2,10,10,10,10];
|
Len = [2,2,2,2,10,10,10,10];
|
||||||
Pol = ["copolarized","alternated","paired","copolarized","copolarized","alternated","paired","copolarized"];
|
Pol = ["copolarized","alternated","paired","copolarized","copolarized","alternated","paired","copolarized"];
|
||||||
Title = ["Co Polarized","Alternating Pol. Interl.","Paired Pol. Interl.","Link Segmentation",];
|
Title = ["Co Polarized","Alternating Pol. Interl.","Paired Pol. Interl.","Link Segmentation",];
|
||||||
D = [0,0,0,3,0,0,0,3];
|
D = [0,0,0,3,0,0,0,3];
|
||||||
Sgm = [0,0,0,1,0,0,0,1];
|
Sgm = [0,0,0,1,0,0,0,1];
|
||||||
|
|
||||||
colidx = [4,8,6];
|
colidx = [4,8,6];
|
||||||
P_launch = [3,6];
|
P_launch = [3,6];
|
||||||
|
|
||||||
fig = figure('Name',plotJob.figName);
|
fig = figure('Name',plotJob.figName);
|
||||||
fig.Position = plotJob.Position;
|
fig.Position = plotJob.Position;
|
||||||
fig.Units = "centimeters";
|
fig.Units = "centimeters";
|
||||||
fig.Position = [0 0 18 7];
|
fig.Position = [0 0 18 7];
|
||||||
t = tiledlayout(numRows,numCols,'TileSpacing','compact','Padding','compact');
|
t = tiledlayout(numRows,numCols,'TileSpacing','compact','Padding','compact');
|
||||||
for idx = 1:(numRows * numCols)
|
for idx = 1:(numRows * numCols)
|
||||||
% Create subplot
|
% Create subplot
|
||||||
% sp = subplot(numRows, numCols, idx);
|
% sp = subplot(numRows, numCols, idx);
|
||||||
nexttile;
|
nexttile;
|
||||||
plotJob.l = Len(idx);
|
plotJob.l = Len(idx);
|
||||||
plotJob.pol = Pol(idx);
|
plotJob.pol = Pol(idx);
|
||||||
plotJob.d = D(idx);
|
plotJob.d = D(idx);
|
||||||
plotJob.sgm = Sgm(idx);
|
plotJob.sgm = Sgm(idx);
|
||||||
plotJob.randzdw = 1;
|
plotJob.randzdw = 1;
|
||||||
|
|
||||||
for i = 1:length(P_launch)
|
for i = 1:length(P_launch)
|
||||||
|
|
||||||
plotJob.p_in = P_launch(i);
|
plotJob.p_in = P_launch(i);
|
||||||
plotJob.color = cols(colidx(i),:);
|
plotJob.color = cols(colidx(i),:);
|
||||||
hold on
|
hold on
|
||||||
plotCurve(wh, plotJob);
|
plotCurve(wh, plotJob);
|
||||||
|
|
||||||
end
|
end
|
||||||
%
|
%
|
||||||
if idx ~= 1 && idx ~= 5 % For example, hide y-axis for subplot 1
|
if idx ~= 1 && idx ~= 5 % For example, hide y-axis for subplot 1
|
||||||
set(gca, 'YTickLabel',[]); % Hide y-axis ticks and labels
|
set(gca, 'YTickLabel',[]); % Hide y-axis ticks and labels
|
||||||
set(gca,'YGrid','on');
|
set(gca,'YGrid','on');
|
||||||
set(gca, 'YLabel', []);
|
set(gca, 'YLabel', []);
|
||||||
end
|
end
|
||||||
if idx ~= 5 && idx ~= 6 && idx ~= 7 && idx ~= 8
|
if idx ~= 5 && idx ~= 6 && idx ~= 7 && idx ~= 8
|
||||||
set(gca, 'XLabel', []);
|
set(gca, 'XLabel', []);
|
||||||
set(gca, 'XTickLabel', []);
|
set(gca, 'XTickLabel', []);
|
||||||
|
|
||||||
end
|
end
|
||||||
grid on
|
grid on
|
||||||
|
|
||||||
g = gca;
|
g = gca;
|
||||||
pos = g.Position;
|
pos = g.Position;
|
||||||
if idx <= 4
|
if idx <= 4
|
||||||
title(Title(idx),'FontSize',8);
|
title(Title(idx),'FontSize',8);
|
||||||
% a = annotation('textbox', pos-[0.0020 -0.1434 0.0947 0.3121], 'String', "FEC: 3.8e-3","LineStyle","none","FontSize",8,'LineWidth',0.1,'Interpreter','latex',"FontUnits","points",'Vert','middle','FitBoxToText','on');
|
% a = annotation('textbox', pos-[0.0020 -0.1434 0.0947 0.3121], 'String', "FEC: 3.8e-3","LineStyle","none","FontSize",8,'LineWidth',0.1,'Interpreter','latex',"FontUnits","points",'Vert','middle','FitBoxToText','on');
|
||||||
% a = annotation('textbox', pos, 'String', "2 km","LineStyle","none","FontSize",8,'LineWidth',0.1,'Interpreter','latex',"FontUnits","points",'Vert','bottom','FitBoxToText','on');
|
% a = annotation('textbox', pos, 'String', "2 km","LineStyle","none","FontSize",8,'LineWidth',0.1,'Interpreter','latex',"FontUnits","points",'Vert','bottom','FitBoxToText','on');
|
||||||
else
|
else
|
||||||
% a = annotation('textbox', pos, 'String', "FEC: 3.8e-3","LineStyle","none","FontSize",8,'LineWidth',0.1,'Interpreter','latex',"FontUnits","points",'Vert','middle','FitBoxToText','on');
|
% a = annotation('textbox', pos, 'String', "FEC: 3.8e-3","LineStyle","none","FontSize",8,'LineWidth',0.1,'Interpreter','latex',"FontUnits","points",'Vert','middle','FitBoxToText','on');
|
||||||
% a = annotation('textbox', pos, 'String', "10 km","LineStyle","none","FontSize",8,'LineWidth',0.1,'Interpreter','latex',"FontUnits","points",'Vert','bottom','FitBoxToText','on');
|
% a = annotation('textbox', pos, 'String', "10 km","LineStyle","none","FontSize",8,'LineWidth',0.1,'Interpreter','latex',"FontUnits","points",'Vert','bottom','FitBoxToText','on');
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
% Create textbox
|
% Create textbox
|
||||||
annotation(fig,'textbox',...
|
annotation(fig,'textbox',...
|
||||||
[0.0696078431372547 0.246851385390432 0.0656862745098043 0.0453400503778337],...
|
[0.0696078431372547 0.246851385390432 0.0656862745098043 0.0453400503778337],...
|
||||||
'String','10 km',...
|
'String','10 km',...
|
||||||
'LineStyle','none',...
|
'LineStyle','none',...
|
||||||
'Interpreter','latex',...
|
'Interpreter','latex',...
|
||||||
'FontSize',8,...
|
'FontSize',8,...
|
||||||
'FitBoxToText','off');
|
'FitBoxToText','off');
|
||||||
|
|
||||||
% Create textbox
|
% Create textbox
|
||||||
annotation(fig,'textbox',...
|
annotation(fig,'textbox',...
|
||||||
[0.288235294117647 0.239294710327459 0.0656862745098043 0.0453400503778338],...
|
[0.288235294117647 0.239294710327459 0.0656862745098043 0.0453400503778338],...
|
||||||
'String','10 km',...
|
'String','10 km',...
|
||||||
'LineStyle','none',...
|
'LineStyle','none',...
|
||||||
'Interpreter','latex',...
|
'Interpreter','latex',...
|
||||||
'FontSize',8,...
|
'FontSize',8,...
|
||||||
'FitBoxToText','off');
|
'FitBoxToText','off');
|
||||||
|
|
||||||
% Create textbox
|
% Create textbox
|
||||||
annotation(fig,'textbox',...
|
annotation(fig,'textbox',...
|
||||||
[0.516666666666666 0.241813602015117 0.0656862745098042 0.0453400503778338],...
|
[0.516666666666666 0.241813602015117 0.0656862745098042 0.0453400503778338],...
|
||||||
'String','10 km',...
|
'String','10 km',...
|
||||||
'LineStyle','none',...
|
'LineStyle','none',...
|
||||||
'Interpreter','latex',...
|
'Interpreter','latex',...
|
||||||
'FontSize',8,...
|
'FontSize',8,...
|
||||||
'FitBoxToText','off');
|
'FitBoxToText','off');
|
||||||
|
|
||||||
% Create textbox
|
% Create textbox
|
||||||
annotation(fig,'textbox',...
|
annotation(fig,'textbox',...
|
||||||
[0.742156862745097 0.236775818639802 0.0656862745098042 0.0453400503778339],...
|
[0.742156862745097 0.236775818639802 0.0656862745098042 0.0453400503778339],...
|
||||||
'String','10 km',...
|
'String','10 km',...
|
||||||
'LineStyle','none',...
|
'LineStyle','none',...
|
||||||
'Interpreter','latex',...
|
'Interpreter','latex',...
|
||||||
'FontSize',8,...
|
'FontSize',8,...
|
||||||
'FitBoxToText','off');
|
'FitBoxToText','off');
|
||||||
|
|
||||||
% Create textbox
|
% Create textbox
|
||||||
annotation(fig,'textbox',...
|
annotation(fig,'textbox',...
|
||||||
[0.071996471804854 0.578899159967702 0.0656862745098039 0.0453400503778341],...
|
[0.071996471804854 0.578899159967702 0.0656862745098039 0.0453400503778341],...
|
||||||
'String',{'2 km'},...
|
'String',{'2 km'},...
|
||||||
'LineStyle','none',...
|
'LineStyle','none',...
|
||||||
'Interpreter','latex',...
|
'Interpreter','latex',...
|
||||||
'FontSize',8,...
|
'FontSize',8,...
|
||||||
'FitBoxToText','off');
|
'FitBoxToText','off');
|
||||||
|
|
||||||
% Create textbox
|
% Create textbox
|
||||||
annotation(fig,'textbox',...
|
annotation(fig,'textbox',...
|
||||||
[0.29596893566113 0.576253721089996 0.0656862745098041 0.0453400503778341],...
|
[0.29596893566113 0.576253721089996 0.0656862745098041 0.0453400503778341],...
|
||||||
'String',{'2 km'},...
|
'String',{'2 km'},...
|
||||||
'LineStyle','none',...
|
'LineStyle','none',...
|
||||||
'Interpreter','latex',...
|
'Interpreter','latex',...
|
||||||
'FontSize',8,...
|
'FontSize',8,...
|
||||||
'FitBoxToText','off');
|
'FitBoxToText','off');
|
||||||
|
|
||||||
% Create textbox
|
% Create textbox
|
||||||
annotation(fig,'textbox',...
|
annotation(fig,'textbox',...
|
||||||
[0.524883914268912 0.580785315705112 0.0656862745098041 0.0453400503778341],...
|
[0.524883914268912 0.580785315705112 0.0656862745098041 0.0453400503778341],...
|
||||||
'String',{'2 km'},...
|
'String',{'2 km'},...
|
||||||
'LineStyle','none',...
|
'LineStyle','none',...
|
||||||
'Interpreter','latex',...
|
'Interpreter','latex',...
|
||||||
'FontSize',8,...
|
'FontSize',8,...
|
||||||
'FitBoxToText','off');
|
'FitBoxToText','off');
|
||||||
|
|
||||||
% Create textbox
|
% Create textbox
|
||||||
annotation(fig,'textbox',...
|
annotation(fig,'textbox',...
|
||||||
[0.753758338909501 0.581291504465311 0.0656862745098037 0.0453400503778341],...
|
[0.753758338909501 0.581291504465311 0.0656862745098037 0.0453400503778341],...
|
||||||
'String',{'2 km'},...
|
'String',{'2 km'},...
|
||||||
'LineStyle','none',...
|
'LineStyle','none',...
|
||||||
'Interpreter','latex',...
|
'Interpreter','latex',...
|
||||||
'FontSize',8,...
|
'FontSize',8,...
|
||||||
'FitBoxToText','off');
|
'FitBoxToText','off');
|
||||||
|
|
||||||
a=sgtitle(['N=',num2str(plotJob.ch),'; $\Delta f_{\mathrm{ch}}$= ',num2str(plotJob.channelspacing*1e-9),' GHz'],'FontSIze',10);
|
a=sgtitle(['N=',num2str(plotJob.ch),'; $\Delta f_{\mathrm{ch}}$= ',num2str(plotJob.channelspacing*1e-9),' GHz'],'FontSIze',10);
|
||||||
a.Interpreter = "latex";
|
a.Interpreter = "latex";
|
||||||
|
|
||||||
lgd = legend('$P_{\mathrm{in}}=0$ dBm','$P_{\mathrm{in}}=3$ dBm','$P_{\mathrm{in}}=6$ dBm','Interpreter','latex');
|
lgd = legend('$P_{\mathrm{in}}=0$ dBm','$P_{\mathrm{in}}=3$ dBm','$P_{\mathrm{in}}=6$ dBm','Interpreter','latex');
|
||||||
lgd.NumColumns = 3;
|
lgd.NumColumns = 3;
|
||||||
lgd.Layout.Tile = 'south';
|
lgd.Layout.Tile = 'south';
|
||||||
|
|
||||||
copygraphics(t,'BackgroundColor','none');
|
copygraphics(t,'BackgroundColor','none');
|
||||||
end
|
end
|
||||||
|
|
||||||
%% 2
|
%% 2
|
||||||
function createviolinplots(wh,plotJob)
|
function createviolinplots(wh,plotJob)
|
||||||
|
|
||||||
width = 350;
|
width = 350;
|
||||||
height = 200;
|
height = 200;
|
||||||
s = 100;
|
s = 100;
|
||||||
e = 100;
|
e = 100;
|
||||||
|
|
||||||
cols = cbrewer2("paired",12);
|
cols = cbrewer2("paired",12);
|
||||||
numRows = 1;
|
numRows = 1;
|
||||||
numCols = 4;
|
numCols = 4;
|
||||||
|
|
||||||
plotJob.ch = 16;
|
plotJob.ch = 16;
|
||||||
plotJob.randzdw = 1;
|
plotJob.randzdw = 1;
|
||||||
|
|
||||||
Pol = ["copolarized","copolarized","alternated","paired",];
|
Pol = ["copolarized","copolarized","alternated","paired",];
|
||||||
Title = ["Co Pol.","Link Segmentation","Paired Pol. Interl.","Alternating Pol. Interl."];
|
Title = ["Co Pol.","Link Segmentation","Paired Pol. Interl.","Alternating Pol. Interl."];
|
||||||
D = [0,3,0,0];
|
D = [0,3,0,0];
|
||||||
Sgm = [0,1,0,0];
|
Sgm = [0,1,0,0];
|
||||||
|
|
||||||
colidx = [3];
|
colidx = [3];
|
||||||
Len = [10];
|
Len = [10];
|
||||||
|
|
||||||
fig = findall(groot, 'Type', 'figure', 'Name', plotJob.figName);
|
fig = findall(groot, 'Type', 'figure', 'Name', plotJob.figName);
|
||||||
if isvalid(fig)
|
if isvalid(fig)
|
||||||
figure(fig)
|
figure(fig)
|
||||||
% fig = get(fig);
|
% fig = get(fig);
|
||||||
AxesMain = fig.CurrentAxes;
|
AxesMain = fig.CurrentAxes;
|
||||||
hold on
|
hold on
|
||||||
% t = tiledlayout(1,4,'TileSpacing','compact','Padding','compact');
|
% t = tiledlayout(1,4,'TileSpacing','compact','Padding','compact');
|
||||||
else
|
else
|
||||||
fig = figure('name',char(plotJob.figName));
|
fig = figure('name',char(plotJob.figName));
|
||||||
AxesMain = gca;
|
AxesMain = gca;
|
||||||
hold on; grid on;
|
hold on; grid on;
|
||||||
% t = tiledlayout(1,4,'TileSpacing','compact','Padding','compact');
|
% t = tiledlayout(1,4,'TileSpacing','compact','Padding','compact');
|
||||||
end
|
end
|
||||||
|
|
||||||
for idx = 1:(numRows * numCols)
|
for idx = 1:(numRows * numCols)
|
||||||
% Create subplot
|
% Create subplot
|
||||||
subplot(numRows, numCols, idx);
|
subplot(numRows, numCols, idx);
|
||||||
|
|
||||||
plotJob.pol = Pol(idx);
|
plotJob.pol = Pol(idx);
|
||||||
plotJob.d = D(idx);
|
plotJob.d = D(idx);
|
||||||
plotJob.sgm = Sgm(idx);
|
plotJob.sgm = Sgm(idx);
|
||||||
|
|
||||||
for i = 1
|
for i = 1
|
||||||
|
|
||||||
plotJob.color = cols(colidx(i),:);
|
plotJob.color = cols(colidx(i),:);
|
||||||
plotJob.l = Len(i);
|
plotJob.l = Len(i);
|
||||||
hold on
|
hold on
|
||||||
plotViolin(wh, plotJob);
|
plotViolin(wh, plotJob);
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if idx ~= 1 % For example, hide y-axis for subplot 1
|
if idx ~= 1 % For example, hide y-axis for subplot 1
|
||||||
%set(gca, 'YTickLabel',[]); % Hide y-axis ticks and labels
|
%set(gca, 'YTickLabel',[]); % Hide y-axis ticks and labels
|
||||||
set(gca, 'YGrid','on');
|
set(gca, 'YGrid','on');
|
||||||
set(gca, 'YLabel', []);
|
set(gca, 'YLabel', []);
|
||||||
end
|
end
|
||||||
|
|
||||||
if idx <= 4
|
if idx <= 4
|
||||||
title(Title(idx));
|
title(Title(idx));
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
% Create textbox
|
% Create textbox
|
||||||
annotation(fig,'textbox',...
|
annotation(fig,'textbox',...
|
||||||
[0.300019607843137 0.816120906801009 0.108803921568628 0.0906801007556676],...
|
[0.300019607843137 0.816120906801009 0.108803921568628 0.0906801007556676],...
|
||||||
'String','$P_{\mathrm{in}}=3$ dBm',...
|
'String','$P_{\mathrm{in}}=3$ dBm',...
|
||||||
'LineStyle','none',...
|
'LineStyle','none',...
|
||||||
'Interpreter','latex',...
|
'Interpreter','latex',...
|
||||||
'FontSize',8,...
|
'FontSize',8,...
|
||||||
'FitBoxToText','off');
|
'FitBoxToText','off');
|
||||||
|
|
||||||
% Create textbox
|
% Create textbox
|
||||||
annotation(fig,'textbox',...
|
annotation(fig,'textbox',...
|
||||||
[0.530411764705882 0.81612090680101 0.108803921568628 0.0906801007556676],...
|
[0.530411764705882 0.81612090680101 0.108803921568628 0.0906801007556676],...
|
||||||
'String','$P_{\mathrm{in}}=3$ dBm',...
|
'String','$P_{\mathrm{in}}=3$ dBm',...
|
||||||
'LineStyle','none',...
|
'LineStyle','none',...
|
||||||
'Interpreter','latex',...
|
'Interpreter','latex',...
|
||||||
'FontSize',8,...
|
'FontSize',8,...
|
||||||
'FitBoxToText','off');
|
'FitBoxToText','off');
|
||||||
|
|
||||||
% Create textbox
|
% Create textbox
|
||||||
annotation(fig,'textbox',...
|
annotation(fig,'textbox',...
|
||||||
[0.755901960784313 0.816120906801011 0.108803921568628 0.0906801007556676],...
|
[0.755901960784313 0.816120906801011 0.108803921568628 0.0906801007556676],...
|
||||||
'String','$P_{\mathrm{in}}=3$ dBm',...
|
'String','$P_{\mathrm{in}}=3$ dBm',...
|
||||||
'LineStyle','none',...
|
'LineStyle','none',...
|
||||||
'Interpreter','latex',...
|
'Interpreter','latex',...
|
||||||
'FontSize',8,...
|
'FontSize',8,...
|
||||||
'FitBoxToText','off');
|
'FitBoxToText','off');
|
||||||
|
|
||||||
% Create textbox
|
% Create textbox
|
||||||
annotation(fig,'textbox',...
|
annotation(fig,'textbox',...
|
||||||
[0.0696274509803918 0.584382871536529 0.108803921568628 0.0906801007556676],...
|
[0.0696274509803918 0.584382871536529 0.108803921568628 0.0906801007556676],...
|
||||||
'String','$P_{\mathrm{in}}=3$ dBm',...
|
'String','$P_{\mathrm{in}}=3$ dBm',...
|
||||||
'LineStyle','none',...
|
'LineStyle','none',...
|
||||||
'Interpreter','latex',...
|
'Interpreter','latex',...
|
||||||
'FontSize',8,...
|
'FontSize',8,...
|
||||||
'FitBoxToText','off');
|
'FitBoxToText','off');
|
||||||
|
|
||||||
% lgd = legend('$P_{\mathrm{in}}=0$ dBm','$P_{\mathrm{in}}=3$ dBm','$P_{\mathrm{in}}=6$ dBm','Interpreter','latex');
|
% lgd = legend('$P_{\mathrm{in}}=0$ dBm','$P_{\mathrm{in}}=3$ dBm','$P_{\mathrm{in}}=6$ dBm','Interpreter','latex');
|
||||||
% lgd.NumColumns = 3;
|
% lgd.NumColumns = 3;
|
||||||
% lgd.Layout.Tile = 'south';
|
% lgd.Layout.Tile = 'south';
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
%% 3
|
%% 3
|
||||||
function createsweepplots(wh,plotJob)
|
function createsweepplots(wh,plotJob)
|
||||||
|
|
||||||
width = 650;
|
width = 650;
|
||||||
height = 200;
|
height = 200;
|
||||||
s = 100;
|
s = 100;
|
||||||
e = 100;
|
e = 100;
|
||||||
plotJob.Position = [0 0 width e+height];
|
plotJob.Position = [0 0 width e+height];
|
||||||
|
|
||||||
cols = cbrewer2("paired",12);
|
cols = cbrewer2("paired",12);
|
||||||
numRows = 1;
|
numRows = 1;
|
||||||
numCols = 4;
|
numCols = 4;
|
||||||
|
|
||||||
|
|
||||||
plotJob.channelspacing = 200e9;
|
plotJob.channelspacing = 200e9;
|
||||||
plotJob.ch = 16;
|
plotJob.ch = 16;
|
||||||
plotJob.randzdw = 1;
|
plotJob.randzdw = 1;
|
||||||
plotJob.l = 10;
|
plotJob.l = 10;
|
||||||
|
|
||||||
plotJob.p_in = 3;
|
plotJob.p_in = 3;
|
||||||
|
|
||||||
Pol = ["copolarized","alternated","paired","copolarized"];
|
Pol = ["copolarized","alternated","paired","copolarized"];
|
||||||
Title = ["Co Polarized","Alternating Pol. Interl.","Paired Pol. Interl.","Link Segmentation",];
|
Title = ["Co Polarized","Alternating Pol. Interl.","Paired Pol. Interl.","Link Segmentation",];
|
||||||
D = [0,0,0,3];
|
D = [0,0,0,3];
|
||||||
Sgm = [0,0,0,1];
|
Sgm = [0,0,0,1];
|
||||||
Channelspacing = [200e9, 200e9];
|
Channelspacing = [200e9, 200e9];
|
||||||
PlotTypeArg = ["--","-"];
|
PlotTypeArg = ["--","-"];
|
||||||
colidx = [6,8,2,4];
|
colidx = [6,8,2,4];
|
||||||
Len = [2,10];
|
Len = [2,10];
|
||||||
|
|
||||||
plotJob.figName = [num2str(plotJob.ch),num2str(plotJob.channelspacing*1e-9),num2str(plotJob.p_in),'...'];
|
plotJob.figName = [num2str(plotJob.ch),num2str(plotJob.channelspacing*1e-9),num2str(plotJob.p_in),'...'];
|
||||||
plotJob.figName = "10km 400ghz";
|
plotJob.figName = "10km 400ghz";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fig = findall(groot, 'Type', 'figure', 'Name', plotJob.figName);
|
fig = findall(groot, 'Type', 'figure', 'Name', plotJob.figName);
|
||||||
|
|
||||||
if isvalid(fig)
|
if isvalid(fig)
|
||||||
figure(fig)
|
figure(fig)
|
||||||
fig = get(fig);
|
fig = get(fig);
|
||||||
AxesMain = fig.CurrentAxes;
|
AxesMain = fig.CurrentAxes;
|
||||||
hold on
|
hold on
|
||||||
else
|
else
|
||||||
fig = figure('name',char(plotJob.figName));
|
fig = figure('name',char(plotJob.figName));
|
||||||
AxesMain = gca;
|
AxesMain = gca;
|
||||||
hold on
|
hold on
|
||||||
end
|
end
|
||||||
|
|
||||||
fig.Position = plotJob.Position;
|
fig.Position = plotJob.Position;
|
||||||
fig.Units = "centimeters";
|
fig.Units = "centimeters";
|
||||||
fig.Position = [0 0 18 7];
|
fig.Position = [0 0 18 7];
|
||||||
|
|
||||||
for j = 1
|
for j = 1
|
||||||
|
|
||||||
plotJob.channelspacing = Channelspacing(j);
|
plotJob.channelspacing = Channelspacing(j);
|
||||||
plotJob.plotTypeArg = PlotTypeArg(j);
|
plotJob.plotTypeArg = PlotTypeArg(j);
|
||||||
|
|
||||||
for idx = 1:4
|
for idx = 1:4
|
||||||
|
|
||||||
plotJob.color = cols(colidx(idx),:);
|
plotJob.color = cols(colidx(idx),:);
|
||||||
plotJob.pol = Pol(idx);
|
plotJob.pol = Pol(idx);
|
||||||
plotJob.d = D(idx);
|
plotJob.d = D(idx);
|
||||||
plotJob.sgm = Sgm(idx);
|
plotJob.sgm = Sgm(idx);
|
||||||
plotJob.displayname = [char(plotJob.pol)];
|
plotJob.displayname = [char(plotJob.pol)];
|
||||||
hold on
|
hold on
|
||||||
plotBerVsZdwFailureRate(wh, plotJob);
|
plotBerVsZdwFailureRate(wh, plotJob);
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
legend('Location', 'southoutside', 'Orientation', 'horizontal');
|
legend('Location', 'southoutside', 'Orientation', 'horizontal');
|
||||||
|
|
||||||
|
|
||||||
%plot channel positions
|
%plot channel positions
|
||||||
hold on
|
hold on
|
||||||
chpos = calcWavelengthPlan(plotJob.ch, plotJob.channelspacing, 1310);
|
chpos = calcWavelengthPlan(plotJob.ch, plotJob.channelspacing, 1310);
|
||||||
xline(chpos,'LineWidth',2,'Alpha',0.4,'HandleVisibility','off');
|
xline(chpos,'LineWidth',2,'Alpha',0.4,'HandleVisibility','off');
|
||||||
|
|
||||||
chpos = calcWavelengthPlan(plotJob.ch, plotJob.channelspacing, chpos(4));
|
chpos = calcWavelengthPlan(plotJob.ch, plotJob.channelspacing, chpos(4));
|
||||||
xline(chpos,'LineWidth',2,'LineStyle','--','Alpha',0.1,'HandleVisibility','off');
|
xline(chpos,'LineWidth',2,'LineStyle','--','Alpha',0.1,'HandleVisibility','off');
|
||||||
|
|
||||||
title(['N=',num2str(plotJob.ch),' $\Delta f_{\mathrm{ch}}$= ',num2str(plotJob.channelspacing*1e-9),' GHz'],'FontSize',10,'Interpreter','latex');
|
title(['N=',num2str(plotJob.ch),' $\Delta f_{\mathrm{ch}}$= ',num2str(plotJob.channelspacing*1e-9),' GHz'],'FontSize',10,'Interpreter','latex');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,83 +1,83 @@
|
|||||||
%automate plots
|
%automate plots
|
||||||
[file, path] = uigetfile("C:\Users\Silas\Documents\MATLAB\Datensätze\Raw_Cluster_Simulations\");
|
[file, path] = uigetfile("C:\Users\Silas\Documents\MATLAB\Datensätze\Raw_Cluster_Simulations\");
|
||||||
wh = load([path filesep file]);
|
wh = load([path filesep file]);
|
||||||
wh = wh.wh;
|
wh = wh.wh;
|
||||||
|
|
||||||
plotJob = struct();
|
plotJob = struct();
|
||||||
width = 350;
|
width = 350;
|
||||||
height = 200;
|
height = 200;
|
||||||
plotJob.Position = [100 100 width 100+height];
|
plotJob.Position = [100 100 width 100+height];
|
||||||
cols = cbrewer2("paired",12);
|
cols = cbrewer2("paired",12);
|
||||||
plotJob.color = cols(1,:);
|
plotJob.color = cols(1,:);
|
||||||
plotJob.l = 1;
|
plotJob.l = 1;
|
||||||
plotJob.ch = 1;
|
plotJob.ch = 1;
|
||||||
|
|
||||||
plotJob.sgm = 1;
|
plotJob.sgm = 1;
|
||||||
plotJob.pol = "copolarized";
|
plotJob.pol = "copolarized";
|
||||||
plotJob.p_in = 3;
|
plotJob.p_in = 3;
|
||||||
plotJob.gamma = 0.0023;
|
plotJob.gamma = 0.0023;
|
||||||
plotJob.pmd = 0.1;
|
plotJob.pmd = 0.1;
|
||||||
plotJob.channelspacing = 400e9;
|
plotJob.channelspacing = 400e9;
|
||||||
plotJob.randzdw = 0;
|
plotJob.randzdw = 0;
|
||||||
|
|
||||||
|
|
||||||
plotJob.plot_ber_curve = 1;
|
plotJob.plot_ber_curve = 1;
|
||||||
plotJob.plot_3dber_curve = 0;
|
plotJob.plot_3dber_curve = 0;
|
||||||
plotJob.plot_violin = 0;
|
plotJob.plot_violin = 0;
|
||||||
plotJob.plot_wavelength_sweep = 0;
|
plotJob.plot_wavelength_sweep = 0;
|
||||||
plotJob.plot_wavelength_sweep_failure_rate = 0;
|
plotJob.plot_wavelength_sweep_failure_rate = 0;
|
||||||
|
|
||||||
|
|
||||||
plotJob.dataStatArg = 'Lineplot with quartiles';
|
plotJob.dataStatArg = 'Lineplot with quartiles';
|
||||||
plotJob.plotTypeArg = 'Lines';
|
plotJob.plotTypeArg = 'Lines';
|
||||||
plotJob.displayname = 'a';
|
plotJob.displayname = 'a';
|
||||||
plotJob.title = 'title';
|
plotJob.title = 'title';
|
||||||
plotJob.figName = '1 Chann__';
|
plotJob.figName = '1 Chann__';
|
||||||
plotJob.xAxisLabel = 'ROP per Channel in dBm';
|
plotJob.xAxisLabel = 'ROP per Channel in dBm';
|
||||||
plotJob.yAxisLabel = 'BER';
|
plotJob.yAxisLabel = 'BER';
|
||||||
|
|
||||||
|
|
||||||
plotJob.d = 0;
|
plotJob.d = 0;
|
||||||
|
|
||||||
xAxis = wh.parameter.p_out.values;
|
xAxis = wh.parameter.p_out.values;
|
||||||
D = wh.parameter.dispersion.values;
|
D = wh.parameter.dispersion.values;
|
||||||
|
|
||||||
figure()
|
figure()
|
||||||
ber_ = [];
|
ber_ = [];
|
||||||
for d_ = 0:39
|
for d_ = 0:39
|
||||||
if d_ == 0
|
if d_ == 0
|
||||||
plotJob.sgm = 0;
|
plotJob.sgm = 0;
|
||||||
ber_(d_+1,:) = wh.getStoValue('ber',plotJob.l,d_,plotJob.sgm,string(plotJob.pol),plotJob.p_in,xAxis,plotJob.pmd,plotJob.gamma,1,plotJob.ch,1310,plotJob.channelspacing,plotJob.randzdw)';
|
ber_(d_+1,:) = wh.getStoValue('ber',plotJob.l,d_,plotJob.sgm,string(plotJob.pol),plotJob.p_in,xAxis,plotJob.pmd,plotJob.gamma,1,plotJob.ch,1310,plotJob.channelspacing,plotJob.randzdw)';
|
||||||
else
|
else
|
||||||
plotJob.sgm = 1;
|
plotJob.sgm = 1;
|
||||||
ber_(d_+1,:) = wh.getStoValue('ber',plotJob.l,d_,plotJob.sgm,string(plotJob.pol),plotJob.p_in,xAxis,plotJob.pmd,plotJob.gamma,1,plotJob.ch,1310,plotJob.channelspacing,plotJob.randzdw)';
|
ber_(d_+1,:) = wh.getStoValue('ber',plotJob.l,d_,plotJob.sgm,string(plotJob.pol),plotJob.p_in,xAxis,plotJob.pmd,plotJob.gamma,1,plotJob.ch,1310,plotJob.channelspacing,plotJob.randzdw)';
|
||||||
end
|
end
|
||||||
hold on
|
hold on
|
||||||
plot(xAxis,ber_(d_+1,:))
|
plot(xAxis,ber_(d_+1,:))
|
||||||
set(gca,'yscale','log');
|
set(gca,'yscale','log');
|
||||||
end
|
end
|
||||||
yline(3.8e-3);
|
yline(3.8e-3);
|
||||||
|
|
||||||
|
|
||||||
hdfec = 3.8e-3.*ones(size(xAxis));
|
hdfec = 3.8e-3.*ones(size(xAxis));
|
||||||
for i = 1:size(ber_,1)
|
for i = 1:size(ber_,1)
|
||||||
ber_series = ber_(i,:);
|
ber_series = ber_(i,:);
|
||||||
a = InterX([hdfec(:)';xAxis],[ber_series;xAxis]);
|
a = InterX([hdfec(:)';xAxis],[ber_series;xAxis]);
|
||||||
cross(i) = a(2);
|
cross(i) = a(2);
|
||||||
end
|
end
|
||||||
|
|
||||||
col = cbrewer2('Paired',8);
|
col = cbrewer2('Paired',8);
|
||||||
figure()
|
figure()
|
||||||
plot(D,cross,'Marker','o','MarkerSize',5,'MarkerEdgeColor',[1,1,1],'MarkerFaceColor',col(2,:),'Color',col(1,:),'LineWidth',1);
|
plot(D,cross,'Marker','o','MarkerSize',5,'MarkerEdgeColor',[1,1,1],'MarkerFaceColor',col(2,:),'Color',col(1,:),'LineWidth',1);
|
||||||
grid minor
|
grid minor
|
||||||
xlabel('Accumulated Dispersion')
|
xlabel('Accumulated Dispersion')
|
||||||
ylabel('Required ROP to reach FEC limit in dB')
|
ylabel('Required ROP to reach FEC limit in dB')
|
||||||
line([D(16),D(16)],[-10,cross(16)],'linestyle','--')
|
line([D(16),D(16)],[-10,cross(16)],'linestyle','--')
|
||||||
line([0,D(16)],[cross(16),cross(16)],'linestyle','--')
|
line([0,D(16)],[cross(16),cross(16)],'linestyle','--')
|
||||||
|
|
||||||
line([D(29),D(29)],[-10,cross(29)],'linestyle','--')
|
line([D(29),D(29)],[-10,cross(29)],'linestyle','--')
|
||||||
line([0,D(29)],[cross(29),cross(29)],'linestyle','--')
|
line([0,D(29)],[cross(29),cross(29)],'linestyle','--')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,52 +1,52 @@
|
|||||||
|
|
||||||
wh = load("C:\Users\Silas\Documents\MATLAB\Datensätze\Raw_Cluster_Simulations\session_dispersion_validation\wh_with_variation.mat");
|
wh = load("C:\Users\Silas\Documents\MATLAB\Datensätze\Raw_Cluster_Simulations\session_dispersion_validation\wh_with_variation.mat");
|
||||||
wh = wh.wh;
|
wh = wh.wh;
|
||||||
|
|
||||||
lambda = 1295;
|
lambda = 1295;
|
||||||
|
|
||||||
figure(3)
|
figure(3)
|
||||||
plot(xAxis,getber(wh,lambda),'DisplayName',['w:', num2str(lambda), 'variation']);
|
plot(xAxis,getber(wh,lambda),'DisplayName',['w:', num2str(lambda), 'variation']);
|
||||||
yline(3.8e-3,'HandleVisibility','off');
|
yline(3.8e-3,'HandleVisibility','off');
|
||||||
legend
|
legend
|
||||||
set(gca,'yscale','log');
|
set(gca,'yscale','log');
|
||||||
grid(gca,'on');
|
grid(gca,'on');
|
||||||
grid(gca,'minor');
|
grid(gca,'minor');
|
||||||
grid minor
|
grid minor
|
||||||
fontsize(gca,8,"points")
|
fontsize(gca,8,"points")
|
||||||
fig.Units = "centimeters";
|
fig.Units = "centimeters";
|
||||||
fig.Position = [2 2 8.5 7];
|
fig.Position = [2 2 8.5 7];
|
||||||
set(gca,'TickLabelInterpreter','latex')
|
set(gca,'TickLabelInterpreter','latex')
|
||||||
ylim([1e-5,0.5]);
|
ylim([1e-5,0.5]);
|
||||||
xlim([min(xAxis),-3]);
|
xlim([min(xAxis),-3]);
|
||||||
|
|
||||||
wh = load("C:\Users\Silas\Documents\MATLAB\Datensätze\Raw_Cluster_Simulations\session_dispersion_validation\wh_no_variation.mat");
|
wh = load("C:\Users\Silas\Documents\MATLAB\Datensätze\Raw_Cluster_Simulations\session_dispersion_validation\wh_no_variation.mat");
|
||||||
wh = wh.wh;
|
wh = wh.wh;
|
||||||
|
|
||||||
|
|
||||||
figure(3)
|
figure(3)
|
||||||
hold on
|
hold on
|
||||||
plot(xAxis,getber(wh,lambda),'DisplayName',['w:', num2str(lambda), 'no variation']);
|
plot(xAxis,getber(wh,lambda),'DisplayName',['w:', num2str(lambda), 'no variation']);
|
||||||
yline(3.8e-3,'HandleVisibility','off');
|
yline(3.8e-3,'HandleVisibility','off');
|
||||||
legend
|
legend
|
||||||
set(gca,'yscale','log');
|
set(gca,'yscale','log');
|
||||||
grid(gca,'on');
|
grid(gca,'on');
|
||||||
grid(gca,'minor');
|
grid(gca,'minor');
|
||||||
grid minor
|
grid minor
|
||||||
fontsize(gca,8,"points")
|
fontsize(gca,8,"points")
|
||||||
fig.Units = "centimeters";
|
fig.Units = "centimeters";
|
||||||
fig.Position = [2 2 8.5 7];
|
fig.Position = [2 2 8.5 7];
|
||||||
set(gca,'TickLabelInterpreter','latex')
|
set(gca,'TickLabelInterpreter','latex')
|
||||||
ylim([1e-5,0.5]);
|
ylim([1e-5,0.5]);
|
||||||
xlim([min(xAxis),-3]);
|
xlim([min(xAxis),-3]);
|
||||||
|
|
||||||
|
|
||||||
function ber = getber(wh,lambda)
|
function ber = getber(wh,lambda)
|
||||||
realization = wh.parameter.realization.values(1:end);
|
realization = wh.parameter.realization.values(1:end);
|
||||||
xAxis = wh.parameter.p_out.values;
|
xAxis = wh.parameter.p_out.values;
|
||||||
ber = [];
|
ber = [];
|
||||||
for xl = 1:numel(xAxis)
|
for xl = 1:numel(xAxis)
|
||||||
p_out = xAxis(xl);
|
p_out = xAxis(xl);
|
||||||
temp = wh.getStoValue('ber',10,0,0,"copolarized",3,p_out,0.1,0.0023,realization,1,lambda,400e9,1);
|
temp = wh.getStoValue('ber',10,0,0,"copolarized",3,p_out,0.1,0.0023,realization,1,lambda,400e9,1);
|
||||||
ber(xl) = mean(temp,'all');
|
ber(xl) = mean(temp,'all');
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -1,61 +1,61 @@
|
|||||||
function generatePlots(wh,plotJob)
|
function generatePlots(wh,plotJob)
|
||||||
|
|
||||||
% 0) Test for valid query:
|
% 0) Test for valid query:
|
||||||
p_out = wh.parameter.p_out.values(1);
|
p_out = wh.parameter.p_out.values(1);
|
||||||
realization = 9;
|
realization = 9;
|
||||||
|
|
||||||
|
|
||||||
if 1 %~isempty(wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.ch,1310))
|
if 1 %~isempty(wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.ch,1310))
|
||||||
% test violin
|
% test violin
|
||||||
|
|
||||||
baseName = plotJob.figName;
|
baseName = plotJob.figName;
|
||||||
|
|
||||||
width = 350;
|
width = 350;
|
||||||
height = 200;
|
height = 200;
|
||||||
s = 100;
|
s = 100;
|
||||||
e = 100;
|
e = 100;
|
||||||
|
|
||||||
if plotJob.plot_ber_curve
|
if plotJob.plot_ber_curve
|
||||||
plotJob.Position = [100 100 width e+height];
|
plotJob.Position = [100 100 width e+height];
|
||||||
plotJob.figName = [baseName, ' zdwvsber'];
|
plotJob.figName = [baseName, ' zdwvsber'];
|
||||||
plotCurve(wh, plotJob);
|
plotCurve(wh, plotJob);
|
||||||
end
|
end
|
||||||
|
|
||||||
if plotJob.plot_3dber_curve
|
if plotJob.plot_3dber_curve
|
||||||
plotJob.Position = [100 100 width e+height];
|
plotJob.Position = [100 100 width e+height];
|
||||||
plotJob.figName = [baseName, ' zdwvsber'];
|
plotJob.figName = [baseName, ' zdwvsber'];
|
||||||
plot3dCurve(wh, plotJob);
|
plot3dCurve(wh, plotJob);
|
||||||
end
|
end
|
||||||
|
|
||||||
if plotJob.plot_wavelength_sweep
|
if plotJob.plot_wavelength_sweep
|
||||||
plotJob.Position = [100 100 width e+height];
|
plotJob.Position = [100 100 width e+height];
|
||||||
plotJob.figName = [baseName, ' zdwvsber'];
|
plotJob.figName = [baseName, ' zdwvsber'];
|
||||||
plotBerVsZDW(wh, plotJob);
|
plotBerVsZDW(wh, plotJob);
|
||||||
end
|
end
|
||||||
|
|
||||||
if plotJob.plot_wavelength_sweep_failure_rate
|
if plotJob.plot_wavelength_sweep_failure_rate
|
||||||
plotJob.Position = [100 100 width e+height];
|
plotJob.Position = [100 100 width e+height];
|
||||||
plotJob.figName = [baseName, ' zdwvsber'];
|
plotJob.figName = [baseName, ' zdwvsber'];
|
||||||
plotBerVsZdwFailureRate(wh, plotJob);
|
plotBerVsZdwFailureRate(wh, plotJob);
|
||||||
end
|
end
|
||||||
|
|
||||||
if plotJob.plot_violin
|
if plotJob.plot_violin
|
||||||
plotJob.Position = [s+width 100 width e+height];
|
plotJob.Position = [s+width 100 width e+height];
|
||||||
plotJob.figName = [baseName, ' violin'];
|
plotJob.figName = [baseName, ' violin'];
|
||||||
plotViolin(wh, plotJob);
|
plotViolin(wh, plotJob);
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
if 0
|
if 0
|
||||||
%2) plotHistogram
|
%2) plotHistogram
|
||||||
plotJob.Position = [s+2*width 100 width e+height];
|
plotJob.Position = [s+2*width 100 width e+height];
|
||||||
plotJob.figName = [baseName, ' FEC crossing'];
|
plotJob.figName = [baseName, ' FEC crossing'];
|
||||||
plotHistogram(wh,plotJob)
|
plotHistogram(wh,plotJob)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
else
|
else
|
||||||
warndlg('The requested Datapoint is not available... This can occur for some edgecase constellations... ')
|
warndlg('The requested Datapoint is not available... This can occur for some edgecase constellations... ')
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -1,248 +1,248 @@
|
|||||||
function plotCurve(wh,plotJob)
|
function plotCurve(wh,plotJob)
|
||||||
%PLOTCURVE Summary of this function goes here
|
%PLOTCURVE Summary of this function goes here
|
||||||
% Detailed explanation goes here
|
% Detailed explanation goes here
|
||||||
|
|
||||||
fig = findall(groot, 'Type', 'figure', 'Name', plotJob.figName);
|
fig = findall(groot, 'Type', 'figure', 'Name', plotJob.figName);
|
||||||
|
|
||||||
if isvalid(fig)
|
if isvalid(fig)
|
||||||
figure(fig)
|
figure(fig)
|
||||||
fig = get(fig);
|
fig = get(fig);
|
||||||
AxesMain = fig.CurrentAxes;
|
AxesMain = fig.CurrentAxes;
|
||||||
hold on
|
hold on
|
||||||
else
|
else
|
||||||
fig = figure('name',char(plotJob.figName));
|
fig = figure('name',char(plotJob.figName));
|
||||||
AxesMain = gca;
|
AxesMain = gca;
|
||||||
hold on
|
hold on
|
||||||
end
|
end
|
||||||
|
|
||||||
col = plotJob.color;
|
col = plotJob.color;
|
||||||
|
|
||||||
% we want to fetch all realizations
|
% we want to fetch all realizations
|
||||||
if plotJob.pmd == 0
|
if plotJob.pmd == 0
|
||||||
realization = 499;
|
realization = 499;
|
||||||
% realization = 0:7;
|
% realization = 0:7;
|
||||||
else
|
else
|
||||||
realization = wh.parameter.realization.values(1:end);
|
realization = wh.parameter.realization.values(1:end);
|
||||||
end
|
end
|
||||||
realization = wh.parameter.realization.values(1:end);
|
realization = wh.parameter.realization.values(1:end);
|
||||||
% get all xAxis values
|
% get all xAxis values
|
||||||
xAxis = wh.parameter.p_out.values;
|
xAxis = wh.parameter.p_out.values;
|
||||||
|
|
||||||
% Fetch Data from Warehouse
|
% Fetch Data from Warehouse
|
||||||
for xl = 1:numel(xAxis)
|
for xl = 1:numel(xAxis)
|
||||||
p_out = xAxis(xl);
|
p_out = xAxis(xl);
|
||||||
if string(plotJob.dataStatArg) == "Worst"
|
if string(plotJob.dataStatArg) == "Worst"
|
||||||
temp = wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.ch,1310,plotJob.channelspacing,plotJob.randzdw);
|
temp = wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.ch,1310,plotJob.channelspacing,plotJob.randzdw);
|
||||||
temp = removeZeros(temp);
|
temp = removeZeros(temp);
|
||||||
ber(xl) = max(temp,[],'all');
|
ber(xl) = max(temp,[],'all');
|
||||||
linew = 1.0;
|
linew = 1.0;
|
||||||
markersz = 3;
|
markersz = 3;
|
||||||
linestyle = '-';
|
linestyle = '-';
|
||||||
elseif string(plotJob.dataStatArg) == "AVG"
|
elseif string(plotJob.dataStatArg) == "AVG"
|
||||||
temp = wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.ch,1310,plotJob.channelspacing,plotJob.randzdw);
|
temp = wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.ch,1310,plotJob.channelspacing,plotJob.randzdw);
|
||||||
temp = removeZeros(temp);
|
temp = removeZeros(temp);
|
||||||
ber(xl) = mean(temp,'all');
|
ber(xl) = mean(temp,'all');
|
||||||
linew = 1.0;
|
linew = 1.0;
|
||||||
markersz = 3;
|
markersz = 3;
|
||||||
linestyle = '-';
|
linestyle = '-';
|
||||||
elseif string(plotJob.dataStatArg) == "Best"
|
elseif string(plotJob.dataStatArg) == "Best"
|
||||||
temp = wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.ch,1310,plotJob.channelspacing,plotJob.randzdw);
|
temp = wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.ch,1310,plotJob.channelspacing,plotJob.randzdw);
|
||||||
temp = removeZeros(temp);
|
temp = removeZeros(temp);
|
||||||
ber(xl) = min(temp,[],'all');
|
ber(xl) = min(temp,[],'all');
|
||||||
linew = 1.0;
|
linew = 1.0;
|
||||||
markersz = 3;
|
markersz = 3;
|
||||||
linestyle = '-';
|
linestyle = '-';
|
||||||
|
|
||||||
elseif string(plotJob.dataStatArg) == "All Channels; mean(PMD Realizations)"
|
elseif string(plotJob.dataStatArg) == "All Channels; mean(PMD Realizations)"
|
||||||
temp = wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.ch,1310,plotJob.channelspacing,plotJob.randzdw);
|
temp = wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.ch,1310,plotJob.channelspacing,plotJob.randzdw);
|
||||||
temp = removeZeros(temp);
|
temp = removeZeros(temp);
|
||||||
|
|
||||||
ber(:,xl) = mean(temp,1,"omitnan").';
|
ber(:,xl) = mean(temp,1,"omitnan").';
|
||||||
|
|
||||||
linew = 1;
|
linew = 1;
|
||||||
markersz = 3;
|
markersz = 3;
|
||||||
linestyle = '--';
|
linestyle = '--';
|
||||||
|
|
||||||
elseif string(plotJob.dataStatArg) == "Lineplot with quartiles"
|
elseif string(plotJob.dataStatArg) == "Lineplot with quartiles"
|
||||||
|
|
||||||
temp = wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.ch,1310,plotJob.channelspacing,plotJob.randzdw);
|
temp = wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.ch,1310,plotJob.channelspacing,plotJob.randzdw);
|
||||||
temp = removeZeros(temp);
|
temp = removeZeros(temp);
|
||||||
ber(xl) = mean(temp,"all","omitnan").';
|
ber(xl) = mean(temp,"all","omitnan").';
|
||||||
|
|
||||||
|
|
||||||
upperq(xl) = quantile(temp,0.9,"all");
|
upperq(xl) = quantile(temp,0.9,"all");
|
||||||
lowerq(xl) = quantile(temp,0.1,"all");
|
lowerq(xl) = quantile(temp,0.1,"all");
|
||||||
|
|
||||||
if lowerq(xl) == 0
|
if lowerq(xl) == 0
|
||||||
lowerq(xl) = lowerq(xl-1);
|
lowerq(xl) = lowerq(xl-1);
|
||||||
end
|
end
|
||||||
% upperq(xl) = 0.5*std(tmp,1,'all','omitnan');
|
% upperq(xl) = 0.5*std(tmp,1,'all','omitnan');
|
||||||
% lowerq(xl) = 0.5*std(tmp,1,'all','omitnan');
|
% lowerq(xl) = 0.5*std(tmp,1,'all','omitnan');
|
||||||
|
|
||||||
% upperq(xl) = max(dataNoNans);
|
% upperq(xl) = max(dataNoNans);
|
||||||
% lowerq(xl) = min(dataNoNans);
|
% lowerq(xl) = min(dataNoNans);
|
||||||
|
|
||||||
% upperq(xl) = mean(tmp,"all","omitnan") + 1.96 * (std(tmp,1,'all','omitnan')/sqrt(numel(tmp)));
|
% upperq(xl) = mean(tmp,"all","omitnan") + 1.96 * (std(tmp,1,'all','omitnan')/sqrt(numel(tmp)));
|
||||||
% lowerq(xl) = mean(tmp,"all","omitnan") - 1.96 * (std(tmp,1,'all','omitnan')/sqrt(numel(tmp)));
|
% lowerq(xl) = mean(tmp,"all","omitnan") - 1.96 * (std(tmp,1,'all','omitnan')/sqrt(numel(tmp)));
|
||||||
|
|
||||||
linew = 1;
|
linew = 1;
|
||||||
markersz = 1;
|
markersz = 1;
|
||||||
linestyle = '-';
|
linestyle = '-';
|
||||||
|
|
||||||
elseif string(plotJob.dataStatArg) == "All Channels ;All PMD Realizations"
|
elseif string(plotJob.dataStatArg) == "All Channels ;All PMD Realizations"
|
||||||
|
|
||||||
tmp = reshape(wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.ch,1310,plotJob.channelspacing,plotJob.randzdw).',[],1);
|
tmp = reshape(wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.ch,1310,plotJob.channelspacing,plotJob.randzdw).',[],1);
|
||||||
ber(1:size(tmp,1),xl) = tmp;
|
ber(1:size(tmp,1),xl) = tmp;
|
||||||
|
|
||||||
linew = 0.3;
|
linew = 0.3;
|
||||||
markersz = 2;
|
markersz = 2;
|
||||||
linestyle = ':';
|
linestyle = ':';
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
xAxis = xAxis;
|
xAxis = xAxis;
|
||||||
|
|
||||||
% Plot Data
|
% Plot Data
|
||||||
if string(plotJob.plotTypeArg) == "Scatter"
|
if string(plotJob.plotTypeArg) == "Scatter"
|
||||||
for rlz = 1:size(ber,1)
|
for rlz = 1:size(ber,1)
|
||||||
|
|
||||||
if rlz < size(ber,1)
|
if rlz < size(ber,1)
|
||||||
scatter(xAxis,ber(rlz,:),markersz,'MarkerEdgeColor',col,'MarkerFaceColor',col,'Parent', AxesMain(1),'HandleVisibility','off');
|
scatter(xAxis,ber(rlz,:),markersz,'MarkerEdgeColor',col,'MarkerFaceColor',col,'Parent', AxesMain(1),'HandleVisibility','off');
|
||||||
else
|
else
|
||||||
scatter(xAxis,ber(rlz,:),markersz,'MarkerEdgeColor',col,'MarkerFaceColor',col,'Parent', AxesMain(1),'DisplayName',[plotJob.dataStatArg,' Ch.: ', plotJob.displayname]);
|
scatter(xAxis,ber(rlz,:),markersz,'MarkerEdgeColor',col,'MarkerFaceColor',col,'Parent', AxesMain(1),'DisplayName',[plotJob.dataStatArg,' Ch.: ', plotJob.displayname]);
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif string(plotJob.plotTypeArg) == "Lines"
|
elseif string(plotJob.plotTypeArg) == "Lines"
|
||||||
|
|
||||||
% if ~anynan(ber)
|
% if ~anynan(ber)
|
||||||
% [xAxis,ber] = interpCurve(xAxis, ber);
|
% [xAxis,ber] = interpCurve(xAxis, ber);
|
||||||
% end
|
% end
|
||||||
|
|
||||||
for rlz = 1:size(ber,1)
|
for rlz = 1:size(ber,1)
|
||||||
%
|
%
|
||||||
if (string(plotJob.dataStatArg) == "All Channels ;All PMD Realizations")||(string(plotJob.dataStatArg) == "All Channels; mean(PMD Realizations)")
|
if (string(plotJob.dataStatArg) == "All Channels ;All PMD Realizations")||(string(plotJob.dataStatArg) == "All Channels; mean(PMD Realizations)")
|
||||||
ch = mod(rlz,plotJob.ch);
|
ch = mod(rlz,plotJob.ch);
|
||||||
if ch == 0; ch = plotJob.ch; end
|
if ch == 0; ch = plotJob.ch; end
|
||||||
else
|
else
|
||||||
ch = plotJob.dataStatArg;
|
ch = plotJob.dataStatArg;
|
||||||
end
|
end
|
||||||
|
|
||||||
if rlz <= size(ber,1)
|
if rlz <= size(ber,1)
|
||||||
|
|
||||||
|
|
||||||
s = plot3(xAxis,repmat(ch,1,numel(xAxis)),ber(rlz,:),linestyle,'Marker',"o",'MarkerSize',markersz,'MarkerFaceColor',plotJob.color,'LineWidth',linew,'Color',col,'Parent', AxesMain,'HandleVisibility','off');
|
s = plot3(xAxis,repmat(ch,1,numel(xAxis)),ber(rlz,:),linestyle,'Marker',"o",'MarkerSize',markersz,'MarkerFaceColor',plotJob.color,'LineWidth',linew,'Color',col,'Parent', AxesMain,'HandleVisibility','off');
|
||||||
|
|
||||||
s.DataTipTemplate.Interpreter = "latex";
|
s.DataTipTemplate.Interpreter = "latex";
|
||||||
s.DataTipTemplate.DataTipRows(1).Label = "Ch: ";
|
s.DataTipTemplate.DataTipRows(1).Label = "Ch: ";
|
||||||
s.DataTipTemplate.DataTipRows(1).Value = repmat(ch,size(ber));
|
s.DataTipTemplate.DataTipRows(1).Value = repmat(ch,size(ber));
|
||||||
s.DataTipTemplate.DataTipRows(1);
|
s.DataTipTemplate.DataTipRows(1);
|
||||||
s.DataTipTemplate.DataTipRows(2) = [];
|
s.DataTipTemplate.DataTipRows(2) = [];
|
||||||
|
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
if string(plotJob.dataStatArg) == "Lineplot with quartiles"
|
if string(plotJob.dataStatArg) == "Lineplot with quartiles"
|
||||||
[hl,hp] = boundedline(xAxis,ber(rlz,:),([(ber(rlz,:)-lowerq(rlz,:));upperq(rlz,:)-ber(rlz,:)]'),'-*', 'alpha','Color',col,'transparency', 0.2);
|
[hl,hp] = boundedline(xAxis,ber(rlz,:),([(ber(rlz,:)-lowerq(rlz,:));upperq(rlz,:)-ber(rlz,:)]'),'-*', 'alpha','Color',col,'transparency', 0.2);
|
||||||
hp.LineWidth = 1.2;
|
hp.LineWidth = 1.2;
|
||||||
|
|
||||||
ho = outlinebounds(hl,hp);
|
ho = outlinebounds(hl,hp);
|
||||||
set(ho, 'linestyle', ':', 'color', col);
|
set(ho, 'linestyle', ':', 'color', col);
|
||||||
else
|
else
|
||||||
|
|
||||||
s = plot(xAxis,ber(rlz,:),linestyle,'Marker',"o",'MarkerFaceColor',col,'MarkerSize',markersz,'LineWidth',linew,'Color',col,'Parent', AxesMain,'DisplayName',[plotJob.displayname]);
|
s = plot(xAxis,ber(rlz,:),linestyle,'Marker',"o",'MarkerFaceColor',col,'MarkerSize',markersz,'LineWidth',linew,'Color',col,'Parent', AxesMain,'DisplayName',[plotJob.displayname]);
|
||||||
|
|
||||||
s.DataTipTemplate.Interpreter = "latex";
|
s.DataTipTemplate.Interpreter = "latex";
|
||||||
s.DataTipTemplate.DataTipRows(1).Label = "Ch: ";
|
s.DataTipTemplate.DataTipRows(1).Label = "Ch: ";
|
||||||
s.DataTipTemplate.DataTipRows(1).Value = repmat(string(ch),size(ber));
|
s.DataTipTemplate.DataTipRows(1).Value = repmat(string(ch),size(ber));
|
||||||
s.DataTipTemplate.DataTipRows(1)
|
s.DataTipTemplate.DataTipRows(1)
|
||||||
s.DataTipTemplate.DataTipRows(2) = [];
|
s.DataTipTemplate.DataTipRows(2) = [];
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
% Draw FEC Threshold Line
|
% Draw FEC Threshold Line
|
||||||
%get x data of first children:
|
%get x data of first children:
|
||||||
%get all linear Values
|
%get all linear Values
|
||||||
if 0
|
if 0
|
||||||
linear = wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,wh.parameter.p_out.values,0,0,499,"symmetric");
|
linear = wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,wh.parameter.p_out.values,0,0,499,"symmetric");
|
||||||
linear = mean(linear,2);
|
linear = mean(linear,2);
|
||||||
lincurve = findall(AxesMain, 'Type', 'line','DisplayName','Linear Baseline');
|
lincurve = findall(AxesMain, 'Type', 'line','DisplayName','Linear Baseline');
|
||||||
%
|
%
|
||||||
if isempty(lincurve)
|
if isempty(lincurve)
|
||||||
xdata = AxesMain.Children(1).XData;
|
xdata = AxesMain.Children(1).XData;
|
||||||
hdfec = 3.8e-3.*ones(size(xdata));
|
hdfec = 3.8e-3.*ones(size(xdata));
|
||||||
plot(xdata,linear,'-','Marker',"o",'MarkerSize',3,'LineWidth',4,'Color',[0.6400 0.6400 0.6400],'MarkerFaceColor',[0.6400 0.6400 0.6400],'Parent', AxesMain,'DisplayName','Linear Baseline');
|
plot(xdata,linear,'-','Marker',"o",'MarkerSize',3,'LineWidth',4,'Color',[0.6400 0.6400 0.6400],'MarkerFaceColor',[0.6400 0.6400 0.6400],'Parent', AxesMain,'DisplayName','Linear Baseline');
|
||||||
%h = get(gca,'Children');
|
%h = get(gca,'Children');
|
||||||
%set(gca,'Children',[h(2) h(1)])
|
%set(gca,'Children',[h(2) h(1)])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
feccurve = findall(AxesMain, 'Type', 'line','DisplayName','FEC $3.8*10^{-3}$');
|
feccurve = findall(AxesMain, 'Type', 'line','DisplayName','FEC $3.8*10^{-3}$');
|
||||||
%
|
%
|
||||||
if isempty(feccurve)
|
if isempty(feccurve)
|
||||||
xdata = xAxis;
|
xdata = xAxis;
|
||||||
hdfec = 3.8e-3.*ones(size(xdata));
|
hdfec = 3.8e-3.*ones(size(xdata));
|
||||||
for ch = 1:plotJob.ch
|
for ch = 1:plotJob.ch
|
||||||
plot3(xdata,repmat(ch,1,numel(xAxis)),hdfec,':','MarkerSize',4,'Color','black','MarkerFaceColor','black','LineWidth',0.5,'Parent', AxesMain,'DisplayName','FEC $3.8*10^{-3}$','HandleVisibility','off');
|
plot3(xdata,repmat(ch,1,numel(xAxis)),hdfec,':','MarkerSize',4,'Color','black','MarkerFaceColor','black','LineWidth',0.5,'Parent', AxesMain,'DisplayName','FEC $3.8*10^{-3}$','HandleVisibility','off');
|
||||||
end
|
end
|
||||||
%h = get(gca,'Children');
|
%h = get(gca,'Children');
|
||||||
%set(gca,'Children',[h(2) h(1)])
|
%set(gca,'Children',[h(2) h(1)])
|
||||||
end
|
end
|
||||||
|
|
||||||
% Figure Settings
|
% Figure Settings
|
||||||
%title(AxesMain,plotJob.title,"Interpreter","none");
|
%title(AxesMain,plotJob.title,"Interpreter","none");
|
||||||
|
|
||||||
xlabel(AxesMain,plotJob.xAxisLabel,"Interpreter","none");
|
xlabel(AxesMain,plotJob.xAxisLabel,"Interpreter","none");
|
||||||
|
|
||||||
ylabel(AxesMain,plotJob.yAxisLabel,"Interpreter","none");
|
ylabel(AxesMain,plotJob.yAxisLabel,"Interpreter","none");
|
||||||
|
|
||||||
set(AxesMain,'zscale','log');
|
set(AxesMain,'zscale','log');
|
||||||
|
|
||||||
grid(AxesMain,'on');
|
grid(AxesMain,'on');
|
||||||
|
|
||||||
grid(AxesMain,'minor');
|
grid(AxesMain,'minor');
|
||||||
|
|
||||||
grid minor
|
grid minor
|
||||||
|
|
||||||
view(AxesMain,[42.0619302949062 23.4176470588235]);
|
view(AxesMain,[42.0619302949062 23.4176470588235]);
|
||||||
%legend(AxesMain);
|
%legend(AxesMain);
|
||||||
|
|
||||||
fontsize(AxesMain,8,"points")
|
fontsize(AxesMain,8,"points")
|
||||||
fontname(AxesMain,"Arial")
|
fontname(AxesMain,"Arial")
|
||||||
|
|
||||||
fig.Position = plotJob.Position;
|
fig.Position = plotJob.Position;
|
||||||
fig.Units = "centimeters";
|
fig.Units = "centimeters";
|
||||||
fig.Position = [2 2 8.5 7];
|
fig.Position = [2 2 8.5 7];
|
||||||
|
|
||||||
set(AxesMain,'TickLabelInterpreter','none')
|
set(AxesMain,'TickLabelInterpreter','none')
|
||||||
|
|
||||||
set(AxesMain.Legend,'Interpreter','none')
|
set(AxesMain.Legend,'Interpreter','none')
|
||||||
% set(gcf,'Units','centimeters')
|
% set(gcf,'Units','centimeters')
|
||||||
% set(gcf,'Position',[2 2 9 4.5])
|
% set(gcf,'Position',[2 2 9 4.5])
|
||||||
|
|
||||||
zlim([1e-4,0.3]);
|
zlim([1e-4,0.3]);
|
||||||
|
|
||||||
xlim([min(xAxis),-3]);
|
xlim([min(xAxis),-3]);
|
||||||
|
|
||||||
|
|
||||||
annotation('textbox', [0.125, 0.32, 0.1, 0.1], 'String', "FEC 3.8e-3","LineStyle","none","FontSize",8,"FontUnits","points")
|
annotation('textbox', [0.125, 0.32, 0.1, 0.1], 'String', "FEC 3.8e-3","LineStyle","none","FontSize",8,"FontUnits","points")
|
||||||
|
|
||||||
|
|
||||||
hold off
|
hold off
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function vec = removeZeros(vec)
|
function vec = removeZeros(vec)
|
||||||
% Find rows that contain only zeros
|
% Find rows that contain only zeros
|
||||||
rows_to_remove = all(vec == 0, 2);
|
rows_to_remove = all(vec == 0, 2);
|
||||||
|
|
||||||
% Remove rows with only zeros
|
% Remove rows with only zeros
|
||||||
vec(rows_to_remove, :) = [];
|
vec(rows_to_remove, :) = [];
|
||||||
end
|
end
|
||||||
@@ -1,300 +1,300 @@
|
|||||||
function plotBerVsZDW(wh,plotJob)
|
function plotBerVsZDW(wh,plotJob)
|
||||||
|
|
||||||
fig = findall(groot, 'Type', 'figure', 'Name', plotJob.figName);
|
fig = findall(groot, 'Type', 'figure', 'Name', plotJob.figName);
|
||||||
|
|
||||||
if isvalid(fig)
|
if isvalid(fig)
|
||||||
figure(fig)
|
figure(fig)
|
||||||
fig = get(fig);
|
fig = get(fig);
|
||||||
AxesMain = fig.CurrentAxes;
|
AxesMain = fig.CurrentAxes;
|
||||||
hold on
|
hold on
|
||||||
else
|
else
|
||||||
fig = figure('name',char(plotJob.figName));
|
fig = figure('name',char(plotJob.figName));
|
||||||
AxesMain = gca;
|
AxesMain = gca;
|
||||||
hold on
|
hold on
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
col = plotJob.color;
|
col = plotJob.color;
|
||||||
|
|
||||||
% we want to fetch all realizations
|
% we want to fetch all realizations
|
||||||
realization = wh.parameter.realization.values(1:end);
|
realization = wh.parameter.realization.values(1:end);
|
||||||
|
|
||||||
% get all xAxis values
|
% get all xAxis values
|
||||||
xAxis = wh.parameter.p_out.values;
|
xAxis = wh.parameter.p_out.values;
|
||||||
|
|
||||||
% get all center wavelengths
|
% get all center wavelengths
|
||||||
wavelengths = wh.parameter.center_wavelength.values;
|
wavelengths = wh.parameter.center_wavelength.values;
|
||||||
|
|
||||||
% totber = NaN(numel(realization),1,numel(xAxis),numel(wavelengths));
|
% totber = NaN(numel(realization),1,numel(xAxis),numel(wavelengths));
|
||||||
% ber = zeros(numel(realization),plotJob.ch,numel(xAxis),numel(wavelengths));
|
% ber = zeros(numel(realization),plotJob.ch,numel(xAxis),numel(wavelengths));
|
||||||
|
|
||||||
%get BER values for query
|
%get BER values for query
|
||||||
for w = 2:numel(wavelengths)
|
for w = 2:numel(wavelengths)
|
||||||
|
|
||||||
for xl = 1:numel(xAxis)
|
for xl = 1:numel(xAxis)
|
||||||
|
|
||||||
c_wavelen = wavelengths(w);
|
c_wavelen = wavelengths(w);
|
||||||
p_out = xAxis(xl);
|
p_out = xAxis(xl);
|
||||||
|
|
||||||
% dim1 : realiz; dim2: channels, dim3: rop, dim4, c_wavelength
|
% dim1 : realiz; dim2: channels, dim3: rop, dim4, c_wavelength
|
||||||
temp = removeZeros(wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.ch,c_wavelen,plotJob.channelspacing,plotJob.randzdw));
|
temp = removeZeros(wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.ch,c_wavelen,plotJob.channelspacing,plotJob.randzdw));
|
||||||
ber(1:size(temp,1),:,xl,w) = temp;
|
ber(1:size(temp,1),:,xl,w) = temp;
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
hdfec = 3.8e-3.*ones(size(xAxis));
|
hdfec = 3.8e-3.*ones(size(xAxis));
|
||||||
zdw_ = [];
|
zdw_ = [];
|
||||||
zdw_chann = [];
|
zdw_chann = [];
|
||||||
zdw_tot = [];
|
zdw_tot = [];
|
||||||
cf_tot = [];
|
cf_tot = [];
|
||||||
cf_ = [];
|
cf_ = [];
|
||||||
S = [];
|
S = [];
|
||||||
Stot = [];
|
Stot = [];
|
||||||
S_chann = [];
|
S_chann = [];
|
||||||
cf_chann = [];
|
cf_chann = [];
|
||||||
|
|
||||||
cnt = 0;
|
cnt = 0;
|
||||||
%get fec thresholds
|
%get fec thresholds
|
||||||
%linear = squeeze(linear);
|
%linear = squeeze(linear);
|
||||||
for c_wavelen = 1:size(ber,4)
|
for c_wavelen = 1:size(ber,4)
|
||||||
for realiz = 1:size(ber,1)
|
for realiz = 1:size(ber,1)
|
||||||
for chann = 1:size(ber,2)
|
for chann = 1:size(ber,2)
|
||||||
|
|
||||||
%finde Schnittpunkt zwischen FEC und BER Kurve
|
%finde Schnittpunkt zwischen FEC und BER Kurve
|
||||||
temp_ber = squeeze(ber(realiz,chann,:,c_wavelen)).';
|
temp_ber = squeeze(ber(realiz,chann,:,c_wavelen)).';
|
||||||
if ~all(temp_ber == 0)
|
if ~all(temp_ber == 0)
|
||||||
%nur wenn nicht alles nullen sind
|
%nur wenn nicht alles nullen sind
|
||||||
crossing_ch = InterX([hdfec;xAxis],[temp_ber;xAxis]);
|
crossing_ch = InterX([hdfec;xAxis],[temp_ber;xAxis]);
|
||||||
else
|
else
|
||||||
continue
|
continue
|
||||||
end
|
end
|
||||||
|
|
||||||
%Req. FEC Ergebnis einsortieren
|
%Req. FEC Ergebnis einsortieren
|
||||||
if ~isempty(crossing_ch)
|
if ~isempty(crossing_ch)
|
||||||
if crossing_ch(2) == 0
|
if crossing_ch(2) == 0
|
||||||
print("d")
|
print("d")
|
||||||
end
|
end
|
||||||
S(realiz,chann,c_wavelen) = crossing_ch(2);
|
S(realiz,chann,c_wavelen) = crossing_ch(2);
|
||||||
else
|
else
|
||||||
S(realiz,chann,c_wavelen) = -1;
|
S(realiz,chann,c_wavelen) = -1;
|
||||||
cnt = cnt +1;
|
cnt = cnt +1;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
temp_max = -inf;
|
temp_max = -inf;
|
||||||
for i = 1:plotJob.ch
|
for i = 1:plotJob.ch
|
||||||
hold on
|
hold on
|
||||||
%S:: 1.dim: realiz; 2.dim: channel; 3.dim: center wavelength
|
%S:: 1.dim: realiz; 2.dim: channel; 3.dim: center wavelength
|
||||||
%squeeze a channel:
|
%squeeze a channel:
|
||||||
temp_data = squeeze(S(:,i,:));
|
temp_data = squeeze(S(:,i,:));
|
||||||
|
|
||||||
%remove realizations that have no entry (only zero)
|
%remove realizations that have no entry (only zero)
|
||||||
temp_data = removeZeros(temp_data);
|
temp_data = removeZeros(temp_data);
|
||||||
|
|
||||||
%replace zeros with NAN (e.g. for the wavelengths that have missing realizations)
|
%replace zeros with NAN (e.g. for the wavelengths that have missing realizations)
|
||||||
temp_data(temp_data==0) = NaN;
|
temp_data(temp_data==0) = NaN;
|
||||||
|
|
||||||
%plot required ROP for channel and all realizations that cross the
|
%plot required ROP for channel and all realizations that cross the
|
||||||
%FEC limit
|
%FEC limit
|
||||||
scatter(wavelengths,temp_data ,5,plotJob.color,'Marker','.');
|
scatter(wavelengths,temp_data ,5,plotJob.color,'Marker','.');
|
||||||
|
|
||||||
% %plot mean per channel
|
% %plot mean per channel
|
||||||
% temp_mean = mean(temp_data,'omitnan');
|
% temp_mean = mean(temp_data,'omitnan');
|
||||||
% hold on
|
% hold on
|
||||||
% plot(wavelengths,temp_mean,'Marker','*');
|
% plot(wavelengths,temp_mean,'Marker','*');
|
||||||
|
|
||||||
%get max overall value
|
%get max overall value
|
||||||
temp_max = max(temp_max,max(temp_data));
|
temp_max = max(temp_max,max(temp_data));
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
%plot mean overall
|
%plot mean overall
|
||||||
mean_overall = squeeze(mean(S,2));
|
mean_overall = squeeze(mean(S,2));
|
||||||
mean_overall(mean_overall==0) = NaN;
|
mean_overall(mean_overall==0) = NaN;
|
||||||
%mean_overall(mean_overall==-1) = NaN;
|
%mean_overall(mean_overall==-1) = NaN;
|
||||||
mean_overall=mean(mean_overall,1,'omitnan');
|
mean_overall=mean(mean_overall,1,'omitnan');
|
||||||
plot(wavelengths,mean_overall,'Color',plotJob.color);
|
plot(wavelengths,mean_overall,'Color',plotJob.color);
|
||||||
|
|
||||||
%plot max overall
|
%plot max overall
|
||||||
scatter(wavelengths,temp_max ,35,plotJob.color,'Marker','v');
|
scatter(wavelengths,temp_max ,35,plotJob.color,'Marker','v');
|
||||||
|
|
||||||
|
|
||||||
%plot channel positions
|
%plot channel positions
|
||||||
hold on
|
hold on
|
||||||
chpos = calcWavelengthPlan(plotJob.ch, 400e9, 1310);
|
chpos = calcWavelengthPlan(plotJob.ch, 400e9, 1310);
|
||||||
xline(chpos,'LineWidth',2,'Alpha',0.2);
|
xline(chpos,'LineWidth',2,'Alpha',0.2);
|
||||||
chpos = calcWavelengthPlan(plotJob.ch, 400e9, chpos(4));
|
chpos = calcWavelengthPlan(plotJob.ch, 400e9, chpos(4));
|
||||||
xline(chpos,'LineWidth',2,'Alpha',0.2);
|
xline(chpos,'LineWidth',2,'Alpha',0.2);
|
||||||
|
|
||||||
fig.Position = plotJob.Position;
|
fig.Position = plotJob.Position;
|
||||||
|
|
||||||
ylabel('Penalty in dB');
|
ylabel('Penalty in dB');
|
||||||
xlabel('Wavelength in nm');
|
xlabel('Wavelength in nm');
|
||||||
|
|
||||||
xlim([min(wavelengths),max(wavelengths) ]);
|
xlim([min(wavelengths),max(wavelengths) ]);
|
||||||
|
|
||||||
grid minor;
|
grid minor;
|
||||||
set(gca, 'color', 'none');
|
set(gca, 'color', 'none');
|
||||||
legend = [];
|
legend = [];
|
||||||
|
|
||||||
fontsize(AxesMain,8,"points")
|
fontsize(AxesMain,8,"points")
|
||||||
|
|
||||||
fig.Position = plotJob.Position;
|
fig.Position = plotJob.Position;
|
||||||
fig.Units = "centimeters";
|
fig.Units = "centimeters";
|
||||||
fig.Position = [2 2 8.5 7];
|
fig.Position = [2 2 8.5 7];
|
||||||
|
|
||||||
set(AxesMain,'TickLabelInterpreter','latex')
|
set(AxesMain,'TickLabelInterpreter','latex')
|
||||||
|
|
||||||
set(AxesMain.Legend,'Interpreter','latex')
|
set(AxesMain.Legend,'Interpreter','latex')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
%
|
%
|
||||||
%
|
%
|
||||||
%
|
%
|
||||||
%
|
%
|
||||||
%
|
%
|
||||||
% distinct_cf = unique(cf_chann);
|
% distinct_cf = unique(cf_chann);
|
||||||
%
|
%
|
||||||
% for i = 1:length(distinct_cf)
|
% for i = 1:length(distinct_cf)
|
||||||
% indices = find(cf_chann==distinct_cf(i));
|
% indices = find(cf_chann==distinct_cf(i));
|
||||||
% cf(i) = distinct_cf(i);
|
% cf(i) = distinct_cf(i);
|
||||||
% worst_fec_cross(i) = max(S_chann(indices));
|
% worst_fec_cross(i) = max(S_chann(indices));
|
||||||
% avg_fec_cross(i) = mean(S_chann(indices));
|
% avg_fec_cross(i) = mean(S_chann(indices));
|
||||||
% end
|
% end
|
||||||
%
|
%
|
||||||
% avg_fec_cross = smooth(avg_fec_cross,5);
|
% avg_fec_cross = smooth(avg_fec_cross,5);
|
||||||
%
|
%
|
||||||
% figure(224)
|
% figure(224)
|
||||||
% hold on
|
% hold on
|
||||||
% scatter(cf_,S,10.*abs(S-mean(S)).*ones(size(S)),'DisplayName',['AVG'],'MarkerEdgeColor',col,'MarkerFaceColor',col,'Marker','.');
|
% scatter(cf_,S,10.*abs(S-mean(S)).*ones(size(S)),'DisplayName',['AVG'],'MarkerEdgeColor',col,'MarkerFaceColor',col,'Marker','.');
|
||||||
% hold on
|
% hold on
|
||||||
% scatter(cf(2:end),worst_fec_cross(2:end),15,'DisplayName',['Worst'],'MarkerEdgeColor',col,'MarkerFaceColor',col,'Marker','.','HandleVisibility','off');
|
% scatter(cf(2:end),worst_fec_cross(2:end),15,'DisplayName',['Worst'],'MarkerEdgeColor',col,'MarkerFaceColor',col,'Marker','.','HandleVisibility','off');
|
||||||
% plot(cf(2:end),avg_fec_cross(2:end),'DisplayName',['AVG'],'LineWidth',1,'LineStyle','-','Color',col,'Marker','none','MarkerFaceColor',col,'MarkerSize',2);
|
% plot(cf(2:end),avg_fec_cross(2:end),'DisplayName',['AVG'],'LineWidth',1,'LineStyle','-','Color',col,'Marker','none','MarkerFaceColor',col,'MarkerSize',2);
|
||||||
% plot(cf(2:end),worst_fec_cross(2:end),'DisplayName',['AVG'],'LineWidth',0.5,'LineStyle','-','Color',col,'Marker','none','MarkerFaceColor',col,'MarkerSize',2);
|
% plot(cf(2:end),worst_fec_cross(2:end),'DisplayName',['AVG'],'LineWidth',0.5,'LineStyle','-','Color',col,'Marker','none','MarkerFaceColor',col,'MarkerSize',2);
|
||||||
% ghzgrid = hz2nm(nm2hz(1310)+[0:1:20].*400e9);
|
% ghzgrid = hz2nm(nm2hz(1310)+[0:1:20].*400e9);
|
||||||
% set(gca,'xtick',sort(ghzgrid))
|
% set(gca,'xtick',sort(ghzgrid))
|
||||||
% xlim([min(cf(cf~=0)), 1310.1]);
|
% xlim([min(cf(cf~=0)), 1310.1]);
|
||||||
%
|
%
|
||||||
%
|
%
|
||||||
% % With matlab internal errorbar function...
|
% % With matlab internal errorbar function...
|
||||||
% figure(221)
|
% figure(221)
|
||||||
% %plot(cf,avg_fec_cross,'DisplayName',['AVG'],'LineWidth',1,'Color',col,'Marker','none','MarkerFaceColor',col,'MarkerSize',2);
|
% %plot(cf,avg_fec_cross,'DisplayName',['AVG'],'LineWidth',1,'Color',col,'Marker','none','MarkerFaceColor',col,'MarkerSize',2);
|
||||||
% hold on
|
% hold on
|
||||||
% %plot(cf_tot,min(S_chann(1:length(cf_tot),:),[],2),'DisplayName',['AVG'],'LineWidth',1,'LineStyle',':','Color',col,'Marker','^','MarkerFaceColor',col,'MarkerSize',2);
|
% %plot(cf_tot,min(S_chann(1:length(cf_tot),:),[],2),'DisplayName',['AVG'],'LineWidth',1,'LineStyle',':','Color',col,'Marker','^','MarkerFaceColor',col,'MarkerSize',2);
|
||||||
% plot(cf,worst_fec_cross,'DisplayName',['AVG'],'LineWidth',2,'LineStyle','-','Color',col,'Marker','none','MarkerFaceColor',col,'MarkerSize',2);
|
% plot(cf,worst_fec_cross,'DisplayName',['AVG'],'LineWidth',2,'LineStyle','-','Color',col,'Marker','none','MarkerFaceColor',col,'MarkerSize',2);
|
||||||
% ghzgrid = hz2nm(nm2hz(1310)+[0:1:20].*400e9);
|
% ghzgrid = hz2nm(nm2hz(1310)+[0:1:20].*400e9);
|
||||||
% set(gca,'xtick',sort(ghzgrid))
|
% set(gca,'xtick',sort(ghzgrid))
|
||||||
% xlim([1302, 1310.1]);
|
% xlim([1302, 1310.1]);
|
||||||
% xline(ghzgrid,'LineStyle',':','Color',[.7 .7 .7]);
|
% xline(ghzgrid,'LineStyle',':','Color',[.7 .7 .7]);
|
||||||
|
|
||||||
|
|
||||||
%with
|
%with
|
||||||
% Stot = movmean(Stot,5);
|
% Stot = movmean(Stot,5);
|
||||||
% figure(222)
|
% figure(222)
|
||||||
% [hl,hp] = boundedline(cf_tot,Stot,[(Stot'-min(S_chann(1:length(cf_tot),:),[],2)),(max(S_chann(1:length(cf_tot),:),[],2)-Stot')], 'alpha','Color',col,'transparency', 0.05);
|
% [hl,hp] = boundedline(cf_tot,Stot,[(Stot'-min(S_chann(1:length(cf_tot),:),[],2)),(max(S_chann(1:length(cf_tot),:),[],2)-Stot')], 'alpha','Color',col,'transparency', 0.05);
|
||||||
% ho = outlinebounds(hl,hp);
|
% ho = outlinebounds(hl,hp);
|
||||||
% set(ho, 'linestyle', ':', 'color', col, 'marker', '.','linewidth',0.5);
|
% set(ho, 'linestyle', ':', 'color', col, 'marker', '.','linewidth',0.5);
|
||||||
% hold on
|
% hold on
|
||||||
%
|
%
|
||||||
% ghzgrid = hz2nm(nm2hz(1310)+[0:1:12].*400e9);
|
% ghzgrid = hz2nm(nm2hz(1310)+[0:1:12].*400e9);
|
||||||
% xline(ghzgrid);
|
% xline(ghzgrid);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
%plot the total ber
|
%plot the total ber
|
||||||
|
|
||||||
% %figure(22);
|
% %figure(22);
|
||||||
% hold on;
|
% hold on;
|
||||||
% b= movmean(Stot,3);
|
% b= movmean(Stot,3);
|
||||||
% plot(AxesMain,cf_tot,b,'LineWidth',2,'DisplayName',[plotJob.dataStatArg,' Ch.: ', plotJob.displayname],'Color',col,'Marker','o');
|
% plot(AxesMain,cf_tot,b,'LineWidth',2,'DisplayName',[plotJob.dataStatArg,' Ch.: ', plotJob.displayname],'Color',col,'Marker','o');
|
||||||
% hold on
|
% hold on
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
%scatter(AxesMain,zdw_,S,'Marker','+','MarkerEdgeColor',col,'MarkerFaceAlpha',0.4,'MarkerEdgeAlpha',0.4,'LineWidth',0.5,'Parent', AxesMain(1),'DisplayName',[plotJob.dataStatArg,' Ch.: ', plotJob.displayname]);
|
%scatter(AxesMain,zdw_,S,'Marker','+','MarkerEdgeColor',col,'MarkerFaceAlpha',0.4,'MarkerEdgeAlpha',0.4,'LineWidth',0.5,'Parent', AxesMain(1),'DisplayName',[plotJob.dataStatArg,' Ch.: ', plotJob.displayname]);
|
||||||
%ylim(AxesMain,[-9.3 -7]);
|
%ylim(AxesMain,[-9.3 -7]);
|
||||||
|
|
||||||
% for i = 1:numel(chp)
|
% for i = 1:numel(chp)
|
||||||
% hold on
|
% hold on
|
||||||
% xline(AxesMain,chp(i),'Color',colr(i,:),'DisplayName',['CH: ', num2str(i)],'LineWidth',1.5);
|
% xline(AxesMain,chp(i),'Color',colr(i,:),'DisplayName',['CH: ', num2str(i)],'LineWidth',1.5);
|
||||||
% hold off
|
% hold off
|
||||||
% end
|
% end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
%
|
%
|
||||||
% a = movmean(sortrows([zdw_; S]'),10,'Endpoints','discard');
|
% a = movmean(sortrows([zdw_; S]'),10,'Endpoints','discard');
|
||||||
%
|
%
|
||||||
% sorted = sortrows([zdw_; S]');
|
% sorted = sortrows([zdw_; S]');
|
||||||
% figure(2)
|
% figure(2)
|
||||||
% scatter(sorted(:,1),sorted(:,2))
|
% scatter(sorted(:,1),sorted(:,2))
|
||||||
%
|
%
|
||||||
% ber_sorted = sort(S);
|
% ber_sorted = sort(S);
|
||||||
% mean(ber_sorted);
|
% mean(ber_sorted);
|
||||||
% std(ber_sorted);
|
% std(ber_sorted);
|
||||||
% z1 = [];
|
% z1 = [];
|
||||||
% penalty = mean(ber_sorted):0.01:mean(ber_sorted)+2;
|
% penalty = mean(ber_sorted):0.01:mean(ber_sorted)+2;
|
||||||
% for i = 1:length(penalty)
|
% for i = 1:length(penalty)
|
||||||
% l = penalty(i);
|
% l = penalty(i);
|
||||||
% if i == 1
|
% if i == 1
|
||||||
% z1 = [z1 sum(ber_sorted(1,:)<l ) / length(ber_sorted) ];
|
% z1 = [z1 sum(ber_sorted(1,:)<l ) / length(ber_sorted) ];
|
||||||
% else
|
% else
|
||||||
% z1 = [z1 sum(ber_sorted(1,:)<l & ber_sorted(1,:)>l-0.01) / length(ber_sorted) ];
|
% z1 = [z1 sum(ber_sorted(1,:)<l & ber_sorted(1,:)>l-0.01) / length(ber_sorted) ];
|
||||||
% end
|
% end
|
||||||
%
|
%
|
||||||
% end
|
% end
|
||||||
%
|
%
|
||||||
% penalty_higherthan = 0.5;
|
% penalty_higherthan = 0.5;
|
||||||
% probability = sum(z1(find(penalty>mean(ber_sorted)+penalty_higherthan)));
|
% probability = sum(z1(find(penalty>mean(ber_sorted)+penalty_higherthan)));
|
||||||
% disp(['A penalty of more than 1dB has a probability of: ', num2str(probability)]);
|
% disp(['A penalty of more than 1dB has a probability of: ', num2str(probability)]);
|
||||||
% %
|
% %
|
||||||
% stem(AxesMain,penalty,z1,"filled",'Marker','o','MarkerSize',2,'Color',col);
|
% stem(AxesMain,penalty,z1,"filled",'Marker','o','MarkerSize',2,'Color',col);
|
||||||
%
|
%
|
||||||
%
|
%
|
||||||
% [f1,x1]=ecdf(S(end,:));
|
% [f1,x1]=ecdf(S(end,:));
|
||||||
% %figure(23);plot(AxesMain,x1,f1,'r','LineWidth',3, 'Color',col);
|
% %figure(23);plot(AxesMain,x1,f1,'r','LineWidth',3, 'Color',col);
|
||||||
%
|
%
|
||||||
% %plot(AxesMain,a(:,1),a(:,2),'Color',col+1,'Parent', AxesMain(1));
|
% %plot(AxesMain,a(:,1),a(:,2),'Color',col+1,'Parent', AxesMain(1));
|
||||||
%
|
%
|
||||||
% % histogram(AxesMain,S,1000,'EdgeColor','none','FaceAlpha',0.4);
|
% % histogram(AxesMain,S,1000,'EdgeColor','none','FaceAlpha',0.4);
|
||||||
%
|
%
|
||||||
%
|
%
|
||||||
%
|
%
|
||||||
% %
|
% %
|
||||||
% %scatter(AxesMain,zdw_,S,'Marker','+','MarkerEdgeColor',col,'MarkerFaceAlpha',0.4,'MarkerEdgeAlpha',0.4,'LineWidth',0.5,'Parent', AxesMain(1),'DisplayName',[plotJob.dataStatArg,' Ch.: ', plotJob.displayname]);
|
% %scatter(AxesMain,zdw_,S,'Marker','+','MarkerEdgeColor',col,'MarkerFaceAlpha',0.4,'MarkerEdgeAlpha',0.4,'LineWidth',0.5,'Parent', AxesMain(1),'DisplayName',[plotJob.dataStatArg,' Ch.: ', plotJob.displayname]);
|
||||||
% hold on
|
% hold on
|
||||||
% %scatter(AxesMain,zdw_chann(:,1),mean(S_chann,2),'Marker','diamond','MarkerEdgeColor',col,'MarkerFaceAlpha',0.6,'LineWidth',7,'MarkerFaceColor',col,'Parent', AxesMain(1),'DisplayName',[plotJob.dataStatArg,' Ch.: ', plotJob.displayname]);
|
% %scatter(AxesMain,zdw_chann(:,1),mean(S_chann,2),'Marker','diamond','MarkerEdgeColor',col,'MarkerFaceAlpha',0.6,'LineWidth',7,'MarkerFaceColor',col,'Parent', AxesMain(1),'DisplayName',[plotJob.dataStatArg,' Ch.: ', plotJob.displayname]);
|
||||||
% hold off
|
% hold off
|
||||||
% %
|
% %
|
||||||
% % for rlz = 1:size(S,2)
|
% % for rlz = 1:size(S,2)
|
||||||
% % zdwval = zdw_(rlz);
|
% % zdwval = zdw_(rlz);
|
||||||
% % feccrossing = S(rlz);
|
% % feccrossing = S(rlz);
|
||||||
% % scatter(AxesMain,zdwval,feccrossing,10,'MarkerEdgeColor',col,'MarkerFaceColor',col,'Parent', AxesMain(1),'DisplayName',[plotJob.dataStatArg,' Ch.: ', plotJob.displayname]);
|
% % scatter(AxesMain,zdwval,feccrossing,10,'MarkerEdgeColor',col,'MarkerFaceColor',col,'Parent', AxesMain(1),'DisplayName',[plotJob.dataStatArg,' Ch.: ', plotJob.displayname]);
|
||||||
% % end
|
% % end
|
||||||
%
|
%
|
||||||
% xline([1302.03471732576,1304.30061112288,1306.57440520904,1308.85614097425,1311.14586009814,1313.44360455251,1315.74941660391,1318.06333881618]);
|
% xline([1302.03471732576,1304.30061112288,1306.57440520904,1308.85614097425,1311.14586009814,1313.44360455251,1315.74941660391,1318.06333881618]);
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function vec = removeZeros(vec)
|
function vec = removeZeros(vec)
|
||||||
% Find rows that contain only zeros
|
% Find rows that contain only zeros
|
||||||
rows_to_remove = all(vec == 0, 2);
|
rows_to_remove = all(vec == 0, 2);
|
||||||
|
|
||||||
% Remove rows with only zeros
|
% Remove rows with only zeros
|
||||||
vec(rows_to_remove, :) = [];
|
vec(rows_to_remove, :) = [];
|
||||||
end
|
end
|
||||||
@@ -1,157 +1,157 @@
|
|||||||
function plotBerVsZdwFailureRate(wh,plotJob)
|
function plotBerVsZdwFailureRate(wh,plotJob)
|
||||||
|
|
||||||
fig = findall(groot, 'Type', 'figure', 'Name', plotJob.figName);
|
fig = findall(groot, 'Type', 'figure', 'Name', plotJob.figName);
|
||||||
|
|
||||||
if isvalid(fig)
|
if isvalid(fig)
|
||||||
figure(fig)
|
figure(fig)
|
||||||
fig = get(fig);
|
fig = get(fig);
|
||||||
AxesMain = fig.CurrentAxes;
|
AxesMain = fig.CurrentAxes;
|
||||||
hold on
|
hold on
|
||||||
else
|
else
|
||||||
fig = figure('name',char(plotJob.figName));
|
fig = figure('name',char(plotJob.figName));
|
||||||
AxesMain = gca;
|
AxesMain = gca;
|
||||||
hold on
|
hold on
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
col = plotJob.color;
|
col = plotJob.color;
|
||||||
|
|
||||||
% we want to fetch all realizations
|
% we want to fetch all realizations
|
||||||
realization = wh.parameter.realization.values(1:end);
|
realization = wh.parameter.realization.values(1:end);
|
||||||
|
|
||||||
% get all xAxis values
|
% get all xAxis values
|
||||||
xAxis = wh.parameter.p_out.values;
|
xAxis = wh.parameter.p_out.values;
|
||||||
|
|
||||||
% get all center wavelengths
|
% get all center wavelengths
|
||||||
wavelengths = wh.parameter.center_wavelength.values;
|
wavelengths = wh.parameter.center_wavelength.values;
|
||||||
%wavelengths = wavelengths(2:end);
|
%wavelengths = wavelengths(2:end);
|
||||||
% totber = NaN(numel(realization),1,numel(xAxis),numel(wavelengths));
|
% totber = NaN(numel(realization),1,numel(xAxis),numel(wavelengths));
|
||||||
% ber = zeros(numel(realization),plotJob.ch,numel(xAxis),numel(wavelengths));
|
% ber = zeros(numel(realization),plotJob.ch,numel(xAxis),numel(wavelengths));
|
||||||
|
|
||||||
%get BER values for query
|
%get BER values for query
|
||||||
for w = 1:numel(wavelengths)
|
for w = 1:numel(wavelengths)
|
||||||
|
|
||||||
for xl = 1:numel(xAxis)
|
for xl = 1:numel(xAxis)
|
||||||
|
|
||||||
c_wavelen = wavelengths(w);
|
c_wavelen = wavelengths(w);
|
||||||
p_out = xAxis(xl);
|
p_out = xAxis(xl);
|
||||||
|
|
||||||
% dim1 : realiz; dim2: channels, dim3: rop, dim4, c_wavelength
|
% dim1 : realiz; dim2: channels, dim3: rop, dim4, c_wavelength
|
||||||
temp = removeZeros(wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.ch,c_wavelen,plotJob.channelspacing,plotJob.randzdw));
|
temp = removeZeros(wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.ch,c_wavelen,plotJob.channelspacing,plotJob.randzdw));
|
||||||
ber(1:size(temp,1),:,xl,w) = temp;
|
ber(1:size(temp,1),:,xl,w) = temp;
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
hdfec = 3.8e-3.*ones(size(xAxis));
|
hdfec = 3.8e-3.*ones(size(xAxis));
|
||||||
zdw_ = [];
|
zdw_ = [];
|
||||||
zdw_chann = [];
|
zdw_chann = [];
|
||||||
zdw_tot = [];
|
zdw_tot = [];
|
||||||
cf_tot = [];
|
cf_tot = [];
|
||||||
cf_ = [];
|
cf_ = [];
|
||||||
S = [];
|
S = [];
|
||||||
Stot = [];
|
Stot = [];
|
||||||
S_chann = [];
|
S_chann = [];
|
||||||
cf_chann = [];
|
cf_chann = [];
|
||||||
|
|
||||||
cnt = 0;
|
cnt = 0;
|
||||||
%get fec thresholds
|
%get fec thresholds
|
||||||
%linear = squeeze(linear);
|
%linear = squeeze(linear);
|
||||||
for c_wavelen = 1:size(ber,4)
|
for c_wavelen = 1:size(ber,4)
|
||||||
for realiz = 1:size(ber,1)
|
for realiz = 1:size(ber,1)
|
||||||
for chann = 1:size(ber,2)
|
for chann = 1:size(ber,2)
|
||||||
|
|
||||||
%finde Schnittpunkt zwischen FEC und BER Kurve
|
%finde Schnittpunkt zwischen FEC und BER Kurve
|
||||||
temp_ber = squeeze(ber(realiz,chann,:,c_wavelen)).';
|
temp_ber = squeeze(ber(realiz,chann,:,c_wavelen)).';
|
||||||
if ~all(temp_ber == 0)
|
if ~all(temp_ber == 0)
|
||||||
%nur wenn nicht alles nullen sind
|
%nur wenn nicht alles nullen sind
|
||||||
crossing_ch = InterX([hdfec;xAxis],[temp_ber;xAxis]);
|
crossing_ch = InterX([hdfec;xAxis],[temp_ber;xAxis]);
|
||||||
else
|
else
|
||||||
continue
|
continue
|
||||||
end
|
end
|
||||||
|
|
||||||
%Req. FEC Ergebnis einsortieren
|
%Req. FEC Ergebnis einsortieren
|
||||||
if ~isempty(crossing_ch)
|
if ~isempty(crossing_ch)
|
||||||
if crossing_ch(2) == 0
|
if crossing_ch(2) == 0
|
||||||
print("d")
|
print("d")
|
||||||
end
|
end
|
||||||
S(realiz,chann,c_wavelen) = crossing_ch(2);
|
S(realiz,chann,c_wavelen) = crossing_ch(2);
|
||||||
else
|
else
|
||||||
S(realiz,chann,c_wavelen) = -1;
|
S(realiz,chann,c_wavelen) = -1;
|
||||||
cnt = cnt +1;
|
cnt = cnt +1;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
temp_max = -inf;
|
temp_max = -inf;
|
||||||
sum_FEC_not_crossed=[];
|
sum_FEC_not_crossed=[];
|
||||||
sum_FEC_crossed=[];
|
sum_FEC_crossed=[];
|
||||||
|
|
||||||
threshold = plotJob.p_in - 10;
|
threshold = plotJob.p_in - 10;
|
||||||
|
|
||||||
for i = 1:plotJob.ch
|
for i = 1:plotJob.ch
|
||||||
hold on
|
hold on
|
||||||
%S:: 1.dim: realiz; 2.dim: channel; 3.dim: center wavelength
|
%S:: 1.dim: realiz; 2.dim: channel; 3.dim: center wavelength
|
||||||
%squeeze a channel:
|
%squeeze a channel:
|
||||||
temp_data = squeeze(S(:,i,:));
|
temp_data = squeeze(S(:,i,:));
|
||||||
|
|
||||||
%remove realizations that have no entry (only zero)
|
%remove realizations that have no entry (only zero)
|
||||||
temp_data = removeZeros(temp_data);
|
temp_data = removeZeros(temp_data);
|
||||||
|
|
||||||
%replace zeros with NAN (e.g. for the wavelengths that have missing realizations)
|
%replace zeros with NAN (e.g. for the wavelengths that have missing realizations)
|
||||||
temp_data(temp_data==0) = NaN;
|
temp_data(temp_data==0) = NaN;
|
||||||
|
|
||||||
%for current channel
|
%for current channel
|
||||||
FEC_crossed = temp_data < threshold & ~isnan(temp_data);
|
FEC_crossed = temp_data < threshold & ~isnan(temp_data);
|
||||||
FEC_not_crossed = temp_data >= threshold & ~isnan(temp_data);
|
FEC_not_crossed = temp_data >= threshold & ~isnan(temp_data);
|
||||||
|
|
||||||
%sum over channels for overall picture
|
%sum over channels for overall picture
|
||||||
sum_FEC_not_crossed(i,:) = sum(FEC_not_crossed);
|
sum_FEC_not_crossed(i,:) = sum(FEC_not_crossed);
|
||||||
sum_FEC_crossed(i,:) = sum(FEC_crossed);
|
sum_FEC_crossed(i,:) = sum(FEC_crossed);
|
||||||
|
|
||||||
failure_rate_channelwise(i,:) = sum_FEC_not_crossed(i,:)./ ( sum_FEC_crossed(i,:) + sum_FEC_not_crossed(i,:));
|
failure_rate_channelwise(i,:) = sum_FEC_not_crossed(i,:)./ ( sum_FEC_crossed(i,:) + sum_FEC_not_crossed(i,:));
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
failure_rate_total = sum(sum_FEC_not_crossed,1) ./ ( sum(sum_FEC_crossed,1) + sum(sum_FEC_not_crossed,1) );
|
failure_rate_total = sum(sum_FEC_not_crossed,1) ./ ( sum(sum_FEC_crossed,1) + sum(sum_FEC_not_crossed,1) );
|
||||||
% plot failure rate (nbetween 0 and 1)
|
% plot failure rate (nbetween 0 and 1)
|
||||||
|
|
||||||
plot(wavelengths,failure_rate_total,'Color',plotJob.color,'LineWidth',1,'LineStyle',plotJob.plotTypeArg,'Marker','x','MarkerSize',5,'MarkerFaceColor',plotJob.color,'DisplayName',plotJob.displayname);
|
plot(wavelengths,failure_rate_total,'Color',plotJob.color,'LineWidth',1,'LineStyle',plotJob.plotTypeArg,'Marker','x','MarkerSize',5,'MarkerFaceColor',plotJob.color,'DisplayName',plotJob.displayname);
|
||||||
|
|
||||||
%plot max overall
|
%plot max overall
|
||||||
%scatter(wavelengths,failure_rate_channelwise ,35,plotJob.color,'Marker','.');
|
%scatter(wavelengths,failure_rate_channelwise ,35,plotJob.color,'Marker','.');
|
||||||
|
|
||||||
ylabel('Failure Rate of Link');
|
ylabel('Failure Rate of Link');
|
||||||
xlabel('Wavelength in nm');
|
xlabel('Wavelength in nm');
|
||||||
|
|
||||||
xlim([min(wavelengths),max(wavelengths) ]);
|
xlim([min(wavelengths),max(wavelengths) ]);
|
||||||
ylim([0,1]);
|
ylim([0,1]);
|
||||||
|
|
||||||
grid minor;
|
grid minor;
|
||||||
set(gca, 'color', 'none');
|
set(gca, 'color', 'none');
|
||||||
legend = [];
|
legend = [];
|
||||||
|
|
||||||
% fontsize(AxesMain,8,"points")
|
% fontsize(AxesMain,8,"points")
|
||||||
|
|
||||||
fig.Position = plotJob.Position;
|
fig.Position = plotJob.Position;
|
||||||
fig.Units = "centimeters";
|
fig.Units = "centimeters";
|
||||||
fig.Position = [0 0 12 5 7];
|
fig.Position = [0 0 12 5 7];
|
||||||
|
|
||||||
try
|
try
|
||||||
set(AxesMain,'TickLabelInterpreter','latex')
|
set(AxesMain,'TickLabelInterpreter','latex')
|
||||||
|
|
||||||
set(AxesMain.Legend,'Interpreter','latex')
|
set(AxesMain.Legend,'Interpreter','latex')
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function vec = removeZeros(vec)
|
function vec = removeZeros(vec)
|
||||||
% Find rows that contain only zeros
|
% Find rows that contain only zeros
|
||||||
rows_to_remove = all(vec == 0, 2);
|
rows_to_remove = all(vec == 0, 2);
|
||||||
|
|
||||||
% Remove rows with only zeros
|
% Remove rows with only zeros
|
||||||
vec(rows_to_remove, :) = [];
|
vec(rows_to_remove, :) = [];
|
||||||
end
|
end
|
||||||
@@ -1,51 +1,51 @@
|
|||||||
function plotChannelSpacingAna(wh,plotJob)
|
function plotChannelSpacingAna(wh,plotJob)
|
||||||
|
|
||||||
xAxis = wh.parameter.p_out.values;
|
xAxis = wh.parameter.p_out.values;
|
||||||
|
|
||||||
|
|
||||||
realization = wh.parameter.realization.values(1:end);
|
realization = wh.parameter.realization.values(1:end);
|
||||||
|
|
||||||
channelsp = wh.parameter.channelspacing.values(1:end);
|
channelsp = wh.parameter.channelspacing.values(1:end);
|
||||||
channelsp = [200 400].*1e9;
|
channelsp = [200 400].*1e9;
|
||||||
for ch = 1:2
|
for ch = 1:2
|
||||||
channspacing = channelsp(ch);
|
channspacing = channelsp(ch);
|
||||||
for xl = 1:numel(xAxis)
|
for xl = 1:numel(xAxis)
|
||||||
p_out = xAxis(xl);
|
p_out = xAxis(xl);
|
||||||
|
|
||||||
curber = wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.numchannels,channspacing);
|
curber = wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.numchannels,channspacing);
|
||||||
curzdw = wh.getStoValue('zdw',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.numchannels,channspacing);
|
curzdw = wh.getStoValue('zdw',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.numchannels,channspacing);
|
||||||
|
|
||||||
ber(1:size(curber,1),1:size(curber,2),xl) = curber;
|
ber(1:size(curber,1),1:size(curber,2),xl) = curber;
|
||||||
zdw(1:size(curber,1),1,xl) = curzdw;
|
zdw(1:size(curber,1),1,xl) = curzdw;
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
ber = squeeze(mean(ber,1));
|
ber = squeeze(mean(ber,1));
|
||||||
zdw = squeeze(mean(zdw,1));
|
zdw = squeeze(mean(zdw,1));
|
||||||
|
|
||||||
hdfec = 3.8e-3.*ones(size(xAxis));
|
hdfec = 3.8e-3.*ones(size(xAxis));
|
||||||
S = [];
|
S = [];
|
||||||
wavelength={};
|
wavelength={};
|
||||||
|
|
||||||
zdw_ = [];
|
zdw_ = [];
|
||||||
zdw_chann = [];
|
zdw_chann = [];
|
||||||
zdw_tot = [];
|
zdw_tot = [];
|
||||||
S = [];
|
S = [];
|
||||||
S_chann = [];
|
S_chann = [];
|
||||||
wl = round([1302.03471732576,1304.30061112288,1306.57440520904,1308.85614097425,1311.14586009814,1313.44360455251,1315.74941660391,1318.06333881618],2);
|
wl = round([1302.03471732576,1304.30061112288,1306.57440520904,1308.85614097425,1311.14586009814,1313.44360455251,1315.74941660391,1318.06333881618],2);
|
||||||
wl = 1:16;
|
wl = 1:16;
|
||||||
wl = [1.2930 1.2953 1.2975 1.2998 1.3020 1.3043 1.3066 1.3089 1.3111 1.3134 1.3157 1.3181 1.3204 1.3227 1.3251 1.3274];
|
wl = [1.2930 1.2953 1.2975 1.2998 1.3020 1.3043 1.3066 1.3089 1.3111 1.3134 1.3157 1.3181 1.3204 1.3227 1.3251 1.3274];
|
||||||
|
|
||||||
|
|
||||||
a = InterX([hdfec(:)';xAxis],[mean(ber,1);xAxis]);
|
a = InterX([hdfec(:)';xAxis],[mean(ber,1);xAxis]);
|
||||||
if ~isempty(a)
|
if ~isempty(a)
|
||||||
s(ch) = a(2);
|
s(ch) = a(2);
|
||||||
else
|
else
|
||||||
s(ch) = NaN;
|
s(ch) = NaN;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
figure(2224)
|
figure(2224)
|
||||||
hold on
|
hold on
|
||||||
plot(channelsp,s,'LineWidth',1,'Color',plotJob.color,'Marker','o');
|
plot(channelsp,s,'LineWidth',1,'Color',plotJob.color,'Marker','o');
|
||||||
|
|
||||||
@@ -1,294 +1,294 @@
|
|||||||
function plotCurve(wh,plotJob)
|
function plotCurve(wh,plotJob)
|
||||||
%PLOTCURVE Summary of this function goes here
|
%PLOTCURVE Summary of this function goes here
|
||||||
% Detailed explanation goes here
|
% Detailed explanation goes here
|
||||||
|
|
||||||
fig = findall(groot, 'Type', 'figure', 'Name', plotJob.figName);
|
fig = findall(groot, 'Type', 'figure', 'Name', plotJob.figName);
|
||||||
|
|
||||||
if isvalid(fig)
|
if isvalid(fig)
|
||||||
figure(fig)
|
figure(fig)
|
||||||
% fig = get(fig);
|
% fig = get(fig);
|
||||||
AxesMain = fig.CurrentAxes;
|
AxesMain = fig.CurrentAxes;
|
||||||
hold on
|
hold on
|
||||||
else
|
else
|
||||||
fig = figure('name',char(plotJob.figName));
|
fig = figure('name',char(plotJob.figName));
|
||||||
AxesMain = gca;
|
AxesMain = gca;
|
||||||
hold on
|
hold on
|
||||||
end
|
end
|
||||||
|
|
||||||
col = plotJob.color;
|
col = plotJob.color;
|
||||||
|
|
||||||
% we want to fetch all realizations
|
% we want to fetch all realizations
|
||||||
if plotJob.pmd == 0
|
if plotJob.pmd == 0
|
||||||
realization = 499;
|
realization = 499;
|
||||||
% realization = 0:7;
|
% realization = 0:7;
|
||||||
else
|
else
|
||||||
realization = wh.parameter.realization.values(1:end);
|
realization = wh.parameter.realization.values(1:end);
|
||||||
end
|
end
|
||||||
realization = wh.parameter.realization.values(1:end);
|
realization = wh.parameter.realization.values(1:end);
|
||||||
% get all xAxis values
|
% get all xAxis values
|
||||||
xAxis = wh.parameter.p_out.values;
|
xAxis = wh.parameter.p_out.values;
|
||||||
|
|
||||||
markerstyle = 'o';
|
markerstyle = 'o';
|
||||||
linestyle = '-';
|
linestyle = '-';
|
||||||
|
|
||||||
% Fetch Data from Warehouse
|
% Fetch Data from Warehouse
|
||||||
for xl = 1:numel(xAxis)
|
for xl = 1:numel(xAxis)
|
||||||
p_out = xAxis(xl);
|
p_out = xAxis(xl);
|
||||||
if string(plotJob.dataStatArg) == "Worst"
|
if string(plotJob.dataStatArg) == "Worst"
|
||||||
temp = wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.ch,1310,plotJob.channelspacing,plotJob.randzdw);
|
temp = wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.ch,1310,plotJob.channelspacing,plotJob.randzdw);
|
||||||
temp = removeZeros(temp);
|
temp = removeZeros(temp);
|
||||||
ber(xl) = quantile(temp,0.9,"all");
|
ber(xl) = quantile(temp,0.9,"all");
|
||||||
% ber(xl) = max(temp,[],'all');
|
% ber(xl) = max(temp,[],'all');
|
||||||
linew = 1.0;
|
linew = 1.0;
|
||||||
markersz = plotJob.markersize;
|
markersz = plotJob.markersize;
|
||||||
markerstyle = plotJob.markerstyle;
|
markerstyle = plotJob.markerstyle;
|
||||||
linestyle = plotJob.linestyle;
|
linestyle = plotJob.linestyle;
|
||||||
|
|
||||||
elseif string(plotJob.dataStatArg) == "AVG"
|
elseif string(plotJob.dataStatArg) == "AVG"
|
||||||
temp = wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.ch,1310,plotJob.channelspacing,plotJob.randzdw);
|
temp = wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.ch,1310,plotJob.channelspacing,plotJob.randzdw);
|
||||||
temp = removeZeros(temp);
|
temp = removeZeros(temp);
|
||||||
ber(xl) = mean(temp,'all');
|
ber(xl) = mean(temp,'all');
|
||||||
linew = 1.0;
|
linew = 1.0;
|
||||||
markersz = plotJob.markersize;
|
markersz = plotJob.markersize;
|
||||||
markerstyle = plotJob.markerstyle;
|
markerstyle = plotJob.markerstyle;
|
||||||
linestyle = plotJob.linestyle;
|
linestyle = plotJob.linestyle;
|
||||||
|
|
||||||
elseif string(plotJob.dataStatArg) == "Best"
|
elseif string(plotJob.dataStatArg) == "Best"
|
||||||
temp = wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.ch,1310,plotJob.channelspacing,plotJob.randzdw);
|
temp = wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.ch,1310,plotJob.channelspacing,plotJob.randzdw);
|
||||||
temp = removeZeros(temp);
|
temp = removeZeros(temp);
|
||||||
ber(xl) = min(temp,[],'all');
|
ber(xl) = min(temp,[],'all');
|
||||||
linew = 1.0;
|
linew = 1.0;
|
||||||
markersz = plotJob.markersize;
|
markersz = plotJob.markersize;
|
||||||
markerstyle = plotJob.markerstyle;
|
markerstyle = plotJob.markerstyle;
|
||||||
linestyle = plotJob.linestyle;
|
linestyle = plotJob.linestyle;
|
||||||
|
|
||||||
elseif string(plotJob.dataStatArg) == "All Channels; mean(PMD Realizations)"
|
elseif string(plotJob.dataStatArg) == "All Channels; mean(PMD Realizations)"
|
||||||
temp = wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.ch,1310,plotJob.channelspacing,plotJob.randzdw);
|
temp = wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.ch,1310,plotJob.channelspacing,plotJob.randzdw);
|
||||||
temp = removeZeros(temp);
|
temp = removeZeros(temp);
|
||||||
|
|
||||||
ber(:,xl) = mean(temp,1,"omitnan").';
|
ber(:,xl) = mean(temp,1,"omitnan").';
|
||||||
|
|
||||||
linew = 1;
|
linew = 1;
|
||||||
markersz = 1;
|
markersz = 1;
|
||||||
markerstyle = plotJob.markerstyle;
|
markerstyle = plotJob.markerstyle;
|
||||||
linestyle = plotJob.linestyle;
|
linestyle = plotJob.linestyle;
|
||||||
|
|
||||||
elseif string(plotJob.dataStatArg) == "Lineplot with quartiles"
|
elseif string(plotJob.dataStatArg) == "Lineplot with quartiles"
|
||||||
|
|
||||||
temp = wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.ch,1310,plotJob.channelspacing,plotJob.randzdw);
|
temp = wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.ch,1310,plotJob.channelspacing,plotJob.randzdw);
|
||||||
temp = removeZeros(temp);
|
temp = removeZeros(temp);
|
||||||
ber(xl) = mean(temp,"all","omitnan").';
|
ber(xl) = mean(temp,"all","omitnan").';
|
||||||
|
|
||||||
|
|
||||||
upperq(xl) = quantile(temp,0.99,"all");
|
upperq(xl) = quantile(temp,0.99,"all");
|
||||||
lowerq(xl) = quantile(temp,0.04,"all");
|
lowerq(xl) = quantile(temp,0.04,"all");
|
||||||
|
|
||||||
|
|
||||||
% upperq(xl) = 0.5*std(tmp,1,'all','omitnan');
|
% upperq(xl) = 0.5*std(tmp,1,'all','omitnan');
|
||||||
% lowerq(xl) = 0.5*std(tmp,1,'all','omitnan');
|
% lowerq(xl) = 0.5*std(tmp,1,'all','omitnan');
|
||||||
|
|
||||||
upperq(xl) = max(temp(:));
|
upperq(xl) = max(temp(:));
|
||||||
lowerq(xl) = min(temp(:));
|
lowerq(xl) = min(temp(:));
|
||||||
|
|
||||||
if lowerq(xl) == 0
|
if lowerq(xl) == 0
|
||||||
lowerq(xl) = 1e-8;
|
lowerq(xl) = 1e-8;
|
||||||
end
|
end
|
||||||
|
|
||||||
% upperq(xl) = mean(tmp,"all","omitnan") + 1.96 * (std(tmp,1,'all','omitnan')/sqrt(numel(tmp)));
|
% upperq(xl) = mean(tmp,"all","omitnan") + 1.96 * (std(tmp,1,'all','omitnan')/sqrt(numel(tmp)));
|
||||||
% lowerq(xl) = mean(tmp,"all","omitnan") - 1.96 * (std(tmp,1,'all','omitnan')/sqrt(numel(tmp)));
|
% lowerq(xl) = mean(tmp,"all","omitnan") - 1.96 * (std(tmp,1,'all','omitnan')/sqrt(numel(tmp)));
|
||||||
|
|
||||||
linew = 1;
|
linew = 1;
|
||||||
markersz = 1;
|
markersz = 1;
|
||||||
linestyle = '-';
|
linestyle = '-';
|
||||||
|
|
||||||
elseif string(plotJob.dataStatArg) == "All Channels ;All PMD Realizations"
|
elseif string(plotJob.dataStatArg) == "All Channels ;All PMD Realizations"
|
||||||
|
|
||||||
raw_fetch = wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.ch,1310,plotJob.channelspacing,plotJob.randzdw).';
|
raw_fetch = wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.ch,1310,plotJob.channelspacing,plotJob.randzdw).';
|
||||||
tmp = reshape(raw_fetch,[],1);
|
tmp = reshape(raw_fetch,[],1);
|
||||||
ber(1:size(tmp,1),xl) = tmp;
|
ber(1:size(tmp,1),xl) = tmp;
|
||||||
|
|
||||||
ber_per_chann(:,:,xl) = raw_fetch;
|
ber_per_chann(:,:,xl) = raw_fetch;
|
||||||
|
|
||||||
linew = 0.3;
|
linew = 0.3;
|
||||||
markersz = 2;
|
markersz = 2;
|
||||||
linestyle = ':';
|
linestyle = ':';
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
%routine to remove total outliers (here those wehere the rop curve has a mean BER greater than 0.1)
|
%routine to remove total outliers (here those wehere the rop curve has a mean BER greater than 0.1)
|
||||||
% ber_per_chann_clean = NaN(size(ber_per_chann));
|
% ber_per_chann_clean = NaN(size(ber_per_chann));
|
||||||
% for ch = 1:size(ber_per_chann,1)
|
% for ch = 1:size(ber_per_chann,1)
|
||||||
% bla = squeeze(ber_per_chann(ch,:,:));
|
% bla = squeeze(ber_per_chann(ch,:,:));
|
||||||
% ber_per_chann(ch,find(mean(bla,2)>0.25),:) = NaN;
|
% ber_per_chann(ch,find(mean(bla,2)>0.25),:) = NaN;
|
||||||
% cleaned = rmoutliers(bla,"mean",'ThresholdFactor',2);
|
% cleaned = rmoutliers(bla,"mean",'ThresholdFactor',2);
|
||||||
%
|
%
|
||||||
% ber_per_chann_clean(ch,1:size(cleaned,1),1:size(cleaned,2)) = cleaned;
|
% ber_per_chann_clean(ch,1:size(cleaned,1),1:size(cleaned,2)) = cleaned;
|
||||||
%
|
%
|
||||||
% end
|
% end
|
||||||
%
|
%
|
||||||
% ber = [];
|
% ber = [];
|
||||||
% for rop = 1:size(ber_per_chann,3)
|
% for rop = 1:size(ber_per_chann,3)
|
||||||
% temp = squeeze(ber_per_chann_clean(:,:,rop));
|
% temp = squeeze(ber_per_chann_clean(:,:,rop));
|
||||||
% ber(rop) = mean(temp,"all","omitnan").';
|
% ber(rop) = mean(temp,"all","omitnan").';
|
||||||
% upperq(rop) = quantile(temp,0.9,"all");
|
% upperq(rop) = quantile(temp,0.9,"all");
|
||||||
% lowerq(rop) = quantile(temp,0.1,"all");
|
% lowerq(rop) = quantile(temp,0.1,"all");
|
||||||
% end
|
% end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
xAxis = xAxis;
|
xAxis = xAxis;
|
||||||
|
|
||||||
% Plot Data
|
% Plot Data
|
||||||
if string(plotJob.plotTypeArg) == "Scatter"
|
if string(plotJob.plotTypeArg) == "Scatter"
|
||||||
for rlz = 1:size(ber,1)
|
for rlz = 1:size(ber,1)
|
||||||
|
|
||||||
if rlz < size(ber,1)
|
if rlz < size(ber,1)
|
||||||
scatter(xAxis,ber(rlz,:),markersz,'MarkerEdgeColor',col,'MarkerFaceColor',col,'Parent', AxesMain(1),'HandleVisibility','off');
|
scatter(xAxis,ber(rlz,:),markersz,'MarkerEdgeColor',col,'MarkerFaceColor',col,'Parent', AxesMain(1),'HandleVisibility','off');
|
||||||
else
|
else
|
||||||
scatter(xAxis,ber(rlz,:),markersz,'MarkerEdgeColor',col,'MarkerFaceColor',col,'Parent', AxesMain(1),'DisplayName',[plotJob.dataStatArg,' Ch.: ', plotJob.displayname]);
|
scatter(xAxis,ber(rlz,:),markersz,'MarkerEdgeColor',col,'MarkerFaceColor',col,'Parent', AxesMain(1),'DisplayName',[plotJob.dataStatArg,' Ch.: ', plotJob.displayname]);
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif string(plotJob.plotTypeArg) == "Lines"
|
elseif string(plotJob.plotTypeArg) == "Lines"
|
||||||
|
|
||||||
% if ~anynan(ber)
|
% if ~anynan(ber)
|
||||||
% [xAxis,ber] = interpCurve(xAxis, ber);
|
% [xAxis,ber] = interpCurve(xAxis, ber);
|
||||||
% end
|
% end
|
||||||
|
|
||||||
cols = cbrewer2('RdBu',size(ber,1));
|
cols = cbrewer2('RdBu',size(ber,1));
|
||||||
for rlz = 1:size(ber,1)
|
for rlz = 1:size(ber,1)
|
||||||
%
|
%
|
||||||
if (string(plotJob.dataStatArg) == "All Channels ;All PMD Realizations")||(string(plotJob.dataStatArg) == "All Channels; mean(PMD Realizations)")
|
if (string(plotJob.dataStatArg) == "All Channels ;All PMD Realizations")||(string(plotJob.dataStatArg) == "All Channels; mean(PMD Realizations)")
|
||||||
ch = mod(rlz,plotJob.ch);
|
ch = mod(rlz,plotJob.ch);
|
||||||
if ch == 0; ch = plotJob.ch; end
|
if ch == 0; ch = plotJob.ch; end
|
||||||
else
|
else
|
||||||
ch = plotJob.dataStatArg;
|
ch = plotJob.dataStatArg;
|
||||||
end
|
end
|
||||||
|
|
||||||
if rlz < size(ber,1)
|
if rlz < size(ber,1)
|
||||||
|
|
||||||
col = cols(rlz,:);
|
col = cols(rlz,:);
|
||||||
|
|
||||||
s = plot(xAxis,ber(rlz,:),linestyle,'Marker',"none",'MarkerSize',markersz,'LineWidth',linew,'Color',col,'Parent', AxesMain,'HandleVisibility','off');
|
s = plot(xAxis,ber(rlz,:),linestyle,'Marker',"none",'MarkerSize',markersz,'LineWidth',linew,'Color',col,'Parent', AxesMain,'HandleVisibility','off');
|
||||||
|
|
||||||
s.DataTipTemplate.Interpreter = "latex";
|
s.DataTipTemplate.Interpreter = "latex";
|
||||||
s.DataTipTemplate.DataTipRows(1).Label = "Ch: ";
|
s.DataTipTemplate.DataTipRows(1).Label = "Ch: ";
|
||||||
s.DataTipTemplate.DataTipRows(1).Value = repmat(ch,size(ber));
|
s.DataTipTemplate.DataTipRows(1).Value = repmat(ch,size(ber));
|
||||||
s.DataTipTemplate.DataTipRows(1);
|
s.DataTipTemplate.DataTipRows(1);
|
||||||
s.DataTipTemplate.DataTipRows(2) = [];
|
s.DataTipTemplate.DataTipRows(2) = [];
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
if string(plotJob.dataStatArg) == "Lineplot with quartiles"
|
if string(plotJob.dataStatArg) == "Lineplot with quartiles"
|
||||||
|
|
||||||
[hl,hp] = boundedline(xAxis,ber(rlz,:),([(ber(rlz,:)-lowerq(rlz,:));upperq(rlz,:)-ber(rlz,:)]'),'-o','alpha','Color',col,'transparency', 0.06,'linewidth',0.7);
|
[hl,hp] = boundedline(xAxis,ber(rlz,:),([(ber(rlz,:)-lowerq(rlz,:));upperq(rlz,:)-ber(rlz,:)]'),'-o','alpha','Color',col,'transparency', 0.06,'linewidth',0.7);
|
||||||
hl.MarkerFaceColor = col;
|
hl.MarkerFaceColor = col;
|
||||||
hl.MarkerSize = 2;
|
hl.MarkerSize = 2;
|
||||||
set(hp,'HandleVisibility','off');
|
set(hp,'HandleVisibility','off');
|
||||||
%hp.LineWidth = 1.2;
|
%hp.LineWidth = 1.2;
|
||||||
|
|
||||||
ho = outlinebounds(hl,hp);
|
ho = outlinebounds(hl,hp);
|
||||||
set(ho, 'linestyle', ':', 'color', col,'Linewidth',0.6);
|
set(ho, 'linestyle', ':', 'color', col,'Linewidth',0.6);
|
||||||
set(ho,'HandleVisibility','off');
|
set(ho,'HandleVisibility','off');
|
||||||
|
|
||||||
% errorbar(xAxis,ber(rlz,:),ber(rlz,:)-lowerq(rlz,:),upperq(rlz,:)-ber(rlz,:),'-o','Color',col,'linewidth',0.7);
|
% errorbar(xAxis,ber(rlz,:),ber(rlz,:)-lowerq(rlz,:),upperq(rlz,:)-ber(rlz,:),'-o','Color',col,'linewidth',0.7);
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
s = plot(xAxis,ber(rlz,:),linestyle,'Marker',markerstyle,'MarkerFaceColor',col,'MarkerSize',markersz,'LineWidth',linew,'Color',col,'Parent', AxesMain,'DisplayName',[plotJob.displayname]);
|
s = plot(xAxis,ber(rlz,:),linestyle,'Marker',markerstyle,'MarkerFaceColor',col,'MarkerSize',markersz,'LineWidth',linew,'Color',col,'Parent', AxesMain,'DisplayName',[plotJob.displayname]);
|
||||||
|
|
||||||
s.DataTipTemplate.Interpreter = "latex";
|
s.DataTipTemplate.Interpreter = "latex";
|
||||||
s.DataTipTemplate.DataTipRows(1).Label = "Ch: ";
|
s.DataTipTemplate.DataTipRows(1).Label = "Ch: ";
|
||||||
s.DataTipTemplate.DataTipRows(1).Value = repmat(string(ch),size(ber));
|
s.DataTipTemplate.DataTipRows(1).Value = repmat(string(ch),size(ber));
|
||||||
s.DataTipTemplate.DataTipRows(1)
|
s.DataTipTemplate.DataTipRows(1)
|
||||||
s.DataTipTemplate.DataTipRows(2) = [];
|
s.DataTipTemplate.DataTipRows(2) = [];
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
% Draw FEC Threshold Line
|
% Draw FEC Threshold Line
|
||||||
%get x data of first children:
|
%get x data of first children:
|
||||||
%get all linear Values
|
%get all linear Values
|
||||||
if 0
|
if 0
|
||||||
linear = wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,wh.parameter.p_out.values,0,0,499,"symmetric");
|
linear = wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,wh.parameter.p_out.values,0,0,499,"symmetric");
|
||||||
linear = mean(linear,2);
|
linear = mean(linear,2);
|
||||||
lincurve = findall(AxesMain, 'Type', 'line','DisplayName','Linear Baseline');
|
lincurve = findall(AxesMain, 'Type', 'line','DisplayName','Linear Baseline');
|
||||||
%
|
%
|
||||||
if isempty(lincurve)
|
if isempty(lincurve)
|
||||||
xdata = AxesMain.Children(1).XData;
|
xdata = AxesMain.Children(1).XData;
|
||||||
hdfec = 3.8e-3.*ones(size(xdata));
|
hdfec = 3.8e-3.*ones(size(xdata));
|
||||||
plot(xdata,linear,'-','Marker',"o",'MarkerSize',3,'LineWidth',4,'Color',[0.6400 0.6400 0.6400],'MarkerFaceColor',[0.6400 0.6400 0.6400],'Parent', AxesMain,'DisplayName','Linear Baseline');
|
plot(xdata,linear,'-','Marker',"o",'MarkerSize',3,'LineWidth',4,'Color',[0.6400 0.6400 0.6400],'MarkerFaceColor',[0.6400 0.6400 0.6400],'Parent', AxesMain,'DisplayName','Linear Baseline');
|
||||||
%h = get(gca,'Children');
|
%h = get(gca,'Children');
|
||||||
%set(gca,'Children',[h(2) h(1)])
|
%set(gca,'Children',[h(2) h(1)])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
feccurve = findall(AxesMain, 'Type', 'line','DisplayName','FEC $3.8*10^{-3}$');
|
feccurve = findall(AxesMain, 'Type', 'line','DisplayName','FEC $3.8*10^{-3}$');
|
||||||
%
|
%
|
||||||
if isempty(feccurve)
|
if isempty(feccurve)
|
||||||
xdata = AxesMain.Children(1).XData;
|
xdata = AxesMain.Children(1).XData;
|
||||||
hdfec = 3.8e-3.*ones(size(xdata));
|
hdfec = 3.8e-3.*ones(size(xdata));
|
||||||
plot(xdata,hdfec,'--','MarkerSize',4,'Color','black','MarkerFaceColor','black','LineWidth',1,'Parent', AxesMain,'DisplayName','FEC $3.8*10^{-3}$','HandleVisibility','off');
|
plot(xdata,hdfec,'--','MarkerSize',4,'Color','black','MarkerFaceColor','black','LineWidth',1,'Parent', AxesMain,'DisplayName','FEC $3.8*10^{-3}$','HandleVisibility','off');
|
||||||
%h = get(gca,'Children');
|
%h = get(gca,'Children');
|
||||||
%set(gca,'Children',[h(2) h(1)])
|
%set(gca,'Children',[h(2) h(1)])
|
||||||
end
|
end
|
||||||
|
|
||||||
% Figure Settings
|
% Figure Settings
|
||||||
%title(AxesMain,plotJob.title,"Interpreter","none");
|
%title(AxesMain,plotJob.title,"Interpreter","none");
|
||||||
|
|
||||||
xlabel(AxesMain,plotJob.xAxisLabel,"Interpreter","latex");
|
xlabel(AxesMain,plotJob.xAxisLabel,"Interpreter","latex");
|
||||||
|
|
||||||
ylabel(AxesMain,plotJob.yAxisLabel,"Interpreter","latex");
|
ylabel(AxesMain,plotJob.yAxisLabel,"Interpreter","latex");
|
||||||
|
|
||||||
set(AxesMain,'yscale','log');
|
set(AxesMain,'yscale','log');
|
||||||
|
|
||||||
grid(AxesMain,'on');
|
grid(AxesMain,'on');
|
||||||
|
|
||||||
grid(AxesMain,'minor');
|
grid(AxesMain,'minor');
|
||||||
|
|
||||||
grid minor
|
grid minor
|
||||||
|
|
||||||
%legend(AxesMain);
|
%legend(AxesMain);
|
||||||
|
|
||||||
fontsize(AxesMain,8,"points")
|
fontsize(AxesMain,8,"points")
|
||||||
% fontname(AxesMain,"Arial")
|
% fontname(AxesMain,"Arial")
|
||||||
|
|
||||||
|
|
||||||
% fig.Position = plotJob.Position;
|
% fig.Position = plotJob.Position;
|
||||||
% fig.Units = "centimeters";
|
% fig.Units = "centimeters";
|
||||||
% fig.Position = [2 2 8.5 7];
|
% fig.Position = [2 2 8.5 7];
|
||||||
|
|
||||||
set(AxesMain,'TickLabelInterpreter','latex')
|
set(AxesMain,'TickLabelInterpreter','latex')
|
||||||
|
|
||||||
set(AxesMain.Legend,'Interpreter','latex')
|
set(AxesMain.Legend,'Interpreter','latex')
|
||||||
% set(gcf,'Units','centimeters')
|
% set(gcf,'Units','centimeters')
|
||||||
% set(gcf,'Position',[2 2 9 4.5])
|
% set(gcf,'Position',[2 2 9 4.5])
|
||||||
|
|
||||||
ylim([1e-5,0.3]);
|
ylim([1e-5,0.3]);
|
||||||
|
|
||||||
xlim([-10,-4]);
|
xlim([-10,-4]);
|
||||||
|
|
||||||
|
|
||||||
% annotation('textbox', [0.125, 0.32, 0.1, 0.1], 'String', "FEC 3.8e-3","LineStyle","none","FontSize",8,"FontUnits","points")
|
% annotation('textbox', [0.125, 0.32, 0.1, 0.1], 'String', "FEC 3.8e-3","LineStyle","none","FontSize",8,"FontUnits","points")
|
||||||
|
|
||||||
|
|
||||||
hold off
|
hold off
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function vec = removeZeros(vec)
|
function vec = removeZeros(vec)
|
||||||
% Find rows that contain only zeros
|
% Find rows that contain only zeros
|
||||||
rows_to_remove = all(vec == 0, 2);
|
rows_to_remove = all(vec == 0, 2);
|
||||||
|
|
||||||
% Remove rows with only zeros
|
% Remove rows with only zeros
|
||||||
vec(rows_to_remove, :) = [];
|
vec(rows_to_remove, :) = [];
|
||||||
end
|
end
|
||||||
@@ -1,151 +1,151 @@
|
|||||||
function plotHistogram(wh,plotJob)
|
function plotHistogram(wh,plotJob)
|
||||||
|
|
||||||
|
|
||||||
fig = findall(groot, 'Type', 'figure', 'Name', plotJob.figName);
|
fig = findall(groot, 'Type', 'figure', 'Name', plotJob.figName);
|
||||||
|
|
||||||
if isvalid(fig)
|
if isvalid(fig)
|
||||||
figure(fig)
|
figure(fig)
|
||||||
fig = get(fig);
|
fig = get(fig);
|
||||||
AxesMain = fig.CurrentAxes;
|
AxesMain = fig.CurrentAxes;
|
||||||
hold on
|
hold on
|
||||||
else
|
else
|
||||||
fig = figure('name',char(plotJob.figName));
|
fig = figure('name',char(plotJob.figName));
|
||||||
AxesMain = gca;
|
AxesMain = gca;
|
||||||
hold on
|
hold on
|
||||||
end
|
end
|
||||||
|
|
||||||
col = plotJob.color;
|
col = plotJob.color;
|
||||||
|
|
||||||
% we want to fetch all realizations
|
% we want to fetch all realizations
|
||||||
realization = wh.parameter.realization.values(1:end);
|
realization = wh.parameter.realization.values(1:end);
|
||||||
|
|
||||||
% get all xAxis values
|
% get all xAxis values
|
||||||
xAxis = wh.parameter.p_out.values;
|
xAxis = wh.parameter.p_out.values;
|
||||||
|
|
||||||
|
|
||||||
% Fetch Data from Warehouse
|
% Fetch Data from Warehouse
|
||||||
for xl = 1:numel(xAxis)
|
for xl = 1:numel(xAxis)
|
||||||
p_out = xAxis(xl);
|
p_out = xAxis(xl);
|
||||||
if string(plotJob.dataStatArg) == "Worst"
|
if string(plotJob.dataStatArg) == "Worst"
|
||||||
ber(xl) = max(wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,string(plotJob.channelplan),string(plotJob.dsp)),[],'all');
|
ber(xl) = max(wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,string(plotJob.channelplan),string(plotJob.dsp)),[],'all');
|
||||||
linew = 2.0;
|
linew = 2.0;
|
||||||
markersz = 3;
|
markersz = 3;
|
||||||
linestyle = '-';
|
linestyle = '-';
|
||||||
elseif string(plotJob.dataStatArg) == "AVG"
|
elseif string(plotJob.dataStatArg) == "AVG"
|
||||||
ber(xl) = mean(wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,string(plotJob.channelplan),string(plotJob.dsp)),'all');
|
ber(xl) = mean(wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,string(plotJob.channelplan),string(plotJob.dsp)),'all');
|
||||||
linew = 2.0;
|
linew = 2.0;
|
||||||
markersz = 3;
|
markersz = 3;
|
||||||
linestyle = ':';
|
linestyle = ':';
|
||||||
elseif string(plotJob.dataStatArg) == "Best"
|
elseif string(plotJob.dataStatArg) == "Best"
|
||||||
ber(xl) = min(wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,string(plotJob.channelplan),string(plotJob.dsp)),[],'all');
|
ber(xl) = min(wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,string(plotJob.channelplan),string(plotJob.dsp)),[],'all');
|
||||||
linew = 2.0;
|
linew = 2.0;
|
||||||
markersz = 3;
|
markersz = 3;
|
||||||
linestyle = ':';
|
linestyle = ':';
|
||||||
|
|
||||||
elseif string(plotJob.dataStatArg) == "All Channels; mean(PMD Realizations)"
|
elseif string(plotJob.dataStatArg) == "All Channels; mean(PMD Realizations)"
|
||||||
tmp = wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,string(plotJob.channelplan),string(plotJob.dsp));
|
tmp = wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,string(plotJob.channelplan),string(plotJob.dsp));
|
||||||
|
|
||||||
if numel(tmp(tmp==0)) ~= 0
|
if numel(tmp(tmp==0)) ~= 0
|
||||||
disp('Removed all zero values!');
|
disp('Removed all zero values!');
|
||||||
tmp(tmp==0) = NaN;
|
tmp(tmp==0) = NaN;
|
||||||
end
|
end
|
||||||
ber(:,xl) = mean(tmp,1,"omitnan").';
|
ber(:,xl) = mean(tmp,1,"omitnan").';
|
||||||
|
|
||||||
linew = 0.7;
|
linew = 0.7;
|
||||||
markersz = 2;
|
markersz = 2;
|
||||||
linestyle = '-';
|
linestyle = '-';
|
||||||
|
|
||||||
elseif string(plotJob.dataStatArg) == "All Channels ;All PMD Realizations"
|
elseif string(plotJob.dataStatArg) == "All Channels ;All PMD Realizations"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
tmp = reshape(wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,string(plotJob.channelplan),string(plotJob.dsp)).',[],1);
|
tmp = reshape(wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,string(plotJob.channelplan),string(plotJob.dsp)).',[],1);
|
||||||
ber(1:size(tmp,1),xl) = tmp;
|
ber(1:size(tmp,1),xl) = tmp;
|
||||||
|
|
||||||
linew = 0.3;
|
linew = 0.3;
|
||||||
markersz = 2;
|
markersz = 2;
|
||||||
linestyle = ':';
|
linestyle = ':';
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
disp('Removed all zero values!');
|
disp('Removed all zero values!');
|
||||||
ber(ber==0) = NaN;
|
ber(ber==0) = NaN;
|
||||||
if ~anynan(ber)
|
if ~anynan(ber)
|
||||||
[xAxis,ber] = interpCurve(xAxis, ber);
|
[xAxis,ber] = interpCurve(xAxis, ber);
|
||||||
end
|
end
|
||||||
|
|
||||||
% plot FEC Crossing as histogram
|
% plot FEC Crossing as histogram
|
||||||
|
|
||||||
hdfec = 3.8e-3.*ones(size(xAxis));
|
hdfec = 3.8e-3.*ones(size(xAxis));
|
||||||
S = [];
|
S = [];
|
||||||
for i = 1:size(ber,1)
|
for i = 1:size(ber,1)
|
||||||
a = InterX([hdfec;xAxis],[ber(i,:);xAxis]);
|
a = InterX([hdfec;xAxis],[ber(i,:);xAxis]);
|
||||||
if ~isempty(a)
|
if ~isempty(a)
|
||||||
S(:,i) = a;
|
S(:,i) = a;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
%% SUB 1
|
%% SUB 1
|
||||||
AxesMain = subplot(2,1,1);
|
AxesMain = subplot(2,1,1);
|
||||||
|
|
||||||
hold on
|
hold on
|
||||||
|
|
||||||
if ~isempty(S)
|
if ~isempty(S)
|
||||||
histogram(S(end,:),300,'Normalization','probability','FaceColor',col,'EdgeColor',col,'Parent',AxesMain,'DisplayName',[plotJob.dataStatArg,' Ch.: ', plotJob.displayname],'FaceAlpha',0.4,'EdgeAlpha',0.4);
|
histogram(S(end,:),300,'Normalization','probability','FaceColor',col,'EdgeColor',col,'Parent',AxesMain,'DisplayName',[plotJob.dataStatArg,' Ch.: ', plotJob.displayname],'FaceAlpha',0.4,'EdgeAlpha',0.4);
|
||||||
end
|
end
|
||||||
|
|
||||||
xlim([-3 ,9 ]);
|
xlim([-3 ,9 ]);
|
||||||
ylim([0 .10]);
|
ylim([0 .10]);
|
||||||
|
|
||||||
% Figure Settings
|
% Figure Settings
|
||||||
title(AxesMain,['$P_{in}:$ ',num2str(plotJob.p_in-9), 'dBm; L : ', num2str(plotJob.l),'Km'],'Interpreter','latex');
|
title(AxesMain,['$P_{in}:$ ',num2str(plotJob.p_in-9), 'dBm; L : ', num2str(plotJob.l),'Km'],'Interpreter','latex');
|
||||||
|
|
||||||
xlabel(AxesMain,plotJob.xAxisLabel,'Interpreter','latex');
|
xlabel(AxesMain,plotJob.xAxisLabel,'Interpreter','latex');
|
||||||
|
|
||||||
ylabel('PDF')
|
ylabel('PDF')
|
||||||
|
|
||||||
grid(AxesMain,'on');
|
grid(AxesMain,'on');
|
||||||
|
|
||||||
grid(AxesMain,'minor');
|
grid(AxesMain,'minor');
|
||||||
|
|
||||||
%legend(AxesMain,'Interpreter','latex');
|
%legend(AxesMain,'Interpreter','latex');
|
||||||
|
|
||||||
fontsize(AxesMain,24,"pixels")
|
fontsize(AxesMain,24,"pixels")
|
||||||
|
|
||||||
hold off
|
hold off
|
||||||
|
|
||||||
|
|
||||||
%% SUB 2
|
%% SUB 2
|
||||||
AxesMain = subplot(2,1,2);
|
AxesMain = subplot(2,1,2);
|
||||||
|
|
||||||
if ~isempty(S)
|
if ~isempty(S)
|
||||||
hold on
|
hold on
|
||||||
|
|
||||||
[f1,x1]=ecdf(S(end,:));
|
[f1,x1]=ecdf(S(end,:));
|
||||||
plot(x1,f1,'r','LineWidth',3, 'Color',col,'DisplayName',[plotJob.dataStatArg,' Ch.: ', plotJob.displayname]);
|
plot(x1,f1,'r','LineWidth',3, 'Color',col,'DisplayName',[plotJob.dataStatArg,' Ch.: ', plotJob.displayname]);
|
||||||
end
|
end
|
||||||
xlim([-3 ,9 ]);
|
xlim([-3 ,9 ]);
|
||||||
ylim([0 1]);
|
ylim([0 1]);
|
||||||
% Figure Settings
|
% Figure Settings
|
||||||
title(AxesMain,['$P_{in}:$ ',num2str(plotJob.p_in-9), 'dBm; L : ', num2str(plotJob.l),'Km'],'Interpreter','latex');
|
title(AxesMain,['$P_{in}:$ ',num2str(plotJob.p_in-9), 'dBm; L : ', num2str(plotJob.l),'Km'],'Interpreter','latex');
|
||||||
|
|
||||||
xlabel(AxesMain,plotJob.xAxisLabel,'Interpreter','latex');
|
xlabel(AxesMain,plotJob.xAxisLabel,'Interpreter','latex');
|
||||||
|
|
||||||
ylabel('CDF')
|
ylabel('CDF')
|
||||||
|
|
||||||
grid(AxesMain,'on');
|
grid(AxesMain,'on');
|
||||||
|
|
||||||
grid(AxesMain,'minor');
|
grid(AxesMain,'minor');
|
||||||
|
|
||||||
fontsize(AxesMain,24,"pixels")
|
fontsize(AxesMain,24,"pixels")
|
||||||
|
|
||||||
%legend(AxesMain,'Interpreter','latex');
|
%legend(AxesMain,'Interpreter','latex');
|
||||||
|
|
||||||
fig.Position = plotJob.Position;
|
fig.Position = plotJob.Position;
|
||||||
|
|
||||||
hold off
|
hold off
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -1,206 +1,206 @@
|
|||||||
function plotViolin(wh,plotJob)
|
function plotViolin(wh,plotJob)
|
||||||
|
|
||||||
fig = findall(groot, 'Type', 'figure', 'Name', plotJob.figName);
|
fig = findall(groot, 'Type', 'figure', 'Name', plotJob.figName);
|
||||||
|
|
||||||
if isvalid(fig)
|
if isvalid(fig)
|
||||||
figure(fig)
|
figure(fig)
|
||||||
fig = get(fig);
|
fig = get(fig);
|
||||||
AxesMain = fig.CurrentAxes;
|
AxesMain = fig.CurrentAxes;
|
||||||
hold on
|
hold on
|
||||||
else
|
else
|
||||||
fig = figure('name',char(plotJob.figName));
|
fig = figure('name',char(plotJob.figName));
|
||||||
AxesMain = gca;
|
AxesMain = gca;
|
||||||
hold on
|
hold on
|
||||||
end
|
end
|
||||||
|
|
||||||
%% Violin
|
%% Violin
|
||||||
col = plotJob.color;
|
col = plotJob.color;
|
||||||
|
|
||||||
% we want to fetch all realizations
|
% we want to fetch all realizations
|
||||||
if plotJob.pmd == 0
|
if plotJob.pmd == 0
|
||||||
realization = 1;
|
realization = 1;
|
||||||
else
|
else
|
||||||
realization = wh.parameter.realization.values(1:end);
|
realization = wh.parameter.realization.values(1:end);
|
||||||
end
|
end
|
||||||
|
|
||||||
%realization = 0:8;
|
%realization = 0:8;
|
||||||
|
|
||||||
% get all xAxis values
|
% get all xAxis values
|
||||||
xAxis = wh.parameter.p_out.values;
|
xAxis = wh.parameter.p_out.values;
|
||||||
|
|
||||||
% ber = NaN(500,16,10);
|
% ber = NaN(500,16,10);
|
||||||
% zdw = NaN(500,1,10);
|
% zdw = NaN(500,1,10);
|
||||||
|
|
||||||
%get BER values for query
|
%get BER values for query
|
||||||
for xl = 1:numel(xAxis)
|
for xl = 1:numel(xAxis)
|
||||||
p_out = xAxis(xl);
|
p_out = xAxis(xl);
|
||||||
|
|
||||||
curber = wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.ch,1310,plotJob.channelspacing,plotJob.randzdw);
|
curber = wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.ch,1310,plotJob.channelspacing,plotJob.randzdw);
|
||||||
curber= removeZeros(curber);
|
curber= removeZeros(curber);
|
||||||
ber(1:size(curber,1),1:size(curber,2),xl) = curber;
|
ber(1:size(curber,1),1:size(curber,2),xl) = curber;
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
% to remove outliers set the percentile range
|
% to remove outliers set the percentile range
|
||||||
% a = squeeze(mean(ber,2));
|
% a = squeeze(mean(ber,2));
|
||||||
% out = isoutlier(mean(a,2),"percentiles",[0 100]);
|
% out = isoutlier(mean(a,2),"percentiles",[0 100]);
|
||||||
% ber = ber(~out,:,:);
|
% ber = ber(~out,:,:);
|
||||||
% disp(sum(out));
|
% disp(sum(out));
|
||||||
|
|
||||||
hdfec = 3.8e-3.*ones(size(xAxis));
|
hdfec = 3.8e-3.*ones(size(xAxis));
|
||||||
S = [];
|
S = [];
|
||||||
wavelength={};
|
wavelength={};
|
||||||
|
|
||||||
|
|
||||||
S = [];
|
S = [];
|
||||||
S_chann = [];
|
S_chann = [];
|
||||||
|
|
||||||
wl = calcWavelengthPlan(plotJob.ch,plotJob.channelspacing,1310);
|
wl = calcWavelengthPlan(plotJob.ch,plotJob.channelspacing,1310);
|
||||||
%get fec thresholds
|
%get fec thresholds
|
||||||
% [C,ia,ib] =intersect(linx,xAxis);
|
% [C,ia,ib] =intersect(linx,xAxis);
|
||||||
% linear = squeeze(linear);
|
% linear = squeeze(linear);
|
||||||
|
|
||||||
%ber(ber==0) = NaN;
|
%ber(ber==0) = NaN;
|
||||||
S_chann_no_crossing = zeros(1,plotJob.ch);
|
S_chann_no_crossing = zeros(1,plotJob.ch);
|
||||||
for chann = 1:size(ber,2)
|
for chann = 1:size(ber,2)
|
||||||
|
|
||||||
for realiz = 1:size(ber,1)
|
for realiz = 1:size(ber,1)
|
||||||
|
|
||||||
ber_series = squeeze(ber(realiz,chann,:)).';
|
ber_series = squeeze(ber(realiz,chann,:)).';
|
||||||
if mean(ber_series) > 0.1
|
if mean(ber_series) > 0.1
|
||||||
continue
|
continue
|
||||||
end
|
end
|
||||||
|
|
||||||
a = InterX([hdfec(:)';xAxis],[ber_series;xAxis]);
|
a = InterX([hdfec(:)';xAxis],[ber_series;xAxis]);
|
||||||
|
|
||||||
if ~isempty(a)
|
if ~isempty(a)
|
||||||
S_chann(realiz,chann) = a(2);
|
S_chann(realiz,chann) = a(2);
|
||||||
% if a(2) > -7 && string(plotJob.pol) == "copolarized"
|
% if a(2) > -7 && string(plotJob.pol) == "copolarized"
|
||||||
% continue
|
% continue
|
||||||
% end
|
% end
|
||||||
S(end+1) = a(2);
|
S(end+1) = a(2);
|
||||||
wavelength{end+1} = num2str(wl(chann));
|
wavelength{end+1} = num2str(wl(chann));
|
||||||
else
|
else
|
||||||
S(end+1) = 0;
|
S(end+1) = 0;
|
||||||
wavelength{end+1} = num2str(wl(chann));
|
wavelength{end+1} = num2str(wl(chann));
|
||||||
S_chann_no_crossing(realiz,chann) = 1;
|
S_chann_no_crossing(realiz,chann) = 1;
|
||||||
S_chann(realiz,chann) = -1;
|
S_chann(realiz,chann) = -1;
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
threshold = -6;
|
threshold = -6;
|
||||||
FEC_crossed = sum(S_chann < threshold & ~isnan(S_chann),1);
|
FEC_crossed = sum(S_chann < threshold & ~isnan(S_chann),1);
|
||||||
FEC_not_crossed = sum(S_chann >= threshold & ~isnan(S_chann),1);
|
FEC_not_crossed = sum(S_chann >= threshold & ~isnan(S_chann),1);
|
||||||
failure_rate = FEC_not_crossed ./ (FEC_crossed + FEC_not_crossed) ;
|
failure_rate = FEC_not_crossed ./ (FEC_crossed + FEC_not_crossed) ;
|
||||||
|
|
||||||
|
|
||||||
S_chann(S_chann==0) = NaN;
|
S_chann(S_chann==0) = NaN;
|
||||||
|
|
||||||
total_avg = mean(S_chann,"all","omitnan");
|
total_avg = mean(S_chann,"all","omitnan");
|
||||||
|
|
||||||
%figure(2024)
|
%figure(2024)
|
||||||
%C = flip(cbrewer2('Spectral',8));
|
%C = flip(cbrewer2('Spectral',8));
|
||||||
if numel(S) <= numel(wl)
|
if numel(S) <= numel(wl)
|
||||||
vs = scatter(1:numel(S),S,50,'o','MarkerEdgeColor','black','MarkerFaceColor',plotJob.color,'LineWidth',1,'HandleVisibility','off');
|
vs = scatter(1:numel(S),S,50,'o','MarkerEdgeColor','black','MarkerFaceColor',plotJob.color,'LineWidth',1,'HandleVisibility','off');
|
||||||
%vs = scatter(1,mean(S),50,'o','MarkerEdgeColor','black','MarkerFaceColor',plotJob.color,'LineWidth',1);
|
%vs = scatter(1,mean(S),50,'o','MarkerEdgeColor','black','MarkerFaceColor',plotJob.color,'LineWidth',1);
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
vs = violinplot(S,wavelength,...
|
vs = violinplot(S,wavelength,...
|
||||||
'ViolinColor',plotJob.color,...
|
'ViolinColor',plotJob.color,...
|
||||||
'ViolinAlpha',0.1,...
|
'ViolinAlpha',0.1,...
|
||||||
'MarkerSize',1,...
|
'MarkerSize',1,...
|
||||||
'ShowMedian',false,...
|
'ShowMedian',false,...
|
||||||
'EdgeColor',plotJob.color,...
|
'EdgeColor',plotJob.color,...
|
||||||
'ShowWhiskers',false,...
|
'ShowWhiskers',false,...
|
||||||
'ShowData',false,...
|
'ShowData',false,...
|
||||||
'ShowBox',false,...
|
'ShowBox',false,...
|
||||||
'Bandwidth',0.051 ...
|
'Bandwidth',0.051 ...
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
hold on
|
hold on
|
||||||
|
|
||||||
partly_failed = boolean(ceil(failure_rate));
|
partly_failed = boolean(ceil(failure_rate));
|
||||||
|
|
||||||
avg = mean(S_chann,1,"omitnan");
|
avg = mean(S_chann,1,"omitnan");
|
||||||
|
|
||||||
notfailed = ~partly_failed .* avg;
|
notfailed = ~partly_failed .* avg;
|
||||||
notfailed(notfailed==0) = NaN;
|
notfailed(notfailed==0) = NaN;
|
||||||
scatter(1:size(S_chann,2),notfailed,10,'Marker','x','MarkerEdgeColor','black','MarkerFaceColor',plotJob.color,'LineWidth',0.5,'HandleVisibility','off');
|
scatter(1:size(S_chann,2),notfailed,10,'Marker','x','MarkerEdgeColor','black','MarkerFaceColor',plotJob.color,'LineWidth',0.5,'HandleVisibility','off');
|
||||||
|
|
||||||
|
|
||||||
hold on
|
hold on
|
||||||
partly_failed = partly_failed.*avg;
|
partly_failed = partly_failed.*avg;
|
||||||
partly_failed(partly_failed==0) = NaN;
|
partly_failed(partly_failed==0) = NaN;
|
||||||
s=scatter(1:numel(failure_rate),partly_failed,10,'Marker','x','LineWidth',0.5,'HandleVisibility','off','MarkerEdgeColor','red');
|
s=scatter(1:numel(failure_rate),partly_failed,10,'Marker','x','LineWidth',0.5,'HandleVisibility','off','MarkerEdgeColor','red');
|
||||||
s.DataTipTemplate.Interpreter = "latex";
|
s.DataTipTemplate.Interpreter = "latex";
|
||||||
s.DataTipTemplate.DataTipRows(1).Label = "Fail Rate: ";
|
s.DataTipTemplate.DataTipRows(1).Label = "Fail Rate: ";
|
||||||
s.DataTipTemplate.DataTipRows(1).Value = failure_rate;
|
s.DataTipTemplate.DataTipRows(1).Value = failure_rate;
|
||||||
s.DataTipTemplate.DataTipRows(2) = [];
|
s.DataTipTemplate.DataTipRows(2) = [];
|
||||||
hold off
|
hold off
|
||||||
end
|
end
|
||||||
|
|
||||||
% ax = gca;
|
% ax = gca;
|
||||||
% ax.XTicks
|
% ax.XTicks
|
||||||
|
|
||||||
hold on
|
hold on
|
||||||
yline(total_avg,'LineWidth',1,'LineStyle','--','DisplayName','System Avg.')
|
yline(total_avg,'LineWidth',1,'LineStyle','--','DisplayName','System Avg.')
|
||||||
fig.Position = plotJob.Position;
|
fig.Position = plotJob.Position;
|
||||||
|
|
||||||
xticklabels(1:16);
|
xticklabels(1:16);
|
||||||
ylabel('Penalty in dB');
|
ylabel('Penalty in dB');
|
||||||
xlabel('Channel Number');
|
xlabel('Channel Number');
|
||||||
ylim([-9.3,-3]);
|
ylim([-9.3,-3]);
|
||||||
xlim([0,plotJob.ch+1]);
|
xlim([0,plotJob.ch+1]);
|
||||||
% grid minor;
|
% grid minor;
|
||||||
set(gca, 'color', 'none');
|
set(gca, 'color', 'none');
|
||||||
legend = [];
|
legend = [];
|
||||||
|
|
||||||
fontsize(AxesMain,8,"points")
|
fontsize(AxesMain,8,"points")
|
||||||
|
|
||||||
fig.Position = plotJob.Position;
|
fig.Position = plotJob.Position;
|
||||||
fig.Units = "centimeters";
|
fig.Units = "centimeters";
|
||||||
fig.Position = [2 2 8.5 7];
|
fig.Position = [2 2 8.5 7];
|
||||||
|
|
||||||
set(AxesMain,'TickLabelInterpreter','latex')
|
set(AxesMain,'TickLabelInterpreter','latex')
|
||||||
|
|
||||||
set(AxesMain.Legend,'Interpreter','latex')
|
set(AxesMain.Legend,'Interpreter','latex')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if 0
|
if 0
|
||||||
ber_sorted = sort(S);
|
ber_sorted = sort(S);
|
||||||
|
|
||||||
z1 = [];
|
z1 = [];
|
||||||
penalty = mean(ber_sorted):0.01:mean(ber_sorted)+2;
|
penalty = mean(ber_sorted):0.01:mean(ber_sorted)+2;
|
||||||
|
|
||||||
for i = 1:length(penalty)
|
for i = 1:length(penalty)
|
||||||
l = penalty(i);
|
l = penalty(i);
|
||||||
if i == 1
|
if i == 1
|
||||||
z1 = [z1 sum(ber_sorted(1,:)<l ) / length(ber_sorted) ];
|
z1 = [z1 sum(ber_sorted(1,:)<l ) / length(ber_sorted) ];
|
||||||
else
|
else
|
||||||
z1 = [z1 sum(ber_sorted(1,:)<l & ber_sorted(1,:)>l-0.01) / length(ber_sorted) ];
|
z1 = [z1 sum(ber_sorted(1,:)<l & ber_sorted(1,:)>l-0.01) / length(ber_sorted) ];
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
penalty_higherthan = 0.5;
|
penalty_higherthan = 0.5;
|
||||||
probability = sum(z1(find(penalty>mean(ber_sorted)+penalty_higherthan)));
|
probability = sum(z1(find(penalty>mean(ber_sorted)+penalty_higherthan)));
|
||||||
disp(['A penalty of more than 0.5 dB has a probability of: ', num2str(probability)]);
|
disp(['A penalty of more than 0.5 dB has a probability of: ', num2str(probability)]);
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function vec = removeZeros(vec)
|
function vec = removeZeros(vec)
|
||||||
% Find rows that contain only zeros
|
% Find rows that contain only zeros
|
||||||
rows_to_remove = all(vec == 0, 2);
|
rows_to_remove = all(vec == 0, 2);
|
||||||
|
|
||||||
% Remove rows with only zeros
|
% Remove rows with only zeros
|
||||||
vec(rows_to_remove, :) = [];
|
vec(rows_to_remove, :) = [];
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -1,58 +1,58 @@
|
|||||||
|
|
||||||
%automate plots
|
%automate plots
|
||||||
% [file, path] = uigetfile("C:\Users\Silas\Documents\MATLAB\Raw_Cluster_Simulations\session_januar24\wh_complete_at_1310.mat");
|
% [file, path] = uigetfile("C:\Users\Silas\Documents\MATLAB\Raw_Cluster_Simulations\session_januar24\wh_complete_at_1310.mat");
|
||||||
% wh = load([path filesep file]);
|
% wh = load([path filesep file]);
|
||||||
% wh = wh.wh;
|
% wh = wh.wh;
|
||||||
|
|
||||||
plotJob = struct();
|
plotJob = struct();
|
||||||
|
|
||||||
plotJob.l = 10;
|
plotJob.l = 10;
|
||||||
plotJob.ch = 16;
|
plotJob.ch = 16;
|
||||||
plotJob.d = 3;
|
plotJob.d = 3;
|
||||||
plotJob.sgm = 1;
|
plotJob.sgm = 1;
|
||||||
plotJob.pol = "copolarized";
|
plotJob.pol = "copolarized";
|
||||||
plotJob.p_in = 3;
|
plotJob.p_in = 3;
|
||||||
plotJob.gamma = 0.0023;
|
plotJob.gamma = 0.0023;
|
||||||
plotJob.pmd = 0.1;
|
plotJob.pmd = 0.1;
|
||||||
plotJob.channelspacing = 400e9;
|
plotJob.channelspacing = 400e9;
|
||||||
plotJob.randzdw = 0;
|
plotJob.randzdw = 0;
|
||||||
|
|
||||||
ber_per_chann = [];
|
ber_per_chann = [];
|
||||||
% get all xAxis values
|
% get all xAxis values
|
||||||
xAxis = wh.parameter.p_out.values;
|
xAxis = wh.parameter.p_out.values;
|
||||||
realization = wh.parameter.realization.values(1:end);
|
realization = wh.parameter.realization.values(1:end);
|
||||||
% Fetch Data from Warehouse
|
% Fetch Data from Warehouse
|
||||||
for xl = 1:numel(xAxis)
|
for xl = 1:numel(xAxis)
|
||||||
p_out = xAxis(xl);
|
p_out = xAxis(xl);
|
||||||
raw_fetch = wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.ch,1310,plotJob.channelspacing,plotJob.randzdw).';
|
raw_fetch = wh.getStoValue('ber',plotJob.l,plotJob.d,plotJob.sgm,string(plotJob.pol),plotJob.p_in,p_out,plotJob.pmd,plotJob.gamma,realization,plotJob.ch,1310,plotJob.channelspacing,plotJob.randzdw).';
|
||||||
|
|
||||||
ber_per_chann(:,:,xl) = raw_fetch;
|
ber_per_chann(:,:,xl) = raw_fetch;
|
||||||
end
|
end
|
||||||
%%
|
%%
|
||||||
|
|
||||||
figure(2023);
|
figure(2023);
|
||||||
|
|
||||||
for ch = [1,floor(plotJob.ch/2),ceil(plotJob.ch/2)+1,plotJob.ch] %1:15:size(ber_per_chann,1)
|
for ch = [1,floor(plotJob.ch/2),ceil(plotJob.ch/2)+1,plotJob.ch] %1:15:size(ber_per_chann,1)
|
||||||
|
|
||||||
for p = 5%1:size(ber_per_chann,3)
|
for p = 5%1:size(ber_per_chann,3)
|
||||||
|
|
||||||
% Extract data for the current row
|
% Extract data for the current row
|
||||||
row_data = squeeze(ber_per_chann(ch,:,p));
|
row_data = squeeze(ber_per_chann(ch,:,p));
|
||||||
[f, xi] = ksdensity(row_data);
|
[f, xi] = ksdensity(row_data);
|
||||||
% Identify the peak point
|
% Identify the peak point
|
||||||
[max_density, max_index] = max(f);
|
[max_density, max_index] = max(f);
|
||||||
peak_x = xi(max_index);
|
peak_x = xi(max_index);
|
||||||
|
|
||||||
end
|
end
|
||||||
% Create a histogram plot for the current row with a unique color
|
% Create a histogram plot for the current row with a unique color
|
||||||
plot(xi, f, 'LineWidth', 2, 'DisplayName', ['Ch. ', num2str(ch)],'LineStyle','--');
|
plot(xi, f, 'LineWidth', 2, 'DisplayName', ['Ch. ', num2str(ch)],'LineStyle','--');
|
||||||
%histogram(row_data,100, 'DisplayName', ['Channel ', num2str(ch)], 'EdgeColor', 'none');
|
%histogram(row_data,100, 'DisplayName', ['Channel ', num2str(ch)], 'EdgeColor', 'none');
|
||||||
|
|
||||||
hold on; % Hold the plot for the next iteration
|
hold on; % Hold the plot for the next iteration
|
||||||
text(peak_x, max_density, ['Ch ', num2str(ch)], 'VerticalAlignment', 'bottom', 'HorizontalAlignment', 'left');
|
text(peak_x, max_density, ['Ch ', num2str(ch)], 'VerticalAlignment', 'bottom', 'HorizontalAlignment', 'left');
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
legend show
|
legend show
|
||||||
|
|
||||||
%%
|
%%
|
||||||
@@ -8,6 +8,7 @@ classdef equalizer_structure < int32
|
|||||||
% db_precoded (3)
|
% db_precoded (3)
|
||||||
vnle_db_mlse (4)
|
vnle_db_mlse (4)
|
||||||
db_encoded (5)
|
db_encoded (5)
|
||||||
|
ml_mlse (6)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -13,14 +13,13 @@ arguments
|
|||||||
end
|
end
|
||||||
|
|
||||||
try
|
try
|
||||||
|
|
||||||
|
|
||||||
% Initialize output structures
|
% Initialize output structures
|
||||||
output.ffe_package = {};
|
output.ffe_package = {};
|
||||||
output.mlse_package = {};
|
output.mlse_package = {};
|
||||||
output.vnle_package = {};
|
output.vnle_package = {};
|
||||||
output.dbtgt_package = {};
|
output.dbtgt_package = {};
|
||||||
output.dbenc_package = {};
|
output.dbenc_package = {};
|
||||||
|
output.mlmlse_package = {};
|
||||||
|
|
||||||
if options.mode == "load_run_id" || options.append_to_db
|
if options.mode == "load_run_id" || options.append_to_db
|
||||||
% Initialize database connection
|
% Initialize database connection
|
||||||
@@ -98,9 +97,10 @@ try
|
|||||||
|
|
||||||
use_ffe = 0;
|
use_ffe = 0;
|
||||||
use_dfe = 0;
|
use_dfe = 0;
|
||||||
use_vnle_mlse = 1;
|
use_vnle_mlse = 0;
|
||||||
use_dbtgt = 0;
|
use_dbtgt = 0;
|
||||||
use_dbenc = 0;
|
use_dbenc = 0;
|
||||||
|
use_ml_mlse = 1;
|
||||||
|
|
||||||
addProcessingResultToDatabase = 0;
|
addProcessingResultToDatabase = 0;
|
||||||
|
|
||||||
@@ -130,7 +130,7 @@ try
|
|||||||
mlse_ = MLSE("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels);
|
mlse_ = MLSE("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels);
|
||||||
|
|
||||||
eq_post = FFE("epochs_tr",5,"epochs_dd",5,"len_tr",4096*2,"mu_dd",1e-4,"mu_tr",0,"order",2001,"sps",1,"decide",0,"adaption_technique","lms");
|
eq_post = FFE("epochs_tr",5,"epochs_dd",5,"len_tr",4096*2,"mu_dd",1e-4,"mu_tr",0,"order",2001,"sps",1,"decide",0,"adaption_technique","lms");
|
||||||
eq_post =FFE("epochs_tr",5,"epochs_dd",2,"len_tr",2^13,"mu_dd",mu_dd,"mu_tr",mu_tr,"order",25,"sps",2,"decide",0, "adaption",adaption_method(adaption),"dd_mode",use_dd_mode);
|
eq_post = FFE("epochs_tr",5,"epochs_dd",2,"len_tr",2^13,"mu_dd",mu_dd,"mu_tr",mu_tr,"order",25,"sps",2,"decide",0, "adaption",adaption_method(adaption),"dd_mode",use_dd_mode);
|
||||||
% Duobinary signaling (db encoded)
|
% Duobinary signaling (db encoded)
|
||||||
mlse_db_enc = MLSE("DIR", [1,1], "duobinary_output", 0, "M", M, "trellis_states", PAMmapper(M,0).levels);
|
mlse_db_enc = MLSE("DIR", [1,1], "duobinary_output", 0, "M", M, "trellis_states", PAMmapper(M,0).levels);
|
||||||
eq_db_enc = EQ("Ne", ffe_order, "Nb", dfe_order, "training_length", len_tr, ...
|
eq_db_enc = EQ("Ne", ffe_order, "Nb", dfe_order, "training_length", len_tr, ...
|
||||||
@@ -233,30 +233,25 @@ try
|
|||||||
database.addProcessingResult(run_id, ffe_results.metrics, ffe_results.config);
|
database.addProcessingResult(run_id, ffe_results.metrics, ffe_results.config);
|
||||||
end
|
end
|
||||||
|
|
||||||
% pf_ncoeffs = 2;
|
end
|
||||||
% eq_ = EQ("Ne",ffe_order,"Nb",dfe_order,"training_length",len_tr,"training_loops",5,"dd_loops",5,"K",2,"DCmu",mu_dc,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",1);
|
|
||||||
% pf_ = Postfilter("ncoeff",pf_ncoeffs,"useBurg",1);
|
if use_ml_mlse
|
||||||
% % mlse_ = MLSE_viterbi("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels);
|
|
||||||
% mlse_ = MLSE("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels);
|
%ML-based MLSE (L=2)
|
||||||
%
|
mu_ml = 0.01; training_epochs = 250;
|
||||||
% [ffe_results, mlse_results] = vnle_postfilter_mlse(eq_, pf_, mlse_, M, Scpe_sig, Symbols, Tx_bits, ...
|
ml_mlse_equalizer = ML_MLSE("epochs_tr",training_epochs,"epochs_dd",1, ...
|
||||||
% "precode_mode", duob_mode,...
|
"len_tr",length(Scpe_sig),"mu_dd",mu_ml,"mu_tr",mu_ml,"order",11,"sps",2, ...
|
||||||
% 'showAnalysis', 0, ...
|
"traceback_depth",128,"L",2,"delta",4,"adaptive_mu",0);
|
||||||
% "postFFE", [],...
|
|
||||||
% "eth_style_symbol_mapping", 0);
|
[ml_mlse_results] = ml_mlse(ml_mlse_equalizer, M, Scpe_sig, Symbols, Tx_bits,"precode_mode",duob_mode);
|
||||||
%
|
output.mlmlse_package{r} = ml_mlse_results;
|
||||||
% ffe_results.metrics.print;
|
|
||||||
% mlse_results.metrics.print;
|
if options.append_to_db
|
||||||
%
|
database.addProcessingResult(run_id, ml_mlse_results.metrics, ml_mlse_results.config);
|
||||||
% output.mlse_package{r} = mlse_results;
|
end
|
||||||
% output.vnle_package{r} = ffe_results;
|
|
||||||
%
|
|
||||||
% if options.append_to_db
|
|
||||||
% database.addProcessingResult(run_id, mlse_results.metrics, mlse_results.config);
|
|
||||||
% database.addProcessingResult(run_id, ffe_results.metrics, ffe_results.config);
|
|
||||||
% end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
if use_dbtgt
|
if use_dbtgt
|
||||||
|
|
||||||
@@ -292,6 +287,7 @@ try
|
|||||||
|
|
||||||
if duob_mode == db_mode.db_encoded
|
if duob_mode == db_mode.db_encoded
|
||||||
|
|
||||||
|
mlse_db_enc = MLSE_viterbi("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels);
|
||||||
db_results = duobinary_signaling(eq_db_enc, mlse_db_enc, M, Scpe_sig, Symbols, Tx_bits, "precode_mode",duob_mode, "showAnalysis",0,"postFFE",[]);
|
db_results = duobinary_signaling(eq_db_enc, mlse_db_enc, M, Scpe_sig, Symbols, Tx_bits, "precode_mode",duob_mode, "showAnalysis",0,"postFFE",[]);
|
||||||
output.dbenc_package{r} = db_results;
|
output.dbenc_package{r} = db_results;
|
||||||
if options.append_to_db
|
if options.append_to_db
|
||||||
|
|||||||
@@ -36,8 +36,9 @@ if ~isempty(options.postFFE)
|
|||||||
end
|
end
|
||||||
|
|
||||||
% Process through MLSE
|
% Process through MLSE
|
||||||
% [mlse_signal] = mlse_.process(eq_signal);
|
[mlse_signal] = mlse_.process(eq_signal);
|
||||||
[mlse_signal,~,GMI_MLSE] = mlse_.process(eq_signal,tx_symbols);
|
% tx_symbols_ = Duobinary().decode(tx_symbols);
|
||||||
|
% [mlse_signal,~,GMI_MLSE] = mlse_.process(eq_signal,tx_symbols);
|
||||||
|
|
||||||
% Apply duobinary encoding and decoding
|
% Apply duobinary encoding and decoding
|
||||||
mlse_signal = Duobinary().encode(mlse_signal);
|
mlse_signal = Duobinary().encode(mlse_signal);
|
||||||
|
|||||||
113
Functions/EQ_structures/ml_mlse.m
Normal file
113
Functions/EQ_structures/ml_mlse.m
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
function [ml_mlse_results] = ml_mlse(eq_, M, rx_signal, tx_symbols, tx_bits, options)
|
||||||
|
%
|
||||||
|
%
|
||||||
|
% Inputs:
|
||||||
|
% eq_ - Equalizer object
|
||||||
|
% M - Modulation order
|
||||||
|
% rx_signal - Received signal
|
||||||
|
% tx_symbols - Transmitted symbols
|
||||||
|
% tx_bits - Transmitted bits
|
||||||
|
% options - Optional parameters
|
||||||
|
%
|
||||||
|
% Outputs:
|
||||||
|
% ffe_results - Results from FFE processing
|
||||||
|
|
||||||
|
arguments
|
||||||
|
eq_
|
||||||
|
M
|
||||||
|
rx_signal
|
||||||
|
tx_symbols
|
||||||
|
tx_bits
|
||||||
|
options.precode_mode db_mode
|
||||||
|
options.eth_style_symbol_mapping = 0;
|
||||||
|
options.postFFE = [];
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Process signals through equalizer
|
||||||
|
|
||||||
|
[eq_signal_hd,y_ref] = eq_.process(rx_signal,tx_symbols);
|
||||||
|
|
||||||
|
%% Calculate BER based on precoding mode
|
||||||
|
[bits, errors, ber, error_pos, errors_precoded, ber_precoded] = calculateBER(eq_signal_hd, tx_symbols, tx_bits, options.precode_mode, M, options.eth_style_symbol_mapping);
|
||||||
|
|
||||||
|
|
||||||
|
% Create FFE results structure
|
||||||
|
ml_mlse_results = struct();
|
||||||
|
try
|
||||||
|
eq_.e = [];
|
||||||
|
eq_.e2 = [];
|
||||||
|
eq_.e3 = [];
|
||||||
|
eq_.b = [];
|
||||||
|
eq_.b2 = [];
|
||||||
|
eq_.b3 = [];
|
||||||
|
end
|
||||||
|
|
||||||
|
ml_mlse_results.config = Equalizerstruct();
|
||||||
|
ml_mlse_results.config.eq = jsonencode(eq_);
|
||||||
|
ml_mlse_results.config.equalizer_structure = int32(equalizer_structure.ml_mlse);
|
||||||
|
ml_mlse_results.config.comment = 'function: ML-based MLSE';
|
||||||
|
|
||||||
|
ml_mlse_results.metrics = Metricstruct;
|
||||||
|
ml_mlse_results.metrics.result_id = NaN;
|
||||||
|
ml_mlse_results.metrics.run_id = NaN;
|
||||||
|
ml_mlse_results.metrics.eqParam_id = NaN;
|
||||||
|
ml_mlse_results.metrics.date_of_processing = datetime('now');
|
||||||
|
ml_mlse_results.metrics.BER = ber;
|
||||||
|
ml_mlse_results.metrics.numBits = bits;
|
||||||
|
ml_mlse_results.metrics.numBitErr = errors;
|
||||||
|
ml_mlse_results.metrics.BER_precoded = ber_precoded;
|
||||||
|
ml_mlse_results.metrics.numBitErr_precoded = errors_precoded;
|
||||||
|
ml_mlse_results.metrics.SNR = NaN;
|
||||||
|
ml_mlse_results.metrics.SNR_level = NaN;
|
||||||
|
ml_mlse_results.metrics.STD = NaN;
|
||||||
|
ml_mlse_results.metrics.STD_level = NaN;
|
||||||
|
ml_mlse_results.metrics.STDrx = NaN;
|
||||||
|
ml_mlse_results.metrics.STDrx_level = NaN;
|
||||||
|
ml_mlse_results.metrics.GMI = NaN;
|
||||||
|
ml_mlse_results.metrics.AIR = NaN;
|
||||||
|
ml_mlse_results.metrics.EVM = NaN;
|
||||||
|
ml_mlse_results.metrics.EVM_level = NaN;
|
||||||
|
ml_mlse_results.metrics.Alpha = NaN;
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Helper Functions
|
||||||
|
function [bits, errors, ber, error_pos, errors_precoded, ber_precoded] = calculateBER(eq_signal_hd, tx_symbols, tx_bits, precode_mode, M, eth_style)
|
||||||
|
% Calculate BER based on precoding mode
|
||||||
|
mapper = PAMmapper(M, 0, "eth_style", eth_style);
|
||||||
|
|
||||||
|
switch precode_mode
|
||||||
|
case db_mode.no_db
|
||||||
|
% TX Data is not precoded
|
||||||
|
% A) Emulate diff precoding
|
||||||
|
eq_signal_hd_precoded = Duobinary().encode(eq_signal_hd, "M", M);
|
||||||
|
eq_signal_hd_precoded = Duobinary().decode(eq_signal_hd_precoded, "M", M);
|
||||||
|
|
||||||
|
tx_symbols_precoded = Duobinary().encode(tx_symbols);
|
||||||
|
tx_symbols_precoded = Duobinary().decode(tx_symbols_precoded);
|
||||||
|
|
||||||
|
tx_bits_precoded = mapper.demap(tx_symbols_precoded);
|
||||||
|
|
||||||
|
rx_bits = mapper.demap(eq_signal_hd_precoded);
|
||||||
|
[~, errors_precoded, ber_precoded, ~] = calc_ber(rx_bits.signal, tx_bits_precoded.signal, "skip_front", 30000, "skip_end", 150, "returnErrorLocation", 1);
|
||||||
|
|
||||||
|
% B) Just determine BER
|
||||||
|
rx_bits = mapper.demap(eq_signal_hd);
|
||||||
|
[bits, errors, ber, error_pos] = calc_ber(rx_bits.signal, tx_bits.signal, "skip_front", 30000, "skip_end", 150, "returnErrorLocation", 1);
|
||||||
|
|
||||||
|
case db_mode.db_precoded
|
||||||
|
% Data is precoded on TX side
|
||||||
|
% A) Decode at Rx if no DB targeting was applied
|
||||||
|
eq_signal_hd_decoded = Duobinary().encode(eq_signal_hd, "M", M);
|
||||||
|
eq_signal_hd_decoded = Duobinary().decode(eq_signal_hd_decoded, "M", M);
|
||||||
|
rx_bits_decoded = mapper.demap(eq_signal_hd_decoded);
|
||||||
|
[~, errors_precoded, ber_precoded, ~] = calc_ber(rx_bits_decoded.signal, tx_bits.signal, "skip_front", 30000, "skip_end", 150, "returnErrorLocation", 1);
|
||||||
|
|
||||||
|
% B) Omit the Coding by comparing with demapped TX symbol sequence
|
||||||
|
tx_bits_demapped = mapper.demap(tx_symbols);
|
||||||
|
rx_bits = mapper.demap(eq_signal_hd);
|
||||||
|
[bits, errors, ber, error_pos] = calc_ber(rx_bits.signal, tx_bits_demapped.signal, "skip_front", 30000, "skip_end", 150, "returnErrorLocation", 1);
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
function [eq_, pf_, mlse_, mlse_db_, eq_post] = configureEqualizers(M, len_tr, vnle_order, dfe_order, mu_dc, mu_ffe, mu_dfe, pf_ncoeffs)
|
|
||||||
% CONFIGUREEQUALIZERS Creates and configures equalizer objects
|
|
||||||
%
|
|
||||||
% Inputs:
|
|
||||||
% M - PAM level
|
|
||||||
% len_tr - Training length
|
|
||||||
% vnle_order - Array with orders for VNLE [order1, order2, order3]
|
|
||||||
% dfe_order - Array with orders for DFE
|
|
||||||
% mu_dc - DC adaptation rate
|
|
||||||
% mu_ffe - Array with adaptation rates for FFE [mu1, mu2, mu3]
|
|
||||||
% mu_dfe - Adaptation rate for DFE
|
|
||||||
% pf_ncoeffs - Number of coefficients for postfilter
|
|
||||||
%
|
|
||||||
% Outputs:
|
|
||||||
% eq_ - Configured EQ object
|
|
||||||
% pf_ - Configured Postfilter object
|
|
||||||
% mlse_ - Configured MLSE_viterbi object
|
|
||||||
% mlse_db_ - Configured MLSE_viterbi object for duobinary
|
|
||||||
% eq_post - Configured FFE object for post-processing
|
|
||||||
|
|
||||||
% Configure main equalizer
|
|
||||||
eq_ = EQ("Ne", vnle_order, "Nb", dfe_order, ...
|
|
||||||
"training_length", len_tr, "training_loops", 5, "dd_loops", 5, ...
|
|
||||||
"K", 2, "DCmu", mu_dc, "DDmu", [mu_ffe mu_dfe], ...
|
|
||||||
"DFEmu", 0.005, "FFEmu", 0, "plotfinal", 0, "ideal_dfe", 1);
|
|
||||||
|
|
||||||
% Configure postfilter
|
|
||||||
pf_ = Postfilter("ncoeff", pf_ncoeffs, "useBurg", 1);
|
|
||||||
|
|
||||||
% Configure MLSE objects
|
|
||||||
mlse_ = MLSE_viterbi("duobinary_output", 0, 'M', M, ...
|
|
||||||
'trellis_states', PAMmapper(M,0).levels);
|
|
||||||
mlse_db_ = MLSE_viterbi("DIR", [1,1], "duobinary_output", 0, ...
|
|
||||||
"M", M, "trellis_states", PAMmapper(M,0).levels);
|
|
||||||
|
|
||||||
% Configure post-FFE
|
|
||||||
eq_post = FFE("epochs_tr", 5, "epochs_dd", 5, "len_tr", 4096*2, ...
|
|
||||||
"mu_dd", 1e-4, "mu_tr", 0, "order", 2001, ...
|
|
||||||
"sps", 1, "decide", 0);
|
|
||||||
end
|
|
||||||
@@ -16,9 +16,9 @@ Scpe_sig = Scpe_sig.resample("fs_out", 2*fsym);
|
|||||||
[Scpe_sig, ~] = Scpe_sig.tsynch("reference", Symbols, "fs_ref", fsym, "debug_plots", 0);
|
[Scpe_sig, ~] = Scpe_sig.tsynch("reference", Symbols, "fs_ref", fsym, "debug_plots", 0);
|
||||||
|
|
||||||
% Apply Gaussian filter
|
% Apply Gaussian filter
|
||||||
% Scpe_sig = Filter('filtdegree', 4, "f_cutoff", Symbols.fs.*0.6, ...
|
Scpe_sig = Filter('filtdegree', 4, "f_cutoff", Symbols.fs.*0.6, ...
|
||||||
% "fs", Scpe_sig.fs, "filterType", filtertypes.gaussian, ...
|
"fs", Scpe_sig.fs, "filterType", filtertypes.gaussian, ...
|
||||||
% "active", true).process(Scpe_sig);
|
"active", true).process(Scpe_sig);
|
||||||
|
|
||||||
% Remove DC offset
|
% Remove DC offset
|
||||||
Scpe_sig = Scpe_sig - mean(Scpe_sig.signal);
|
Scpe_sig = Scpe_sig - mean(Scpe_sig.signal);
|
||||||
|
|||||||
@@ -209,6 +209,7 @@ wh = submit_options.wh;
|
|||||||
wh.addValueToStorageByLinIdx(val.vnle_package, 'vnle_package', jobIndex);
|
wh.addValueToStorageByLinIdx(val.vnle_package, 'vnle_package', jobIndex);
|
||||||
wh.addValueToStorageByLinIdx(val.dbtgt_package,'dbtgt_package',jobIndex);
|
wh.addValueToStorageByLinIdx(val.dbtgt_package,'dbtgt_package',jobIndex);
|
||||||
wh.addValueToStorageByLinIdx(val.dbenc_package,'dbenc_package',jobIndex);
|
wh.addValueToStorageByLinIdx(val.dbenc_package,'dbenc_package',jobIndex);
|
||||||
|
wh.addValueToStorageByLinIdx(val.mlmlse_package,'mlmlse_package',jobIndex);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
function p = setupParallelPool(numWorkers, idleTimeout)
|
function p = setupParallelPool(numWorkers, idleTimeout)
|
||||||
|
|||||||
@@ -1,43 +1,97 @@
|
|||||||
function beautifyBERplot(options)
|
function beautifyBERplot(options)
|
||||||
|
% BEAUTIFYBERPLOT Enhances BER-style plots for publication-quality figures.
|
||||||
|
% Supports automatic smoothing and trend-line overlay.
|
||||||
|
%
|
||||||
|
% Usage examples:
|
||||||
|
% beautifyBERplot; % default
|
||||||
|
% beautifyBERplot("polyfit",1); % add polynomial fit
|
||||||
|
% beautifyBERplot("polyfit",1,"fitmethod","pchip") % piecewise cubic fit
|
||||||
|
%
|
||||||
|
% Supported fitmethod options: 'polyfit', 'smoothingspline', 'loess', 'pchip'
|
||||||
|
|
||||||
arguments
|
arguments
|
||||||
options.logscale = 1
|
options.logscale (1,1) logical = 1
|
||||||
|
options.polyfit (1,1) logical = 0
|
||||||
|
options.polyorder (1,1) double = 2
|
||||||
|
options.fitmethod (1,1) string = "polyfit" % choose fit type
|
||||||
end
|
end
|
||||||
% BEAUTIFYBERPLOT Enhances a BER plot for publication-quality figures.
|
|
||||||
|
|
||||||
% Set line properties for all current plot lines
|
% --- find all line objects in current axes
|
||||||
lines = findall(gca, 'Type', 'Line');
|
lines = findall(gca, 'Type', 'Line');
|
||||||
markers = {'o', 's', 'd', '^', 'v', '>', '<', 'p', 'h'}; % Define marker styles
|
markers = {'o', 's', 'd', '^', 'v', '>', '<', 'p', 'h'};
|
||||||
num_markers = length(markers);
|
num_markers = length(markers);
|
||||||
|
|
||||||
|
% --- style all lines consistently
|
||||||
|
for i = 1:length(lines)
|
||||||
|
lines(i).LineWidth = 1.1;
|
||||||
|
lines(i).LineStyle = '-';
|
||||||
|
if string(lines(i).Marker) == "none"
|
||||||
|
lines(i).Marker = markers{mod(i-1, num_markers) + 1};
|
||||||
|
end
|
||||||
|
lines(i).MarkerSize = 4;
|
||||||
|
lines(i).MarkerFaceColor = lines(i).Color;
|
||||||
|
end
|
||||||
|
|
||||||
|
% --- optional smoothing/fitting overlay
|
||||||
|
if options.polyfit
|
||||||
|
hold on
|
||||||
for i = 1:length(lines)
|
for i = 1:length(lines)
|
||||||
lines(i).LineWidth = 1.3; % Thicker line width
|
x = lines(i).XData;
|
||||||
lines(i).LineStyle = '-'; % Solid lines for simplicity
|
y = lines(i).YData;
|
||||||
if string(lines(i).Marker) == "none"
|
valid = isfinite(x) & isfinite(y);
|
||||||
lines(i).Marker = markers{mod(i-1, num_markers) + 1}; % Assign markers cyclically
|
if sum(valid) < options.polyorder + 1
|
||||||
|
continue;
|
||||||
end
|
end
|
||||||
lines(i).MarkerSize = 7; % Marker size
|
|
||||||
lines(i).MarkerFaceColor = lines(i).Color; % Use line color for marker face
|
xf = linspace(min(x(valid)), max(x(valid)), 200);
|
||||||
lines(i).MarkerEdgeColor = 'white';
|
|
||||||
|
% ----- choose fitting method -----
|
||||||
|
switch lower(options.fitmethod)
|
||||||
|
case "polyfit"
|
||||||
|
p = polyfit(x(valid), y(valid), options.polyorder);
|
||||||
|
yf = polyval(p, xf);
|
||||||
|
|
||||||
|
case "smoothingspline"
|
||||||
|
try
|
||||||
|
f = fit(x(valid)', y(valid)', 'smoothingspline');
|
||||||
|
yf = feval(f, xf);
|
||||||
|
catch
|
||||||
|
yf = interp1(x(valid), y(valid), xf, 'pchip');
|
||||||
|
end
|
||||||
|
|
||||||
|
case "loess"
|
||||||
|
yf = smooth(x(valid), y(valid), 0.2, 'loess');
|
||||||
|
yf = interp1(x(valid), yf, xf, 'linear', 'extrap');
|
||||||
|
|
||||||
|
case "pchip"
|
||||||
|
yf = interp1(x(valid), y(valid), xf, 'pchip');
|
||||||
|
|
||||||
|
otherwise
|
||||||
|
warning('Unknown fitmethod "%s". Using polyfit.', options.fitmethod);
|
||||||
|
p = polyfit(x(valid), y(valid), options.polyorder);
|
||||||
|
yf = polyval(p, xf);
|
||||||
|
end
|
||||||
|
|
||||||
|
% --- lightened color for fit overlay
|
||||||
|
lightcol = lines(i).Color + 0.4 * (1 - lines(i).Color);
|
||||||
|
lightcol(lightcol > 1) = 1;
|
||||||
|
|
||||||
|
plot(xf, yf, '-', 'Color', lightcol, ...
|
||||||
|
'LineWidth', 0.7, 'Marker', 'none', ...
|
||||||
|
'HandleVisibility','off');
|
||||||
end
|
end
|
||||||
|
hold off
|
||||||
% Change all text interpreters to LaTeX
|
end
|
||||||
set(findall(gca, '-property', 'Interpreter'), 'Interpreter', 'latex');
|
|
||||||
|
% --- axis scaling and cosmetics
|
||||||
% Set figure background to white
|
if options.logscale
|
||||||
set(gcf, 'Color', 'w');
|
set(gca, 'YScale', 'log');
|
||||||
|
end
|
||||||
|
|
||||||
% Set logarithmic scale for y-axis, but only if it makes sense.
|
set(findall(gca, '-property', 'Interpreter'), 'Interpreter', 'latex');
|
||||||
% If this is not always desired, you could condition this on the presence of lines or data.
|
set(gcf, 'Color', 'w');
|
||||||
if options.logscale
|
set(gca, 'Box', 'on', 'LineWidth', 0.8);
|
||||||
set(gca, 'YScale', 'log');
|
grid on;
|
||||||
end
|
set(gca, 'FontSize', 10, 'FontName', 'Times New Roman');
|
||||||
|
|
||||||
% Customize grid and box appearance
|
|
||||||
set(gca, 'Box', 'on', 'LineWidth', 0.8); % Thicker border
|
|
||||||
grid on;
|
|
||||||
% grid minor;
|
|
||||||
|
|
||||||
% Adjust font size and style for better readability
|
|
||||||
set(gca, 'FontSize', 10, 'FontName', 'Times New Roman');
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ fp.where('Runs', 'rop_attenuation','EQUALS', 0);
|
|||||||
|
|
||||||
|
|
||||||
fields = db.getTableFieldNames('power_state_info');
|
fields = db.getTableFieldNames('power_state_info');
|
||||||
fields = [fields; db.getTableFieldNames('dashboard_ungrouped')];
|
fields = [fields; db.getTableFieldNames('dashboard_ungrouped_new')];
|
||||||
[dataTable,~] = db.queryDB(fp, fields);
|
[dataTable,~] = db.queryDB(fp, fields);
|
||||||
|
|
||||||
eqstructures = unique(dataTable.equalizer_structure);
|
eqstructures = unique(dataTable.equalizer_structure);
|
||||||
|
|||||||
@@ -41,7 +41,9 @@ plotdefs = struct( ...
|
|||||||
'legendLocation' , 'best', ...
|
'legendLocation' , 'best', ...
|
||||||
'fecLineWidth' , 2.2, ... % thicker FEC limits
|
'fecLineWidth' , 2.2, ... % thicker FEC limits
|
||||||
'fecColor' , [0.25 0.25 0.25], ...
|
'fecColor' , [0.25 0.25 0.25], ...
|
||||||
'capSize' , 6 ...
|
'capSize' , 6, ...
|
||||||
|
'lineStyle_default' , '-', ...
|
||||||
|
'use_pre_emph_styling' , true ...
|
||||||
);
|
);
|
||||||
cfg.plot = filldefaults(cfg.plot, plotdefs);
|
cfg.plot = filldefaults(cfg.plot, plotdefs);
|
||||||
|
|
||||||
@@ -131,8 +133,23 @@ for gi = 1:nG
|
|||||||
yu = yu(ord); ylo = ylo(ord); yhi = yhi(ord);
|
yu = yu(ord); ylo = ylo(ord); yhi = yhi(ord);
|
||||||
|
|
||||||
% Styles
|
% Styles
|
||||||
pre = logical(grpTbl.pre_emph(gi));
|
% Decide if we style by pre_emph
|
||||||
ls = tern(pre, cfg.plot.lineStyle_pre_emph_on, cfg.plot.lineStyle_pre_emph_off);
|
canStyleByPre = cfg.plot.use_pre_emph_styling && ismember('pre_emph', T.Properties.VariableNames);
|
||||||
|
|
||||||
|
if canStyleByPre
|
||||||
|
if any(strcmp(group_by,'pre_emph'))
|
||||||
|
% pre_emph is an explicit grouping key -> take it from the group table
|
||||||
|
pre = logical(grpTbl.pre_emph(gi));
|
||||||
|
else
|
||||||
|
% pre_emph not grouped, but available in the rows -> infer from the members of this group
|
||||||
|
pre = logical(mode(T.pre_emph(G==gi)));
|
||||||
|
end
|
||||||
|
ls = tern(pre, cfg.plot.lineStyle_pre_emph_on, cfg.plot.lineStyle_pre_emph_off);
|
||||||
|
else
|
||||||
|
% no pre-emph styling → use a single default style
|
||||||
|
ls = cfg.plot.lineStyle_default;
|
||||||
|
end
|
||||||
|
|
||||||
lbl = buildLabel(grpTbl(gi,:), group_by);
|
lbl = buildLabel(grpTbl(gi,:), group_by);
|
||||||
|
|
||||||
% Main line (dark)
|
% Main line (dark)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
% === SETTINGS ===
|
% === SETTINGS ===
|
||||||
dsp_options.append_to_db = 1;
|
dsp_options.append_to_db = 1;
|
||||||
dsp_options.max_occurences = 15;
|
dsp_options.max_occurences = 2;
|
||||||
|
|
||||||
experiment = "highspeed_2024";
|
experiment = "highspeed_2024";
|
||||||
dsp_options.mode = "load_run_id"; % 'simulate' & 'load_files'
|
dsp_options.mode = "load_run_id"; % 'simulate' & 'load_files'
|
||||||
@@ -42,16 +42,16 @@ fp = QueryFilter();
|
|||||||
% fp.where('Runs', 'run_id','EQUALS', 987);
|
% fp.where('Runs', 'run_id','EQUALS', 987);
|
||||||
M = 4;
|
M = 4;
|
||||||
fp.where('Runs', 'pam_level','EQUALS', M);
|
fp.where('Runs', 'pam_level','EQUALS', M);
|
||||||
fp.where('Runs', 'bitrate','EQUALS', 420e9);%360,390
|
fp.where('Runs', 'bitrate','EQUALS', 300e9);%360,390
|
||||||
% fp.where('Runs', 'symbolrate','EQUALS', 162e9);
|
% fp.where('Runs', 'symbolrate','EQUALS', 195e9);
|
||||||
fp.where('Runs', 'fiber_length','EQUALS', 2);
|
% fp.where('Runs', 'fiber_length','EQUALS', 1);
|
||||||
fp.where('Runs', 'is_mpi','EQUALS', 0);
|
fp.where('Runs', 'is_mpi','EQUALS', 0);
|
||||||
% fp.where('Runs', 'interference_path_length','EQUALS', 1000);
|
% fp.where('Runs', 'interference_path_length','EQUALS', 1000);
|
||||||
% fp.where('Runs', 'loop_id','GREATER_THAN', 11);
|
% fp.where('Runs', 'loop_id','GREATER_THAN', 11);
|
||||||
% fp.where('Runs', 'sir','EQUALS',18);
|
% fp.where('Runs', 'sir','EQUALS',18);
|
||||||
fp.where('Runs', 'wavelength','EQUAL', 1310);
|
fp.where('Runs', 'wavelength','EQUAL', 1310);
|
||||||
fp.where('Runs', 'db_mode','EQUALS', 0);
|
fp.where('Runs', 'db_mode','EQUALS', 1);
|
||||||
fp.where('Runs', 'rop_attenuation','EQUAL', 0);
|
% fp.where('Runs', 'rop_attenuation','EQUAL', 0);
|
||||||
% fp.where('Runs', 'power_pd_in','GREATER_THAN', 7);
|
% fp.where('Runs', 'power_pd_in','GREATER_THAN', 7);
|
||||||
|
|
||||||
[dataTable,~] = db.queryDB(fp, db.getTableFieldNames('Runs'));
|
[dataTable,~] = db.queryDB(fp, db.getTableFieldNames('Runs'));
|
||||||
@@ -66,15 +66,41 @@ wh.addStorage("mlse_package");
|
|||||||
wh.addStorage("vnle_package");
|
wh.addStorage("vnle_package");
|
||||||
wh.addStorage("dbtgt_package");
|
wh.addStorage("dbtgt_package");
|
||||||
wh.addStorage("dbenc_package");
|
wh.addStorage("dbenc_package");
|
||||||
|
wh.addStorage("mlmlse_package");
|
||||||
|
|
||||||
% === RUN IT ===
|
%% === RUN IT ===
|
||||||
|
|
||||||
[results,wh] = submitJobs(dataTable.run_id(:), dsp_options, "serial", 'wh', wh, 'waitbar', true);
|
[results,wh] = submitJobs(dataTable.run_id(:), dsp_options, "serial", 'wh', wh, 'waitbar', true);
|
||||||
|
|
||||||
|
%%
|
||||||
results_db = results(dataTable.db_mode==1);
|
results_db = results(dataTable.db_mode==1);
|
||||||
results_nodb = results(dataTable.db_mode==0);
|
results_nodb = results(dataTable.db_mode==0);
|
||||||
|
|
||||||
for i = 1:numel(results_db)
|
%BER for ML based MLSE
|
||||||
|
for i = 1:length(results_db)
|
||||||
|
ber_m = cellfun(@(c) c.metrics.BER_precoded, results_db{1,i}.mlmlse_package);
|
||||||
|
[BER_MLMLSE_pre_emph(i), ~] = min(ber_m);
|
||||||
|
|
||||||
|
ber_m = cellfun(@(c) c.metrics.BER_precoded, results_nodb{1,i}.mlmlse_package);
|
||||||
|
[BER_MLMLSE(i), ~] = min(ber_m);
|
||||||
|
|
||||||
|
ber_m = cellfun(@(c) c.metrics.BER_precoded, results_nodb{1,i}.mlmlse_package);
|
||||||
|
[BER_MLMLSE(i), ~] = min(ber_m);
|
||||||
|
|
||||||
|
baudrate(i) = dataTable.symbolrate(i);
|
||||||
|
rop_db(i) = dataTable.power_rop((2*i)-1);
|
||||||
|
end
|
||||||
|
|
||||||
|
figure(11);hold on
|
||||||
|
plot(sort(rop_db),sort(BER_MLMLSE_pre_emph))
|
||||||
|
plot(sort(rop_db),sort(BER_MLMLSE))
|
||||||
|
beautifyBERplot
|
||||||
|
|
||||||
|
%%
|
||||||
|
results_db = results(dataTable.db_mode==1);
|
||||||
|
results_nodb = results(dataTable.db_mode==0);
|
||||||
|
|
||||||
|
for i = 1:numel(results_nodb)
|
||||||
|
|
||||||
% VNLE (from results_nodb)
|
% VNLE (from results_nodb)
|
||||||
gmi_v = cellfun(@(c) c.metrics.GMI, results_nodb{1,i}.vnle_package);
|
gmi_v = cellfun(@(c) c.metrics.GMI, results_nodb{1,i}.vnle_package);
|
||||||
@@ -89,9 +115,9 @@ for i = 1:numel(results_db)
|
|||||||
idx_air_max_vnle(i) = find(air_v == max(air_v), 1);
|
idx_air_max_vnle(i) = find(air_v == max(air_v), 1);
|
||||||
|
|
||||||
% MLSE (from results_db)
|
% MLSE (from results_db)
|
||||||
gmi_m = cellfun(@(c) c.metrics.GMI, results_nodb{1,i}.mlse_package);
|
gmi_m = cellfun(@(c) c.metrics.GMI, results_db{1,i}.mlse_package);
|
||||||
ber_m = cellfun(@(c) c.metrics.BER, results_nodb{1,i}.mlse_package);
|
ber_m = cellfun(@(c) c.metrics.BER, results_nodb{1,i}.mlse_package);
|
||||||
air_m = cellfun(@(c) c.metrics.AIR, results_nodb{1,i}.mlse_package);
|
air_m = cellfun(@(c) c.metrics.AIR, results_db{1,i}.mlse_package);
|
||||||
[BER_MLSE(i), idx_ber] = min(ber_m);
|
[BER_MLSE(i), idx_ber] = min(ber_m);
|
||||||
GMI_MLSE(i) = gmi_m(idx_ber);
|
GMI_MLSE(i) = gmi_m(idx_ber);
|
||||||
AIR_MLSE(i) = air_m(idx_ber);
|
AIR_MLSE(i) = air_m(idx_ber);
|
||||||
@@ -111,11 +137,22 @@ for i = 1:numel(results_db)
|
|||||||
idx_gmi_min_db(i) = find(gmi_db == min(gmi_db), 1);
|
idx_gmi_min_db(i) = find(gmi_db == min(gmi_db), 1);
|
||||||
idx_air_max_db(i) = find(air_db == max(air_db), 1);
|
idx_air_max_db(i) = find(air_db == max(air_db), 1);
|
||||||
|
|
||||||
|
%BER for ML based MLSE
|
||||||
|
ber_m = cellfun(@(c) c.metrics.BER, results_nodb{1,i}.mlmlse_package);
|
||||||
|
[BER_MLMLSE(i), idx_ber] = min(ber_m);
|
||||||
|
ber_m = cellfun(@(c) c.metrics.BER_precoded, results_db{1,i}.mlmlse_package);
|
||||||
|
[BER_MLMLSE_PREC(i), idx_ber] = min(ber_m);
|
||||||
|
|
||||||
% metadata
|
% metadata
|
||||||
bitrate(i) = dataTable.bitrate(i);
|
bitrate(i) = dataTable.bitrate(i);
|
||||||
baudrate(i) = dataTable.symbolrate(i);
|
baudrate(i) = dataTable.symbolrate(i);
|
||||||
|
rop_atten(i) = dataTable.rop_attenuation(2*i);
|
||||||
|
rop_pre(i) = dataTable.power_rop((2*i)-1);
|
||||||
|
rop(i) = dataTable.power_rop((2*i));
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
%%
|
||||||
STYLE_BASE = 2; % adjust this single number to scale markers & lines
|
STYLE_BASE = 2; % adjust this single number to scale markers & lines
|
||||||
MARKER_SIZE = STYLE_BASE; % marker size (MATLAB MarkerSize)
|
MARKER_SIZE = STYLE_BASE; % marker size (MATLAB MarkerSize)
|
||||||
LINE_WIDTH = max(2, STYLE_BASE/3); % line width (keeps lines reasonable when STYLE_BASE large)
|
LINE_WIDTH = max(2, STYLE_BASE/3); % line width (keeps lines reasonable when STYLE_BASE large)
|
||||||
@@ -128,6 +165,7 @@ cm.VNLE = cols(1 + d, :);
|
|||||||
cm.MLSE = cols(2 + d, :);
|
cm.MLSE = cols(2 + d, :);
|
||||||
cm.DB_precode = cols(3 + d, :);
|
cm.DB_precode = cols(3 + d, :);
|
||||||
cm.DB = cols(4 + d, :); % duobinary
|
cm.DB = cols(4 + d, :); % duobinary
|
||||||
|
cm.ML_MLSE = cols(6 + d, :);
|
||||||
|
|
||||||
% prepare x values in GBd
|
% prepare x values in GBd
|
||||||
xGHz = baudrate .* 1e-9;
|
xGHz = baudrate .* 1e-9;
|
||||||
@@ -139,7 +177,7 @@ mk.VNLE = {'Marker','o','MarkerFaceColor',cm.VNLE,'MarkerEdgeColor',cm.VNLE,'
|
|||||||
mk.MLSE = {'Marker','*','MarkerFaceColor',cm.MLSE,'MarkerEdgeColor',cm.MLSE,'MarkerSize',MARKER_SIZE};
|
mk.MLSE = {'Marker','*','MarkerFaceColor',cm.MLSE,'MarkerEdgeColor',cm.MLSE,'MarkerSize',MARKER_SIZE};
|
||||||
mk.DB_precode = {'Marker','^','MarkerFaceColor',cm.DB_precode,'MarkerEdgeColor',cm.DB_precode,'MarkerSize',MARKER_SIZE};
|
mk.DB_precode = {'Marker','^','MarkerFaceColor',cm.DB_precode,'MarkerEdgeColor',cm.DB_precode,'MarkerSize',MARKER_SIZE};
|
||||||
mk.DB = {'Marker','d','MarkerFaceColor',cm.DB,'MarkerEdgeColor',cm.DB,'MarkerSize',MARKER_SIZE};
|
mk.DB = {'Marker','d','MarkerFaceColor',cm.DB,'MarkerEdgeColor',cm.DB,'MarkerSize',MARKER_SIZE};
|
||||||
|
mk.ML_MLSE = {'Marker','^','MarkerFaceColor',cm.ML_MLSE,'MarkerEdgeColor',cm.ML_MLSE,'MarkerSize',MARKER_SIZE};
|
||||||
|
|
||||||
% ---------------- FIGURE : BER ----------------
|
% ---------------- FIGURE : BER ----------------
|
||||||
figure(112+M); clf; hold on;
|
figure(112+M); clf; hold on;
|
||||||
@@ -149,20 +187,100 @@ plot(xGHz, BER_VNLE, ...
|
|||||||
plot(xGHz, BER_MLSE, ...
|
plot(xGHz, BER_MLSE, ...
|
||||||
'DisplayName','MLSE', ...
|
'DisplayName','MLSE', ...
|
||||||
mk.MLSE{:}, 'LineStyle','-','LineWidth',LINE_WIDTH,'Color',cm.MLSE);
|
mk.MLSE{:}, 'LineStyle','-','LineWidth',LINE_WIDTH,'Color',cm.MLSE);
|
||||||
plot(xGHz, BER_DB, ...
|
|
||||||
'DisplayName','DB tgt.', ...
|
|
||||||
mk.DB{:}, 'LineStyle','-','LineWidth',LINE_WIDTH,'Color',cm.DB);
|
|
||||||
plot(xGHz, BER_DB_PREC, ...
|
plot(xGHz, BER_DB_PREC, ...
|
||||||
'DisplayName','Diff. Precode + DB tgt.', ...
|
'DisplayName','Diff. Precode + DB tgt.', ...
|
||||||
mk.DB{:}, 'LineStyle',':','LineWidth',LINE_WIDTH,'Color',cm.DB);
|
mk.DB{:}, 'LineStyle','-','LineWidth',LINE_WIDTH,'Color',cm.DB);
|
||||||
|
plot(xGHz, BER_MLMLSE_PREC, ...
|
||||||
|
'DisplayName','ML-based MLSE (L=2)', ...
|
||||||
|
mk.ML_MLSE{:}, 'LineStyle',':','LineWidth',LINE_WIDTH,'Color',cm.ML_MLSE);
|
||||||
|
|
||||||
|
yline(2e-2,'LineWidth',1,'HandleVisibility','off');
|
||||||
yline(4.85e-3,'LineWidth',1,'HandleVisibility','off');
|
yline(4.85e-3,'LineWidth',1,'HandleVisibility','off');
|
||||||
yline(2.2e-4,'LineWidth',1,'HandleVisibility','off');
|
yline(2.2e-4,'LineWidth',1,'HandleVisibility','off');
|
||||||
xlabel('Baudrate in GBd');
|
xlabel('Baudrate in GBd');
|
||||||
ylabel('BER');
|
ylabel('BER');
|
||||||
set(gca, 'yscale', 'log');
|
set(gca, 'yscale', 'log');
|
||||||
set(gca, 'XTick', xticks_vals(1:2:end), 'XTickLabel', xtick_labels(1:2:end));
|
set(gca, 'XTick', xticks_vals(1:end), 'XTickLabel', xtick_labels(1:end));
|
||||||
grid on;
|
grid on;
|
||||||
legend('Location','best');
|
legend('Location','best');
|
||||||
|
beautifyBERplot
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
%%
|
||||||
|
%%
|
||||||
|
STYLE_BASE = 2; % adjust this single number to scale markers & lines
|
||||||
|
MARKER_SIZE = STYLE_BASE; % marker size (MATLAB MarkerSize)
|
||||||
|
LINE_WIDTH = max(2, STYLE_BASE/3); % line width (keeps lines reasonable when STYLE_BASE large)
|
||||||
|
|
||||||
|
% --- color map / method -> color assignment (keeps colors consistent) ---
|
||||||
|
cols = cbrewer2('Paired',8);
|
||||||
|
cols = linspecer(6);
|
||||||
|
d = 0;
|
||||||
|
cm.VNLE = cols(1 + d, :);
|
||||||
|
cm.MLSE = cols(2 + d, :);
|
||||||
|
cm.DB_precode = cols(3 + d, :);
|
||||||
|
cm.DB = cols(4 + d, :); % duobinary
|
||||||
|
cm.ML_MLSE = cols(6 + d, :);
|
||||||
|
|
||||||
|
% prepare x values in GBd
|
||||||
|
xdbm = flip(sort(rop));
|
||||||
|
xticks_vals = xdbm;
|
||||||
|
xtick_labels = arrayfun(@(v) sprintf('%d', round(v)), xticks_vals, 'UniformOutput', false);
|
||||||
|
|
||||||
|
% common marker settings (filled, same face+edge color)
|
||||||
|
mk.VNLE = {'Marker','o','MarkerFaceColor',cm.VNLE,'MarkerEdgeColor',cm.VNLE,'MarkerSize',MARKER_SIZE};
|
||||||
|
mk.MLSE = {'Marker','*','MarkerFaceColor',cm.MLSE,'MarkerEdgeColor',cm.MLSE,'MarkerSize',MARKER_SIZE};
|
||||||
|
mk.DB_precode = {'Marker','^','MarkerFaceColor',cm.DB_precode,'MarkerEdgeColor',cm.DB_precode,'MarkerSize',MARKER_SIZE};
|
||||||
|
mk.DB = {'Marker','d','MarkerFaceColor',cm.DB,'MarkerEdgeColor',cm.DB,'MarkerSize',MARKER_SIZE};
|
||||||
|
mk.ML_MLSE = {'Marker','^','MarkerFaceColor',cm.ML_MLSE,'MarkerEdgeColor',cm.ML_MLSE,'MarkerSize',MARKER_SIZE};
|
||||||
|
|
||||||
|
% ---------------- FIGURE : BER ----------------
|
||||||
|
figure(112+M); clf; hold on;
|
||||||
|
plot(flip(sort(rop)), sort(BER_VNLE), ...
|
||||||
|
'DisplayName','VNLE', ...
|
||||||
|
mk.VNLE{:}, 'LineStyle','-','LineWidth',LINE_WIDTH,'Color',cm.VNLE);
|
||||||
|
plot(flip(sort(rop)), sort(BER_MLSE), ...
|
||||||
|
'DisplayName','MLSE', ...
|
||||||
|
mk.MLSE{:}, 'LineStyle','-','LineWidth',LINE_WIDTH,'Color',cm.MLSE);
|
||||||
|
plot(flip(sort(rop)), sort(BER_MLSE), ...
|
||||||
|
'DisplayName','MLSE', ...
|
||||||
|
mk.MLSE{:}, 'LineStyle','-','LineWidth',LINE_WIDTH,'Color',cm.MLSE);
|
||||||
|
plot(flip(sort(rop_pre)), sort(BER_DB_PREC), ...
|
||||||
|
'DisplayName','Diff. Precode + DB tgt.', ...
|
||||||
|
mk.DB{:}, 'LineStyle','-','LineWidth',LINE_WIDTH,'Color',cm.DB);
|
||||||
|
plot(flip(sort(rop_pre)), sort(BER_MLMLSE_PREC), ...
|
||||||
|
'DisplayName','ML-based MLSE Diff. Prec. (L=2)', ...
|
||||||
|
mk.ML_MLSE{:}, 'LineStyle','-','LineWidth',LINE_WIDTH,'Color',cm.ML_MLSE);
|
||||||
|
plot(flip(sort(rop_pre)), sort(BER_MLMLSE), ...
|
||||||
|
'DisplayName','ML-based MLSE (L=2)', ...
|
||||||
|
mk.ML_MLSE{:}, 'LineStyle',':','LineWidth',LINE_WIDTH,'Color',cm.DB_precode);
|
||||||
|
|
||||||
|
yline(2e-2,'LineWidth',1,'HandleVisibility','off');
|
||||||
|
yline(4.85e-3,'LineWidth',1,'HandleVisibility','off');
|
||||||
|
yline(2.2e-4,'LineWidth',1,'HandleVisibility','off');
|
||||||
|
xlabel('ROP in dBm');
|
||||||
|
ylabel('BER');
|
||||||
|
set(gca, 'yscale', 'log');
|
||||||
|
% set(gca, 'XTick', xticks_vals(1:end), 'XTickLabel', xtick_labels(1:end));
|
||||||
|
grid on;
|
||||||
|
legend('Location','best');
|
||||||
|
beautifyBERplot
|
||||||
|
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
% ---------------- FIGURE 15 : GMI ----------------
|
% ---------------- FIGURE 15 : GMI ----------------
|
||||||
|
|||||||
@@ -6,31 +6,32 @@ M = 4;
|
|||||||
fp = QueryFilter();
|
fp = QueryFilter();
|
||||||
% fp.where('Runs', 'run_id','EQUALS', 987);
|
% fp.where('Runs', 'run_id','EQUALS', 987);
|
||||||
% fp.where('Runs', 'pam_level','EQUALS', M);
|
% fp.where('Runs', 'pam_level','EQUALS', M);
|
||||||
% fp.where('Runs', 'symbolrate','EQUALS', 150e9);
|
% fp.where('Runs', 'symbolrate','EQUALS', 165e9); %150, 165, 180, 195, 210, 225, 240
|
||||||
% fp.where('Runs', 'fiber_length','EQUALS', 10);
|
% fp.where('Runs', 'fiber_length','EQUALS', 10);
|
||||||
fp.where('Runs', 'is_mpi','EQUALS', 0);
|
% fp.where('Runs', 'is_mpi','EQUALS', 0);
|
||||||
|
% fp.where('Runs', 'power_pd_in','GREATER_THAN', 7);
|
||||||
% fp.where('Runs', 'interference_path_length','EQUALS', 1000);
|
% fp.where('Runs', 'interference_path_length','EQUALS', 1000);
|
||||||
% fp.where('Runs', 'loop_id','GREATER_THAN', 11);
|
% fp.where('Runs', 'loop_id','GREATER_THAN', 11);
|
||||||
% fp.where('Runs', 'sir','EQUALS',18);
|
% fp.where('Runs', 'sir','EQUALS',18);
|
||||||
% fp.where('Runs', 'wavelength','EQUALS', 1310);
|
% fp.where('Runs', 'wavelength','EQUALS', 1310);
|
||||||
fp.where('Runs', 'db_mode','EQUALS', 1); % 0 == high preemphasis // 1 == low preemphasis
|
fp.where('Runs', 'db_mode','EQUALS', 2); % 0 == high preemphasis // 1 == low preemphasis
|
||||||
fp.where('Runs', 'rop_attenuation','EQUALS', 0);
|
% fp.where('Runs', 'rop_attenuation','EQUALS', 0);
|
||||||
|
|
||||||
fields = db.getTableFieldNames('power_state_info');
|
fields = db.getTableFieldNames('power_state_info');
|
||||||
fields = [fields; db.getTableFieldNames('dashboard_ungrouped_new')];
|
fields = [fields; db.getTableFieldNames('dashboard_ungrouped_new')];
|
||||||
[dataTable,~] = db.queryDB(fp, fields);
|
[dataTable,~] = db.queryDB(fp, fields);
|
||||||
|
|
||||||
%%
|
%%
|
||||||
cfg = struct;
|
cfg = struct;
|
||||||
cfg.x_axis = 'wavelength'; % 'symbolrate' | 'baudrate' | 'bitrate' | 'wavelength'
|
cfg.x_axis = 'symbolrate'; % 'symbolrate' | 'bitrate' | 'wavelength'
|
||||||
cfg.y_axis = 'power_mzm'; % 'BER' | 'GMI' | 'AIR' | ...
|
cfg.y_axis = 'BER'; % 'BER' | 'GMI' | 'AIR' | ...
|
||||||
cfg.group_by = {};
|
cfg.group_by = {'wavelength'};
|
||||||
cfg.filters = struct('is_mpi',0,'pam_level',M,'equalizer_structure',[equalizer_structure.vnle,equalizer_structure.ffe,equalizer_structure.vnle_pf_mlse,equalizer_structure.vnle_db_mlse,equalizer_structure.dfe]);
|
cfg.filters = struct('is_mpi',0,'pam_level',M,'equalizer_structure',[equalizer_structure.vnle_db_mlse]);%,equalizer_structure.ffe,equalizer_structure.vnle_pf_mlse,equalizer_structure.vnle_db_mlse,equalizer_structure.dfe]);
|
||||||
|
|
||||||
cfg.y_scale = 'auto'; % auto -> log for BER*, linear otherwise
|
cfg.y_scale = 'auto'; % auto -> log for BER*, linear otherwise
|
||||||
cfg.outlier = 'mad'; % simple, robust; 'none' or 'pctl' also available
|
cfg.outlier = 'mad'; % simple, robust; 'none' or 'pctl' also available
|
||||||
cfg.show_raw = true;
|
cfg.show_raw = true;
|
||||||
cfg.show_spread = 'none'; % 'none' or 'iqr'
|
cfg.show_spread = 'iqr'; % 'none' or 'iqr'
|
||||||
cfg.agg = 'mean'; % or 'median'
|
cfg.agg = 'mean'; % or 'median'
|
||||||
cfg.show_precoded = 0;
|
cfg.show_precoded = 0;
|
||||||
cfg.fec_lines = [2.2e-4 4.85e-3 2e-2]; % optional
|
cfg.fec_lines = [2.2e-4 4.85e-3 2e-2]; % optional
|
||||||
@@ -45,5 +46,4 @@ cfg.plot.scatterAlpha = 0.35;
|
|||||||
cfg.plot.legendLocation = 'best';
|
cfg.plot.legendLocation = 'best';
|
||||||
cfg.plot.fecLineWidth = 2.4; % thicker FEC limits
|
cfg.plot.fecLineWidth = 2.4; % thicker FEC limits
|
||||||
|
|
||||||
|
|
||||||
plot_measurements_gpt(dataTable, cfg);
|
plot_measurements_gpt(dataTable, cfg);
|
||||||
164
projects/ML_based_MLSE/analyze_filter_length.m
Normal file
164
projects/ML_based_MLSE/analyze_filter_length.m
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
%% analyze_filter_length.m
|
||||||
|
clear; clc;
|
||||||
|
|
||||||
|
M = 4;
|
||||||
|
randkey = 1;
|
||||||
|
|
||||||
|
% --- Parameter sweep
|
||||||
|
order_range = 2:3:11; % FFE order
|
||||||
|
delta_range = 0:2:4; % delta
|
||||||
|
SNR_dB = 20;
|
||||||
|
|
||||||
|
% --- Prepare bit sequence
|
||||||
|
order_bits = 19;
|
||||||
|
s = RandStream('twister','Seed',randkey);
|
||||||
|
for i = 1:log2(M)
|
||||||
|
N = 2^(order_bits-1);
|
||||||
|
bitpattern(:,i) = randi(s,[0 1], N, 1);
|
||||||
|
end
|
||||||
|
Bits = Informationsignal(bitpattern);
|
||||||
|
Symbols = PAMmapper(M,0).map(Bits);
|
||||||
|
Symbols.fs = 200e9;
|
||||||
|
|
||||||
|
% --- Channel (minimal ISI + AWGN)
|
||||||
|
h = [0.3 0.9 0.3]; h = h/norm(h);
|
||||||
|
symbols_filt = Symbols.filter(h,1);
|
||||||
|
symbols_noi = symbols_filt;
|
||||||
|
symbols_noi.signal = awgn(symbols_filt.signal,SNR_dB,'measured');
|
||||||
|
|
||||||
|
% --- Generate all parameter pairs
|
||||||
|
[O,D] = ndgrid(order_range, delta_range);
|
||||||
|
pairs = [O(:), D(:)];
|
||||||
|
|
||||||
|
training_len = 100;
|
||||||
|
|
||||||
|
ber_vec = nan(size(pairs,1),1); % initialize with NaN
|
||||||
|
ber_training = nan(size(pairs,1),training_len);
|
||||||
|
ce_vec = nan(size(pairs,1),1);
|
||||||
|
ce_training = nan(size(pairs,1),training_len);
|
||||||
|
|
||||||
|
% --- Parallel loop over parameter pairs
|
||||||
|
parfor k = 1:size(pairs,1)
|
||||||
|
order_k = pairs(k,1);
|
||||||
|
delta_k = pairs(k,2);
|
||||||
|
|
||||||
|
% Skip invalid combinations (delay cannot exceed filter length)
|
||||||
|
if abs(delta_k) >= order_k
|
||||||
|
fprintf('Skip: order=%d, delta=%d (invalid)\n', order_k, delta_k);
|
||||||
|
continue;
|
||||||
|
end
|
||||||
|
|
||||||
|
try
|
||||||
|
ml = ML_MLSE("epochs_tr",training_len,"epochs_dd",1,"len_tr",2^15, ...
|
||||||
|
"mu_dd",0.1,"mu_tr",0.1,"order",order_k,"sps",1, ...
|
||||||
|
"traceback_depth",128,"L",3,"delta",delta_k,"adaptive_mu",0);
|
||||||
|
|
||||||
|
[y_ml,y_ref] = ml.process(symbols_noi,Symbols);
|
||||||
|
ref_bits = PAMmapper(M,0).demap(y_ref);
|
||||||
|
eq_bits = PAMmapper(M,0).demap(y_ml);
|
||||||
|
|
||||||
|
ber_training(k,:) = ml.ber;
|
||||||
|
ce_training(k,:) = ml.ce;
|
||||||
|
|
||||||
|
[~,~,ber_vec(k)] = calc_ber(eq_bits.signal, ref_bits.signal, ...
|
||||||
|
"skip_front",10,"skip_end",10);
|
||||||
|
L = min(length(ml.ce),30);
|
||||||
|
ce_vec(k) = mean(ml.ce(end-L+1:end));
|
||||||
|
|
||||||
|
fprintf('order=%d, delta=%d → BER=%.2e, CE=%.3f\n', ...
|
||||||
|
order_k, delta_k, ber_vec(k), ce_vec(k));
|
||||||
|
catch ME
|
||||||
|
fprintf('Error at order=%d, delta=%d: %s\n', ...
|
||||||
|
order_k, delta_k, ME.message);
|
||||||
|
ber_vec(k) = NaN;
|
||||||
|
ce_vec(k) = NaN;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
% --- reshape to 2D matrices
|
||||||
|
ber_mat = reshape(ber_vec, numel(order_range), numel(delta_range));
|
||||||
|
ce_mat = reshape(ce_vec, numel(order_range), numel(delta_range));
|
||||||
|
|
||||||
|
|
||||||
|
%% --- Plot BER
|
||||||
|
figure; hold on
|
||||||
|
cols = cbrewer2('Set1',10);
|
||||||
|
for i = 1:numel(delta_range)
|
||||||
|
plot(order_range,ber_mat(:,i),'DisplayName',sprintf('delta: %d',delta_range(i)),'Color',cols(i,:))
|
||||||
|
end
|
||||||
|
beautifyBERplot
|
||||||
|
ylabel('BER'); xlabel('Filter Order [N]');
|
||||||
|
title('BER vs. Filter order');
|
||||||
|
ylim([1e-4, 0.1]);
|
||||||
|
yline(3.8e-3,'HandleVisibility','off');
|
||||||
|
yline(2.2e-4,'HandleVisibility','off');
|
||||||
|
|
||||||
|
%% --- Plot Cross-Entropy
|
||||||
|
figure; hold on
|
||||||
|
for i = 1:numel(delta_range)
|
||||||
|
plot(order_range,ce_mat(:,i),'DisplayName',sprintf('delta: %d',delta_range(i)))
|
||||||
|
end
|
||||||
|
% beautifyBERplot
|
||||||
|
ylabel('BER'); xlabel('Filter Order [N]');
|
||||||
|
title('BER vs. Filter order');
|
||||||
|
|
||||||
|
%% --- Training Curves: BER and CE per combination
|
||||||
|
figure('Name','Training Convergence'); hold on
|
||||||
|
cols = cbrewer2('Set1', 10); % one color per delta
|
||||||
|
|
||||||
|
[O, D] = ndgrid(order_range, delta_range);
|
||||||
|
|
||||||
|
for i = 1:size(ber_training,1)
|
||||||
|
ord = O(i);
|
||||||
|
del = D(i);
|
||||||
|
|
||||||
|
if ord <= del
|
||||||
|
continue;
|
||||||
|
end
|
||||||
|
% --- show only order 2 and 10
|
||||||
|
if ord == 2
|
||||||
|
lnst = '-';
|
||||||
|
elseif ord == 5
|
||||||
|
lnst = ':';
|
||||||
|
elseif ord == 8
|
||||||
|
lnst = '--';
|
||||||
|
elseif ord == 11
|
||||||
|
lnst = '-.';
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
b = ber_training(i,:);
|
||||||
|
|
||||||
|
|
||||||
|
plot_label = sprintf('order=%d, delta=%d', ord, del);
|
||||||
|
plot(1:length(b), b, 'Color', cols(del+1, :), ...
|
||||||
|
'DisplayName', plot_label,'LineStyle',lnst);
|
||||||
|
end
|
||||||
|
|
||||||
|
set(gca,'YScale','log');
|
||||||
|
xlabel('Epoch');
|
||||||
|
ylabel('BER');
|
||||||
|
title('Training Convergence (BER)');
|
||||||
|
legend('show');
|
||||||
|
grid on;
|
||||||
|
|
||||||
|
|
||||||
|
%% --- Cross-Entropy curves
|
||||||
|
figure('Name','Cross-Entropy'); hold on
|
||||||
|
cols = cbrewer2('Set1',size(ce_training,1));
|
||||||
|
for i = 1:size(ce_training,1)
|
||||||
|
|
||||||
|
[O, D] = ndgrid(order_range, delta_range);
|
||||||
|
plot_label = sprintf('order=%d, delta=%d', O(i), D(i));
|
||||||
|
c = ce_training(i,:);
|
||||||
|
c(~isfinite(c) | c==0) = NaN;
|
||||||
|
if all(isnan(c)), continue; end
|
||||||
|
plot(1:length(c), c, 'Color', cols(D(i)+1,:), ...
|
||||||
|
'DisplayName', plot_label);
|
||||||
|
end
|
||||||
|
set(gca,'YScale','log');
|
||||||
|
xlabel('Epoch');
|
||||||
|
ylabel('Cross-Entropy');
|
||||||
|
title('Training Convergence (CE)');
|
||||||
|
legend('show');
|
||||||
|
grid on;
|
||||||
113
projects/ML_based_MLSE/analyze_mu.m
Normal file
113
projects/ML_based_MLSE/analyze_mu.m
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
|
||||||
|
M = 4;
|
||||||
|
order = 19;
|
||||||
|
randkey = 1;
|
||||||
|
|
||||||
|
bitpattern = [];
|
||||||
|
s = RandStream('twister','Seed',randkey);
|
||||||
|
for i = 1:log2(M)
|
||||||
|
N = 2^(order-1); %length of prbs
|
||||||
|
bitpattern(:,i) = randi(s,[0 1], N, 1);
|
||||||
|
end
|
||||||
|
|
||||||
|
if M == 6
|
||||||
|
bitpattern = reshape(bitpattern',[],1);
|
||||||
|
bitpattern = bitpattern(1:end-mod(length(bitpattern),5));
|
||||||
|
end
|
||||||
|
|
||||||
|
Bits = Informationsignal(bitpattern);
|
||||||
|
|
||||||
|
Symbols = PAMmapper(M,0).map(Bits);
|
||||||
|
Symbols.fs = 200e9;
|
||||||
|
|
||||||
|
Bits_ = PAMmapper(M, 0, "eth_style", 0).demap(Symbols);
|
||||||
|
|
||||||
|
% --- Channel: minimal ISI response + AWGN ---
|
||||||
|
h = [0.3 0.9 0.3]; % impulse response (normalized later if desired)
|
||||||
|
h = h / norm(h); % optional normalization for unit energy
|
||||||
|
|
||||||
|
symbols_filt = Symbols.filter(h,1);
|
||||||
|
|
||||||
|
|
||||||
|
%% SHOW Loss during training
|
||||||
|
|
||||||
|
mu = logspace(-3,-0.8,12);
|
||||||
|
ber_ml_mlse = zeros(size(mu));
|
||||||
|
ber_training = [];
|
||||||
|
ce_training = [];
|
||||||
|
|
||||||
|
parfor i = 1:numel(mu)
|
||||||
|
|
||||||
|
symbols_noi = symbols_filt;
|
||||||
|
SNR_dB = 20;
|
||||||
|
symbols_noi.signal = awgn(symbols_filt.signal, SNR_dB, 'measured'); % AWGN with given SNR
|
||||||
|
|
||||||
|
ml_mlse_equalizer = ML_MLSE("epochs_tr",200,"epochs_dd",1,"len_tr",2^15,...
|
||||||
|
"mu_dd",mu(i),"mu_tr",mu(i),"order",5,"sps",1,...
|
||||||
|
"traceback_depth",128,"L",3,"delta",0,'adaptive_mu',0);
|
||||||
|
|
||||||
|
[y_ml_mlse,y_ref] = ml_mlse_equalizer.process(symbols_noi,Symbols);
|
||||||
|
ref_bits = PAMmapper(M, 0, "eth_style", 0).demap(y_ref);
|
||||||
|
ml_mlse_bits = PAMmapper(M, 0, "eth_style", 0).demap(y_ml_mlse);
|
||||||
|
[~, errors, ber_ml_mlse(i), errpos] = calc_ber(ml_mlse_bits.signal, ref_bits.signal, "skip_front", 10, "skip_end", 10, "returnErrorLocation", 1);
|
||||||
|
fprintf('ML MLSE BER: %.2e \n',ber_ml_mlse(i));
|
||||||
|
ber_training(i,:) = ml_mlse_equalizer.ber;
|
||||||
|
ce_training(i,:) = ml_mlse_equalizer.ce;
|
||||||
|
end
|
||||||
|
|
||||||
|
%%
|
||||||
|
symbols_noi = symbols_filt;
|
||||||
|
SNR_dB = 20;
|
||||||
|
symbols_noi.signal = awgn(symbols_filt.signal, SNR_dB, 'measured'); % AWGN with given SNR
|
||||||
|
ml_mlse_equalizer_adap = ML_MLSE("epochs_tr",200,"epochs_dd",1,"len_tr",2^16,...
|
||||||
|
"mu_dd",1,"mu_tr",1,"order",5,"sps",1,...
|
||||||
|
"traceback_depth",128,"L",3,"delta",0,"adaptive_mu",1);
|
||||||
|
|
||||||
|
[y_ml_mlse,y_ref] = ml_mlse_equalizer_adap.process(symbols_noi,Symbols);
|
||||||
|
ref_bits = PAMmapper(M, 0, "eth_style", 0).demap(y_ref);
|
||||||
|
ml_mlse_bits = PAMmapper(M, 0, "eth_style", 0).demap(y_ml_mlse);
|
||||||
|
[~, errors, ber_ml_mlse_, errpos] = calc_ber(ml_mlse_bits.signal, ref_bits.signal, "skip_front", 10, "skip_end", 10, "returnErrorLocation", 1);
|
||||||
|
fprintf('ML MLSE BER: %.2e \n',ber_ml_mlse_);
|
||||||
|
|
||||||
|
%%
|
||||||
|
figure();hold on
|
||||||
|
|
||||||
|
plot(mu,ber_ml_mlse,'DisplayName','ML-based MLSE');
|
||||||
|
|
||||||
|
beautifyBERplot;
|
||||||
|
xlim([mu(1), mu(end)]);
|
||||||
|
xlabel('mu');
|
||||||
|
ylabel('BER');
|
||||||
|
title('PAM-4; M=3; AWGN Channel');
|
||||||
|
ylim([1e-5 0.1]);
|
||||||
|
|
||||||
|
%%
|
||||||
|
figure()
|
||||||
|
hold on;
|
||||||
|
cols = cbrewer2('Spectral',12);
|
||||||
|
for i = 1:12
|
||||||
|
plot(1:200,ber_training(i,:),'DisplayName', sprintf('mu=%.3f ',mu(i)),'Color',cols(i,:));
|
||||||
|
end
|
||||||
|
set(gca,'YScale','log');
|
||||||
|
xlabel('Epoch');
|
||||||
|
ylabel('BER');
|
||||||
|
title('PAM-4; L=3; SNR=20; AWGN Channel');
|
||||||
|
plot(1:200,ml_mlse_equalizer_adap.ber,'DisplayName','Adaptive mu');
|
||||||
|
|
||||||
|
%%
|
||||||
|
figure()
|
||||||
|
hold on;
|
||||||
|
cols = cbrewer2('Spectral',12);
|
||||||
|
for i = 1:12
|
||||||
|
plot(1:200,ce_training(i,:),'DisplayName', sprintf('mu=%.3f ',mu(i)),'Color',cols(i,:));
|
||||||
|
end
|
||||||
|
set(gca,'YScale','log');
|
||||||
|
xlabel('Epoch');
|
||||||
|
ylabel('Cross-Entropy');
|
||||||
|
title('PAM-4; L=3; SNR=20; AWGN Channel');
|
||||||
|
plot(1:200,ml_mlse_equalizer_adap.ce,'DisplayName','Adaptive mu');
|
||||||
|
|
||||||
|
|
||||||
|
%% SUPER LONG EPOCHS
|
||||||
|
|
||||||
|
|
||||||
162
projects/ML_based_MLSE/experimental_data.m
Normal file
162
projects/ML_based_MLSE/experimental_data.m
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
|
||||||
|
|
||||||
|
dsp_options.storage_path = 'Z:\2024\sioe_labor\';
|
||||||
|
dsp_options.max_occurences = 1;
|
||||||
|
database = DBHandler("dataBase", 'labor_highspeed', "type", 'mysql' );
|
||||||
|
run_id = 2776;
|
||||||
|
dataTable = queryRunid(run_id, database);
|
||||||
|
fsym = dataTable.symbolrate;
|
||||||
|
M = double(dataTable.pam_level);
|
||||||
|
duob_mode = db_mode(strrep(dataTable.db_mode,'"',''));
|
||||||
|
|
||||||
|
% if database.checkIfRunExists('Results','run_id',run_id)
|
||||||
|
% disp(['Already got at least one reulst for run id: ',num2str(run_id),' '])
|
||||||
|
% return
|
||||||
|
% end
|
||||||
|
|
||||||
|
% Load and Sync signal data from DB
|
||||||
|
[Tx_bits, Symbols, Scpe_cell, ~] = loadAndSyncSignalDataFromDb(dataTable, dsp_options);
|
||||||
|
|
||||||
|
% Preprocess signal
|
||||||
|
Scpe_sig = preprocessSignal(Scpe_cell{1}, Symbols, fsym);
|
||||||
|
|
||||||
|
Scpe_sig.spectrum("fignum",1,"displayname",'Rx')
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
ffe_order = [50, 5, 5];
|
||||||
|
mu_ffe = [0.0001, 0.0008, 0.001];
|
||||||
|
mu_dfe = 0.0004;
|
||||||
|
eq_ = EQ("Ne",ffe_order,"Nb",[0,0,0],"training_length",2^14,"training_loops",5,"dd_loops",5,"K",2,"DCmu",0.005,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",1);
|
||||||
|
mlse_ = MLSE("DIR",[1,1],"duobinary_output",0,"M",M,"trellis_states",PAMmapper(M,0).levels,'scale_mode',2,'trellis_exclusion',0,'trellis_state_mode',3);
|
||||||
|
|
||||||
|
|
||||||
|
%Duobinary Targeting
|
||||||
|
db_ref_sequence = Duobinary().encode(Symbols);
|
||||||
|
db_ref_constellation = unique(db_ref_sequence.signal);
|
||||||
|
[eq_signal, eq_noise] = eq_.process(Scpe_sig,db_ref_sequence);
|
||||||
|
%%
|
||||||
|
if 0
|
||||||
|
[mlse_sig_sd,LLR,GMI_MLSE] = mlse_.process(eq_signal,Symbols);
|
||||||
|
else
|
||||||
|
% Ml MLSE
|
||||||
|
ml_mlse_equalizer = ML_MLSE("epochs_tr",20,"epochs_dd",1,"len_tr",length(eq_signal),...
|
||||||
|
"mu_dd",0.01,"mu_tr",0.01,"order",11,"sps",2,...
|
||||||
|
"traceback_depth",128,"L",1,"delta",4,'adaptive_mu',0);
|
||||||
|
[mlse_sig_sd,ref_sig] = ml_mlse_equalizer.process(Scpe_sig,db_ref_sequence);
|
||||||
|
end
|
||||||
|
|
||||||
|
%%
|
||||||
|
mlse_sig_sd_decoded = Duobinary().decode(mlse_sig_sd,"M",M);
|
||||||
|
ref_sig_decoded = Duobinary().decode(db_ref_sequence,"M",M);
|
||||||
|
|
||||||
|
mlse_sig_bits = PAMmapper(M,0,"eth_style",0).demap(mlse_sig_sd_decoded);
|
||||||
|
ref_sig_bits = PAMmapper(M,0,"eth_style",0).demap(ref_sig_decoded);
|
||||||
|
|
||||||
|
err = sum(ref_sig_decoded.signal ~= mlse_sig_sd_decoded.signal);
|
||||||
|
|
||||||
|
[bits_db,errors_db,ber_db,a] = calc_ber(mlse_sig_bits.signal,ref_sig_bits.signal,"skip_front",0,"skip_end",0,"returnErrorLocation",1);
|
||||||
|
|
||||||
|
%%
|
||||||
|
switch duob_mode
|
||||||
|
|
||||||
|
case db_mode.no_db
|
||||||
|
% TX Data is not precoded:
|
||||||
|
|
||||||
|
% A) Emulate diff precoding
|
||||||
|
mlse_sig_hd_precoded = Duobinary().encode(mlse_sig_hd,"M",M);
|
||||||
|
mlse_sig_hd_precoded = Duobinary().decode(mlse_sig_hd_precoded,"M",M);
|
||||||
|
|
||||||
|
tx_symbols_precoded = Duobinary().encode(Symbols);
|
||||||
|
tx_symbols_precoded = Duobinary().decode(tx_symbols_precoded);
|
||||||
|
|
||||||
|
tx_bits_precoded = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(tx_symbols_precoded);
|
||||||
|
rx_bits_mlse = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(mlse_sig_hd_precoded);
|
||||||
|
|
||||||
|
[~,errors_db_diff_precoded,ber_db_diff_precoded,~] = calc_ber(rx_bits_mlse.signal,tx_bits_precoded.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
||||||
|
|
||||||
|
%B) Just determine BER
|
||||||
|
rx_bits_mlse = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(mlse_sig_hd);
|
||||||
|
[bits_mlse,errors_mlse,ber_db,~] = calc_ber(rx_bits_mlse.signal,Tx_bits.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
||||||
|
|
||||||
|
case db_mode.db_precoded
|
||||||
|
|
||||||
|
% Daten SIND TATSÄCHLICH precoded auf TX Seite:
|
||||||
|
|
||||||
|
% A) Decode at Rx if no DB targeting was applied (we are in VNLE or MLSE EQ structure here!
|
||||||
|
mlse_sig_hd_decoded = Duobinary().encode(mlse_sig_hd,"M",M);
|
||||||
|
mlse_sig_hd_decoded = Duobinary().decode(mlse_sig_hd_decoded,"M",M);
|
||||||
|
rx_bits_mlse_decoded = PAMmapper(M,0,"eth_style",0).demap(mlse_sig_hd_decoded);
|
||||||
|
[~,errors_db_diff_precoded,ber_db_diff_precoded,a] = calc_ber(rx_bits_mlse_decoded.signal,Tx_bits.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
||||||
|
burst_db_precoded = count_error_bursts(a, 40);
|
||||||
|
% B) Omit the Coding by comparing with demapped TX symbol sequence
|
||||||
|
|
||||||
|
Tx_bits_ = PAMmapper(M,0,"eth_style",0).demap(Symbols);
|
||||||
|
rx_bits_mlse = PAMmapper(M,0,"eth_style",0).demap(mlse_sig_hd);
|
||||||
|
[bits_db,errors_db,ber_db,a] = calc_ber(rx_bits_mlse.signal,Tx_bits_.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
||||||
|
burst_db = count_error_bursts(a, 40);
|
||||||
|
|
||||||
|
cols = linspecer(8);
|
||||||
|
figure();hold on;
|
||||||
|
stem(1:40,burst_db,'LineWidth',1,'Color',cols(4,:),'Marker','_','DisplayName','w/o diff. precoder');
|
||||||
|
stem(1:40,burst_db_precoded,'LineWidth',1,'Color',cols(3,:),'Marker','.','LineStyle','-','DisplayName','w diff. precoder');
|
||||||
|
xlabel('Bit Error Burst Length')
|
||||||
|
ylabel('Occurence')
|
||||||
|
set(gca, 'yscale', 'log');
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
%% SHOW Loss during training
|
||||||
|
|
||||||
|
mu = logspace(-3,-0.8,12);
|
||||||
|
ber_ml_mlse = zeros(size(mu));
|
||||||
|
ber_training = [];
|
||||||
|
ce_training = [];
|
||||||
|
|
||||||
|
parfor i = 1:numel(mu)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ml_mlse_equalizer = ML_MLSE("epochs_tr",200,"epochs_dd",1,"len_tr",length(Scpe_sig),...
|
||||||
|
"mu_dd",mu(i),"mu_tr",mu(i),"order",11,"sps",2,...
|
||||||
|
"traceback_depth",128,"L",2,"delta",4,'adaptive_mu',0);
|
||||||
|
|
||||||
|
[y_ml_mlse,y_ref] = ml_mlse_equalizer.process(Scpe_sig,Symbols);
|
||||||
|
ref_bits = PAMmapper(M, 0, "eth_style", 0).demap(y_ref);
|
||||||
|
ml_mlse_bits = PAMmapper(M, 0, "eth_style", 0).demap(y_ml_mlse);
|
||||||
|
[~, errors, ber_ml_mlse(i), errpos] = calc_ber(ml_mlse_bits.signal, ref_bits.signal, "skip_front", 10, "skip_end", 10, "returnErrorLocation", 1);
|
||||||
|
fprintf('ML MLSE BER: %.2e \n',ber_ml_mlse(i));
|
||||||
|
|
||||||
|
ber_training(i,:) = ml_mlse_equalizer.ber;
|
||||||
|
ce_training(i,:) = ml_mlse_equalizer.ce;
|
||||||
|
end
|
||||||
|
|
||||||
|
%%
|
||||||
|
figure();hold on
|
||||||
|
|
||||||
|
plot(mu,ber_ml_mlse,'DisplayName','ML-based MLSE');
|
||||||
|
|
||||||
|
beautifyBERplot;
|
||||||
|
xlim([mu(1), mu(end)]);
|
||||||
|
xlabel('mu');
|
||||||
|
ylabel('BER');
|
||||||
|
title('PAM-4; M=3; AWGN Channel');
|
||||||
|
ylim([1e-5 0.1]);
|
||||||
|
|
||||||
|
|
||||||
|
%%
|
||||||
|
figure()
|
||||||
|
hold on;
|
||||||
|
cols = cbrewer2('Spectral',12);
|
||||||
|
for i = 1:12
|
||||||
|
plot(1:200,ber_training(i,:),'DisplayName', sprintf('mu=%.3f ',mu(i)),'Color',cols(i,:));
|
||||||
|
end
|
||||||
|
set(gca,'YScale','log');
|
||||||
|
xlabel('Epoch');
|
||||||
|
ylabel('BER');
|
||||||
|
title('PAM-4; L=3; SNR=20; AWGN Channel');
|
||||||
|
plot(1:200,ml_mlse_equalizer_adap.ber,'DisplayName','Adaptive mu');
|
||||||
13
projects/ML_based_MLSE/interp_fec_cross.m
Normal file
13
projects/ML_based_MLSE/interp_fec_cross.m
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
function rop_fec = interp_fec_cross(rops, ber, fec_thr)
|
||||||
|
if all(~isfinite(ber))
|
||||||
|
rop_fec = NaN; return;
|
||||||
|
end
|
||||||
|
idx = find(ber < fec_thr, 1, 'first');
|
||||||
|
if isempty(idx) || idx == 1
|
||||||
|
rop_fec = NaN; return; % no crossing
|
||||||
|
end
|
||||||
|
% linear interpolation between the two nearest points
|
||||||
|
x1 = rops(idx-1); x2 = rops(idx);
|
||||||
|
y1 = ber(idx-1); y2 = ber(idx);
|
||||||
|
rop_fec = interp1([y1 y2], [x1 x2], fec_thr, 'linear', NaN);
|
||||||
|
end
|
||||||
BIN
projects/ML_based_MLSE/minimal_example_huawei.zip
Normal file
BIN
projects/ML_based_MLSE/minimal_example_huawei.zip
Normal file
Binary file not shown.
555
projects/ML_based_MLSE/minimal_example_huawei/bcjr_pam.m
Normal file
555
projects/ML_based_MLSE/minimal_example_huawei/bcjr_pam.m
Normal file
@@ -0,0 +1,555 @@
|
|||||||
|
classdef bcjr_pam < handle
|
||||||
|
%MLSE calculates the most probable sequence for an input signal with given/ known channel impulse response of any length
|
||||||
|
|
||||||
|
properties(Access=public)
|
||||||
|
M %PAM-M
|
||||||
|
DIR
|
||||||
|
trellis_states
|
||||||
|
duobinary_output
|
||||||
|
end
|
||||||
|
|
||||||
|
methods (Access=public)
|
||||||
|
|
||||||
|
function obj = bcjr_pam(options)
|
||||||
|
%NAME Construct an instance of this class
|
||||||
|
% Detailed explanation goes here
|
||||||
|
|
||||||
|
arguments
|
||||||
|
options.M double = 4;
|
||||||
|
options.DIR double = [1];
|
||||||
|
options.trellis_states double = [-3 -1 1 3];
|
||||||
|
options.duobinary_output logical = false;
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
%
|
||||||
|
fn = fieldnames(options);
|
||||||
|
for n = 1:numel(fn)
|
||||||
|
try
|
||||||
|
obj.(fn{n}) = options.(fn{n});
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function [VITERBI_ESTIMATION_SYMBOLS,LLR_exact,GMI] = process(obj,data_in,data_ref,tx_bits,bit_mapping)
|
||||||
|
|
||||||
|
|
||||||
|
debug = 0;
|
||||||
|
|
||||||
|
% States should match the target states of the prev. EQ (EQ's job was to reduce the error between signal and the target)
|
||||||
|
trellis_state_mode = 2;
|
||||||
|
% 0 = use provided states (MUST provide the correct states);
|
||||||
|
% 1 = normalize to = 1 rms;
|
||||||
|
% 2 = use target symbols;
|
||||||
|
% 3 = use statistical levels
|
||||||
|
% 3 analyzes avg of rx signal levels - can help with nonlinear impairments
|
||||||
|
|
||||||
|
trellis_exclusion = 1; % PAM-6 only (only if data is NOT precoded!)
|
||||||
|
|
||||||
|
% Additional scaling between states, expected output (noiseless_received) and the noisy, filtered input signal
|
||||||
|
scale_mode = 2; % scale_mode:
|
||||||
|
% 0 = no scaling,
|
||||||
|
% 1 = use RMS to scale MODEL,
|
||||||
|
% 2 = use MMSE/time-corr to scale MODEL, -> This best to get the GMI right -> sometimes the LLP's are not centered around zero...
|
||||||
|
% 3 = use RMS to scale DATA,
|
||||||
|
% 4 = use MMSE/time-corr to scale DATA
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
%%%%%% PREPARATIONS %%%%%%%%
|
||||||
|
|
||||||
|
% remove unnecessary zeros at start of impulse response to keep
|
||||||
|
% number of trellis states minimal
|
||||||
|
DIR_nonzero = find(obj.DIR ~= 0);
|
||||||
|
if DIR_nonzero(1) > 1
|
||||||
|
obj.DIR(1:DIR_nonzero(1)-1) = [];
|
||||||
|
end
|
||||||
|
|
||||||
|
if isscalar(obj.DIR)
|
||||||
|
obj.DIR = [0 obj.DIR];
|
||||||
|
end
|
||||||
|
|
||||||
|
% impulse respnse to remove from signal
|
||||||
|
obj.DIR = flip(obj.DIR); %i.e. -0.2676 -0.0478 1.0000
|
||||||
|
|
||||||
|
% Trellis States
|
||||||
|
obj.trellis_states = reshape(obj.trellis_states,1,[]);
|
||||||
|
if trellis_state_mode == 1 % Normalize the Trellis states to =1 RMS
|
||||||
|
|
||||||
|
obj.trellis_states = obj.trellis_states ./ rms(obj.trellis_states);
|
||||||
|
|
||||||
|
elseif trellis_state_mode == 2 %simply use the states from the ref signal (should be a robust option)
|
||||||
|
|
||||||
|
obj.trellis_states = reshape(unique(data_ref),size(obj.trellis_states));
|
||||||
|
|
||||||
|
elseif trellis_state_mode == 3 %use_statistical_levels
|
||||||
|
|
||||||
|
%%%% Separate the equalized signal into the respective levels based on the actually transmitted level
|
||||||
|
constellation = unique(data_ref);
|
||||||
|
|
||||||
|
% find actual levels from rx signal
|
||||||
|
symbols_for_lvl = NaN(numel(constellation),length(data_ref));
|
||||||
|
for l = 1:numel(constellation)
|
||||||
|
level_amplitude = constellation(l);
|
||||||
|
symbols_for_lvl(l,data_ref==level_amplitude) = data_in(data_ref==level_amplitude);
|
||||||
|
end
|
||||||
|
|
||||||
|
%replace the trellis states
|
||||||
|
avg_levels = mean(symbols_for_lvl,2,'omitnan');
|
||||||
|
obj.trellis_states = sort(avg_levels)';
|
||||||
|
|
||||||
|
%also replace the whole ref signal (PAM-M) levels
|
||||||
|
[~, idx] = ismember(data_ref, unique(data_ref));
|
||||||
|
data_ref = avg_levels(idx);
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
% seems to be the only way to use combvec for a flexible amount
|
||||||
|
% of vectors. 'combs' contains all trellis states
|
||||||
|
pre_comb_mat = repmat(obj.trellis_states,length(obj.DIR)-1,1);
|
||||||
|
pre_comb_cell = mat2cell(pre_comb_mat,ones(1,size(pre_comb_mat,1)),size(pre_comb_mat,2));
|
||||||
|
combs = fliplr(combvec(pre_comb_cell{:}).');
|
||||||
|
first_sym = combs(:,1); % das ist das älteste/ trailing Symbol aus der sequenz
|
||||||
|
last_sym = combs(:,end); %hiermit wird entschieden/ das ist das cursor symbol am ende der sequenz
|
||||||
|
nStates = length(last_sym);
|
||||||
|
|
||||||
|
% % 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
|
||||||
|
% assumes: last_sym = combs(:,end); % already defined earlier
|
||||||
|
levels = sort(unique(obj.trellis_states(:)).');
|
||||||
|
edges = [levels(1) levels(end)]; % edge levels (0 and 5 in PAM6)
|
||||||
|
|
||||||
|
noise_free_received = inf(nStates,nStates); % rows: to, cols: from
|
||||||
|
edge_edge_mask = false(nStates,nStates); % rows: to, cols: from
|
||||||
|
|
||||||
|
for from = 1:nStates
|
||||||
|
for to = 1:nStates
|
||||||
|
% valid transition if shift-register overlap holds
|
||||||
|
if all(combs(to,2:end) == combs(from,1:end-1))
|
||||||
|
% noiseless sample for the 'to' state reached from 'from'
|
||||||
|
noise_free_received(to,from) = ...
|
||||||
|
dot(combs(to,:), obj.DIR(end:-1:2)) + last_sym(from)*obj.DIR(1);
|
||||||
|
|
||||||
|
% mark edge→edge candidate (to be excluded only on even→odd steps)
|
||||||
|
edge_edge_mask(to,from) = ...
|
||||||
|
(last_sym(from)==edges(1) || last_sym(from)==edges(2)) && ...
|
||||||
|
(last_sym(to) ==edges(1) || last_sym(to) ==edges(2));
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
h = flip(obj.DIR(:)).';
|
||||||
|
data_in = data_in(:);
|
||||||
|
y_ideal = conv(data_ref(:), h, "same");
|
||||||
|
|
||||||
|
switch scale_mode
|
||||||
|
case 0
|
||||||
|
g = 1; b = 0;
|
||||||
|
case 1 % RMS: scale model to data
|
||||||
|
g = rms(data_in)/rms(y_ideal); b = mean(data_in) - g*mean(y_ideal);
|
||||||
|
case 2 % MMSE/time-corr: scale states to data
|
||||||
|
[c,lags] = xcorr(data_in(:), y_ideal, 64);
|
||||||
|
[~,ix] = max(abs(c));
|
||||||
|
lag = lags(ix);
|
||||||
|
y_ideal = circshift(y_ideal, lag);
|
||||||
|
mu_y = mean(data_in(:));
|
||||||
|
mu_i = mean(y_ideal);
|
||||||
|
y_c = data_in(:)-mu_y;
|
||||||
|
yi_c = y_ideal-mu_i;
|
||||||
|
g = (yi_c'*y_c)/(yi_c'*yi_c);
|
||||||
|
b = mu_y - g*mu_i;
|
||||||
|
case 3 % RMS flipped: scale data to model
|
||||||
|
gd = rms(y_ideal)/rms(data_in); bd = mean(y_ideal) - gd*mean(data_in);
|
||||||
|
data_in = gd*data_in + bd;
|
||||||
|
g = 1; b = 0;
|
||||||
|
case 4 % MMSE/time-corr flipped: scale data to states
|
||||||
|
[c,lags] = xcorr(data_in(:), y_ideal(:), 64);
|
||||||
|
[~,ix] = max(abs(c));
|
||||||
|
lag = lags(ix);
|
||||||
|
y_ideal = circshift(y_ideal(:), lag);
|
||||||
|
mu_y = mean(data_in(:));
|
||||||
|
mu_i = mean(y_ideal);
|
||||||
|
y_c = data_in(:) - mu_y; % data_in centered
|
||||||
|
yi_c = y_ideal - mu_i; % ideal centered
|
||||||
|
g = (y_c' * yi_c) / (y_c' * y_c);
|
||||||
|
b = mu_i - g * mu_y;
|
||||||
|
data_in = g * data_in(:) + b;
|
||||||
|
g = 1; b = 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
% apply (g,b) to states/ expected values
|
||||||
|
noise_free_received = g*noise_free_received + b;
|
||||||
|
last_sym = g*last_sym + b;
|
||||||
|
|
||||||
|
% calculate noise power
|
||||||
|
sigma2 = mean(abs(data_in - (g*y_ideal + b)).^2); %noise = mean(abs((RX Signal - IDEAL Signal)))^2
|
||||||
|
inv2s2 = 1/(2*sigma2);
|
||||||
|
|
||||||
|
if debug
|
||||||
|
figure(100); clf; hold on
|
||||||
|
obj.showLevelScatter_(data_in, data_ref);
|
||||||
|
yline(noise_free_received(:), 'DisplayName','Transition States','Color','red','HandleVisibility','off');
|
||||||
|
yline(obj.trellis_states(:), 'DisplayName','Transition States','Color','green','LineWidth',2,'HandleVisibility','off')
|
||||||
|
end
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
%%%%% FORWARD PASS (VITERBI -Alpha's) %%%%%
|
||||||
|
|
||||||
|
% Initialize the output vector
|
||||||
|
pm = zeros(nStates,nStates);
|
||||||
|
bm_fw = zeros(nStates,nStates,length(data_in));
|
||||||
|
|
||||||
|
% first start is evaluated without ISI/ wihout the full Impulse response
|
||||||
|
% so simply use the constellation here
|
||||||
|
bm = -(data_in(1) - last_sym).^2 * inv2s2;
|
||||||
|
pm = pm + bm;
|
||||||
|
[alpha(:,1),pm_survivor_fw_idx(:,1)] = max(pm,[],2);
|
||||||
|
pm = repmat(alpha(:,1).',nStates,1);
|
||||||
|
bm_fw(:,:,1) = pm;
|
||||||
|
|
||||||
|
% Forward Recursion (FSM Computation)
|
||||||
|
for n = 2:length(data_in)
|
||||||
|
|
||||||
|
bm = -(data_in(n) - noise_free_received).^2 * inv2s2;
|
||||||
|
|
||||||
|
% exclude edge to edge transitions only for even->odd steps && PAM-6
|
||||||
|
if mod(n,2) == 0 && obj.M == 6 && trellis_exclusion
|
||||||
|
bm(edge_edge_mask) = -Inf;
|
||||||
|
end
|
||||||
|
|
||||||
|
pm = pm + bm;
|
||||||
|
[alpha(:,n),pm_survivor_fw_idx(:,n)] = max(pm,[],2); % choose lowest path metric as new state (get min distance for all state transitions towards a new state)
|
||||||
|
pm = repmat(alpha(:,n).',nStates,1); % update pm (chosen state to 2nd dimension -> FROM state)
|
||||||
|
|
||||||
|
bm_fw(:,:,n) = bm;
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
% we can now get the best path as min
|
||||||
|
viterbi_path = NaN(1,length(data_in));
|
||||||
|
|
||||||
|
% find ideal trellis path by going through the trellis backwards
|
||||||
|
[~,viterbi_path(length(data_in))] = max(alpha(:,length(data_in)));
|
||||||
|
for n = length(data_in):-1:2
|
||||||
|
viterbi_path(n-1) = pm_survivor_fw_idx(viterbi_path(n),n);
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if debug
|
||||||
|
alpha_ = alpha - min(alpha) + eps;
|
||||||
|
figure();hold on;
|
||||||
|
n = 10;
|
||||||
|
scatter(1:n,obj.trellis_states(repmat([1:numel(obj.trellis_states)]',1,n)),abs(alpha_(:,end-n+1:end)),'Marker','o','LineWidth',1);
|
||||||
|
scatter(1:n,obj.trellis_states(viterbi_path(end-n+1:end)),500,'Marker','x','LineWidth',1,'MarkerEdgeColor','green');
|
||||||
|
% scatter(1:n,data_ref(end-n+1:end),500,'Marker','x','LineWidth',1,'MarkerEdgeColor','red');
|
||||||
|
yticks(obj.trellis_states);
|
||||||
|
ylim([min(obj.trellis_states)-1 max(obj.trellis_states)+1]);
|
||||||
|
end
|
||||||
|
|
||||||
|
VITERBI_ESTIMATION_SYMBOLS(1:length(data_in)) = first_sym(viterbi_path);
|
||||||
|
VITERBI_ESTIMATION_SYMBOLS = reshape(VITERBI_ESTIMATION_SYMBOLS,size(data_in));
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
%%%%% BACKWARD (Beta's) %%%%%
|
||||||
|
|
||||||
|
% Initialize the output vector
|
||||||
|
pm = zeros(nStates,nStates);
|
||||||
|
beta = zeros(nStates,length(data_in));
|
||||||
|
pm_survivor_bw_idx = zeros(nStates,length(data_in));
|
||||||
|
bm_bw = zeros(nStates,nStates,length(data_in));
|
||||||
|
|
||||||
|
% 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:1
|
||||||
|
|
||||||
|
bm = -(data_in(h+1) - noise_free_received).^2 * inv2s2;
|
||||||
|
|
||||||
|
% exclude edge to edge transitions for even->odd steps && PAM-6
|
||||||
|
if mod(h+1, 2) == 0 && obj.M == 6 && trellis_exclusion
|
||||||
|
bm(edge_edge_mask) = -Inf;
|
||||||
|
end
|
||||||
|
|
||||||
|
pm = pm + bm.';
|
||||||
|
[beta(:,h),pm_survivor_bw_idx(:,h)] = max(pm,[],2); % choose lowest path metric as new state
|
||||||
|
pm = repmat(beta(:,h).',nStates,1); % update pm (chosen state to 2nd dimension -> FROM state)
|
||||||
|
|
||||||
|
bm_bw(:,:,h) = bm;
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
%%%%% FORWARD (Combine Alpha and Beta to yield LLP's) %%%%%
|
||||||
|
|
||||||
|
%calc the log probabilities (llp's)
|
||||||
|
|
||||||
|
for k = 1:length(data_in)
|
||||||
|
|
||||||
|
if k == 1
|
||||||
|
|
||||||
|
alpha_ = repmat(alpha(:,k)',[nStates,1])';
|
||||||
|
beta_ = beta(:,k);
|
||||||
|
|
||||||
|
LLP(:,k) = max(alpha_ + beta_,[],2);
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
alpha_ = repmat(alpha(:,k-1)',[nStates,1])';
|
||||||
|
gamma_ = bm_fw(:,:,k)';
|
||||||
|
beta_ = beta(:,k);
|
||||||
|
|
||||||
|
LLP(:,k) = max(alpha_ + gamma_,[],1) + beta_';
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
%%%%% Calc LLR's %%%%%
|
||||||
|
|
||||||
|
% These are interchangeable...
|
||||||
|
nml_LLP = LLP - max(LLP); %subtract highest value for better numerical stability, LLP's are not always close to zero
|
||||||
|
expLLP = exp(nml_LLP);
|
||||||
|
state_prob = expLLP ./ sum(expLLP); % sums to one (or numerically close to one)
|
||||||
|
|
||||||
|
% compute symbol‐posteriors from LLP in the log‐domain:
|
||||||
|
amax = max(LLP,[],1);
|
||||||
|
logZ = amax + log(sum(exp(LLP - amax), 1));
|
||||||
|
logPstate = LLP - logZ; % still in log‐domain
|
||||||
|
state_prob = exp(logPstate); % exact, sums to 1
|
||||||
|
|
||||||
|
if obj.M == 6
|
||||||
|
|
||||||
|
num_bits = 5;
|
||||||
|
|
||||||
|
% all possible transitions (for now 36, including the "edges"
|
||||||
|
% of the QAM 32 constellation)
|
||||||
|
states = [-5 -3 -1 1 3 5];
|
||||||
|
pam6transitions = combvec(states,states)'; % pam6transitions =
|
||||||
|
% [-5 -5;
|
||||||
|
% -3 -5;
|
||||||
|
% -1 -5; ...
|
||||||
|
|
||||||
|
[~, idx_sym_1] = ismember(pam6transitions(:,1), states);
|
||||||
|
[~, idx_sym_2] = ismember(pam6transitions(:,2), states);
|
||||||
|
pam6ind = [idx_sym_1, idx_sym_2];
|
||||||
|
|
||||||
|
numPairs = floor(size(LLP,2)/2);
|
||||||
|
LLR_exact = zeros(numPairs,5);
|
||||||
|
LLR_maxlogmap = zeros(numPairs,5);
|
||||||
|
|
||||||
|
for k = 1:numPairs
|
||||||
|
symbol1 = 2*k-1;
|
||||||
|
symbol2 = 2*k;
|
||||||
|
|
||||||
|
LLP1 = LLP(:,symbol1);
|
||||||
|
LLP2 = LLP(:,symbol2);
|
||||||
|
prob1 = state_prob(:,symbol1);
|
||||||
|
prob2 = state_prob(:,symbol2);
|
||||||
|
|
||||||
|
% All 36 Combinations: M = LLP Symbol 1 + LLP Symbol 2
|
||||||
|
Mij = LLP1(pam6ind(:,1)) + LLP2(pam6ind(:,2));
|
||||||
|
pij = prob1(pam6ind(:,1)) .* prob2(pam6ind(:,2));
|
||||||
|
|
||||||
|
% for each of the 5 bits sum exact-probs or max-log
|
||||||
|
for b = 1:num_bits
|
||||||
|
idx_sym_1 = bit_mapping(:,b)==1;
|
||||||
|
idx_bit_1 = bit_mapping(:,b)==0;
|
||||||
|
|
||||||
|
% exact LLR from probabilities
|
||||||
|
P1 = sum(pij(idx_sym_1)); %prob that bit == 1
|
||||||
|
P0 = sum(pij(idx_bit_1));
|
||||||
|
LLR_exact(k,b) = log(P1./P0); %ratio by multiplication
|
||||||
|
|
||||||
|
% max-log:
|
||||||
|
LLR_maxlogmap(k,b) = max( Mij(idx_sym_1) ) - max( Mij(idx_bit_1) ); % ratio by subtraction
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
% GMI calc includes the Tx-bitstream
|
||||||
|
tx_bits_pam6_reshaped = reshape(tx_bits',5,[])'; % N x 5
|
||||||
|
MI = zeros(1, num_bits);
|
||||||
|
for k = 1:num_bits
|
||||||
|
|
||||||
|
idx_bit_1 = (tx_bits_pam6_reshaped(:,k) == 0); %wo sind die 1en
|
||||||
|
idx_sym_1 = (tx_bits_pam6_reshaped(:,k) == 1); %wo sind die 0en
|
||||||
|
|
||||||
|
%LLR's for all actually transmitted ones or zeros
|
||||||
|
llr0 = LLR_exact(idx_bit_1,k);
|
||||||
|
llr1 = LLR_exact(idx_sym_1,k);
|
||||||
|
|
||||||
|
% Calculate mutual information for bit position k
|
||||||
|
I0 = mean(log2(1 + exp(llr0))); % exp(--LLR) = exp(positive) > 1
|
||||||
|
I1 = mean(log2(1 + exp(-llr1))); % exp(-+LLR) = exp(negative) < 1
|
||||||
|
MI(k) = 1 - 0.5 * (I0 + I1);
|
||||||
|
end
|
||||||
|
|
||||||
|
GMI = sum(MI); % Total mutual information per symbol
|
||||||
|
GMI = GMI/2; % GMI per single symbol not per two symbols
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
% Number of symbols and bits per symbol
|
||||||
|
num_bits = log2(length(obj.trellis_states)); % 2 bits per symbol
|
||||||
|
|
||||||
|
% bit_mapping = PAMmapper(length(obj.trellis_states),0,"eth_style",0).showBitMapping;
|
||||||
|
|
||||||
|
% Initialize LLR storage
|
||||||
|
LLR_maxlogmap = zeros(length(data_in),num_bits);
|
||||||
|
LLR_exact = zeros(length(data_in),num_bits);
|
||||||
|
|
||||||
|
% Compute bit-wise LLRs
|
||||||
|
for bit_idx = 1:num_bits
|
||||||
|
|
||||||
|
% Find indices where bit is 0 and where it is 1
|
||||||
|
idx_bit_0 = bit_mapping(:,bit_idx) == 0;
|
||||||
|
idx_bit_1 = bit_mapping(:,bit_idx) == 1;
|
||||||
|
|
||||||
|
% Sum over log-probabilities
|
||||||
|
% Max-Log approximation uses the single max LLP value
|
||||||
|
% instead of sum over all LLP's
|
||||||
|
LLR_maxlogmap(:,bit_idx) = max(LLP(idx_bit_1,:), [], 1) - max(LLP(idx_bit_0,:), [], 1);
|
||||||
|
|
||||||
|
% Sum probabilities over states for which the bit is 1 and 0, respectively.
|
||||||
|
P0 = sum(state_prob(idx_bit_0, :),1);
|
||||||
|
P1 = sum(state_prob(idx_bit_1, :),1);
|
||||||
|
LLR_exact(:,bit_idx) = log(P1./P0); % N x num_bits
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
%%%%% CALC NGMI %%%%%
|
||||||
|
|
||||||
|
MI = zeros(1, num_bits);
|
||||||
|
for k = 1:num_bits
|
||||||
|
|
||||||
|
idx_bit_0 = (tx_bits(:,k) == 0); %wo sind die 1en
|
||||||
|
idx_bit_1 = (tx_bits(:,k) == 1); %wo sind die 0en
|
||||||
|
|
||||||
|
%LLR's for all actually transmitted ones or zeros
|
||||||
|
llr0 = LLR_exact(idx_bit_0,k);
|
||||||
|
llr1 = LLR_exact(idx_bit_1,k);
|
||||||
|
|
||||||
|
% mutual information for bit position k
|
||||||
|
I0 = mean(log2(1 + exp(llr0))); % exp(--LLR) = exp(positive) > 1
|
||||||
|
I1 = mean(log2(1 + exp(-llr1))); % exp(-+LLR) = exp(negative) < 1
|
||||||
|
MI(k) = 1 - 0.5 * (I0 + I1); % assumes equally distributed ones and zeros
|
||||||
|
end
|
||||||
|
|
||||||
|
GMI = sum(MI); % Total bitwise mutual information
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if debug
|
||||||
|
%%% DEBUG PLOT LIKELIHOOD RATIOS %%%
|
||||||
|
figure(115);clf
|
||||||
|
subplot(2,1,1)
|
||||||
|
for bit = 1:num_bits
|
||||||
|
hold on;
|
||||||
|
histogram(LLR_exact(:,bit),1000,"DisplayName",sprintf('Actual LLR of Bit Pos %d',bit),'LineStyle','none','FaceAlpha',0.4);
|
||||||
|
end
|
||||||
|
legend
|
||||||
|
|
||||||
|
subplot(2,1,2)
|
||||||
|
for bit = 1:num_bits
|
||||||
|
hold on;
|
||||||
|
histogram(LLR_maxlogmap(:,bit),1000,"DisplayName",sprintf('Max Log LLR of Bit Pos %d',bit),'LineStyle','none','FaceAlpha',0.4);
|
||||||
|
end
|
||||||
|
legend
|
||||||
|
|
||||||
|
if obj.M == 6
|
||||||
|
pairs = reshape(VITERBI_ESTIMATION_SYMBOLS,2,[]).';
|
||||||
|
levels = sort(unique(VITERBI_ESTIMATION_SYMBOLS));
|
||||||
|
isedge = ismember(pairs, [levels(1) levels(end)]);
|
||||||
|
isforbidden = sum(isedge,2)==2;
|
||||||
|
fprintf('Found %d forbidden transitions (even -> odd ; edge -> edge).\n', nnz(isforbidden));
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function [symbols_for_lvl,avg_for_lvl] = showLevelScatter_(~,eq_signal,ref_symbols)
|
||||||
|
|
||||||
|
figure()
|
||||||
|
|
||||||
|
rx_symbols = eq_signal; %./ rms(eq_signal);
|
||||||
|
correct_symbols = ref_symbols;
|
||||||
|
|
||||||
|
% col = cbrewer2('Paired',numel(unique(correct_symbols))*2);
|
||||||
|
col = ...
|
||||||
|
[0.6510 0.8078 0.8902; ...
|
||||||
|
0.1216 0.4706 0.7059; ...
|
||||||
|
0.6980 0.8745 0.5412; ...
|
||||||
|
0.2000 0.6275 0.1725; ...
|
||||||
|
0.9843 0.6039 0.6000; ...
|
||||||
|
0.8902 0.1020 0.1098; ...
|
||||||
|
0.9922 0.7490 0.4353; ...
|
||||||
|
1.0000 0.4980 0; ...
|
||||||
|
0.7922 0.6980 0.8392; ...
|
||||||
|
0.4157 0.2392 0.6039; ...
|
||||||
|
1.0000 1.0000 0.6000; ...
|
||||||
|
0.6941 0.3490 0.1569; ...
|
||||||
|
0.6510 0.8078 0.8902; ...
|
||||||
|
0.1216 0.4706 0.7059; ...
|
||||||
|
0.6980 0.8745 0.5412; ...
|
||||||
|
0.2000 0.6275 0.1725];
|
||||||
|
ccnt = -1;
|
||||||
|
|
||||||
|
levels = unique(correct_symbols);
|
||||||
|
symbols_for_lvl = NaN(numel(levels),length(correct_symbols));
|
||||||
|
start = 1;
|
||||||
|
ende = length(correct_symbols);
|
||||||
|
|
||||||
|
for l = 1:numel(levels)
|
||||||
|
ccnt = ccnt+2;
|
||||||
|
|
||||||
|
level_amplitude = levels(l);
|
||||||
|
|
||||||
|
symbols_for_lvl(l,correct_symbols==level_amplitude) = rx_symbols(correct_symbols==level_amplitude);
|
||||||
|
std_lvl(l) = std(symbols_for_lvl(l,:),'omitnan');
|
||||||
|
xax = 1:length(correct_symbols);
|
||||||
|
|
||||||
|
scatter(xax(start:ende),symbols_for_lvl(l,start:ende),10,'.','MarkerFaceAlpha',0.5,'MarkerEdgeAlpha',0.5,'MarkerEdgeColor',col(ccnt,:));
|
||||||
|
hold on;
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
std_lvl = round(std_lvl,2);
|
||||||
|
|
||||||
|
ccnt = 0;
|
||||||
|
avg_for_lvl = NaN(numel(levels),length(correct_symbols));
|
||||||
|
% Add the windowed/ smoothed curves
|
||||||
|
for l = 1:numel(levels)
|
||||||
|
ccnt = ccnt+2;
|
||||||
|
level_amplitude = levels(l);
|
||||||
|
|
||||||
|
L = 500;
|
||||||
|
movmean = 1/L .* movsum(rx_symbols(correct_symbols==level_amplitude),[L/2,L/2], 'Endpoints', 'fill');
|
||||||
|
|
||||||
|
avg_for_lvl(l,correct_symbols==level_amplitude) = movmean;
|
||||||
|
|
||||||
|
nanx = isnan(avg_for_lvl(l,:));
|
||||||
|
t = 1:numel(avg_for_lvl(l,:));
|
||||||
|
avg_for_lvl(l,nanx) = interp1(t(~nanx), avg_for_lvl(l,~nanx), t(nanx));
|
||||||
|
|
||||||
|
plot(xax(start:ende),avg_for_lvl(l,start:ende),'Color',col(ccnt,:));
|
||||||
|
|
||||||
|
hold on
|
||||||
|
end
|
||||||
|
|
||||||
|
% yline(levels);
|
||||||
|
xlabel('Samples');
|
||||||
|
ylabel('Amplitude');
|
||||||
|
ylim([-3 3]);
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
193
projects/ML_based_MLSE/minimal_example_huawei/minimal_example.m
Normal file
193
projects/ML_based_MLSE/minimal_example_huawei/minimal_example.m
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
|
||||||
|
if 0
|
||||||
|
% A) RUN FULL LOOP
|
||||||
|
M_format = [2,4,6,8];
|
||||||
|
snr = 10:25;
|
||||||
|
else
|
||||||
|
% B) RUN FOR DEBUG AND TEST
|
||||||
|
M_format = 4;
|
||||||
|
snr = 20;
|
||||||
|
end
|
||||||
|
|
||||||
|
for m = 1:length(M_format)
|
||||||
|
% --- Parameters ---
|
||||||
|
M = M_format(m); % PAM order (e.g., 2,4,8)
|
||||||
|
Nsym = 1e5; % number of symbols
|
||||||
|
h = [1, 0.5, 0.2]; % Impulse response to remove
|
||||||
|
|
||||||
|
b = log2(M);
|
||||||
|
if M == 6 b = 5; end
|
||||||
|
rng(1);
|
||||||
|
bits_tx = logical(randi([0 1], Nsym, b, 'uint8'));
|
||||||
|
|
||||||
|
tx_symbols = pammap(bits_tx,M);
|
||||||
|
|
||||||
|
if M == 6
|
||||||
|
states = unique(tx_symbols);
|
||||||
|
pam6transitions = combvec(states',states')'; % pam6transitions =
|
||||||
|
bitmapping = pamdemap(reshape(pam6transitions',1,[])',M);
|
||||||
|
else
|
||||||
|
bitmapping = pamdemap(unique(tx_symbols),M);
|
||||||
|
end
|
||||||
|
|
||||||
|
scaling = sqrt(sum(unique(tx_symbols).^2)/numel(unique(tx_symbols)));
|
||||||
|
tx_symbols = tx_symbols ./ scaling;
|
||||||
|
|
||||||
|
% apply impulse response to signal
|
||||||
|
y_filt = filter(h, 1, tx_symbols);
|
||||||
|
|
||||||
|
for s = 1:length(snr)
|
||||||
|
|
||||||
|
% apply noise
|
||||||
|
y = awgn(y_filt,snr(s),"measured",1);
|
||||||
|
|
||||||
|
% apply ml-MLSE
|
||||||
|
adaptive_mu = 0;
|
||||||
|
mu_lms = 0.15;
|
||||||
|
ml_mlse_equalizer = ml_mlse_pam("epochs_tr",50,"epochs_dd",1,"len_tr",length(y)/2,...
|
||||||
|
"mu_dd",mu_lms,"mu_tr",mu_lms,"order",11,"sps",1,...
|
||||||
|
"L",2,"delta",4,"adaptive_mu",adaptive_mu);
|
||||||
|
|
||||||
|
[ml_mlse_estimate,~] = ml_mlse_equalizer.process(y,tx_symbols);
|
||||||
|
rx_symbols = ml_mlse_estimate .* scaling;
|
||||||
|
bits_rx = pamdemap(rx_symbols,M);
|
||||||
|
|
||||||
|
BER_ml(m,s) = nnz(bits_tx ~= bits_rx) / numel(bits_tx);
|
||||||
|
fprintf('BER = %.2e \n', BER_ml(m,s));
|
||||||
|
|
||||||
|
|
||||||
|
% apply bcjr
|
||||||
|
BCJR = bcjr_pam("DIR",h,"duobinary_output",0,"M",M,"trellis_states",unique(tx_symbols));
|
||||||
|
[viterbi_estimate,LLR,GMI(m,s)] = BCJR.process(y,tx_symbols,bits_tx,bitmapping);
|
||||||
|
|
||||||
|
% decode LLR's
|
||||||
|
bits_LLR = LLR > 0;
|
||||||
|
|
||||||
|
% demap viterbi symbols sequence
|
||||||
|
rx_symbols = viterbi_estimate .* scaling;
|
||||||
|
bits_rx = pamdemap(rx_symbols,M);
|
||||||
|
|
||||||
|
% BER calc
|
||||||
|
BER_vit(m,s) = nnz(bits_tx ~= bits_LLR) / numel(bits_tx);
|
||||||
|
fprintf('BER LLR = %.2e \n', BER_vit(m,s));
|
||||||
|
|
||||||
|
BER_llr(m,s) = nnz(bits_tx ~= bits_rx) / numel(bits_tx);
|
||||||
|
fprintf('BER = %.2e \n', BER_llr(m,s));
|
||||||
|
end
|
||||||
|
end
|
||||||
|
%%
|
||||||
|
figure();hold on
|
||||||
|
for m = 1:length(M_format)
|
||||||
|
p=plot(snr,BER_llr(m,:),'DisplayName',sprintf('Viterbi: PAM %d',M_format(m)));
|
||||||
|
plot(snr,BER_ml(m,:),'DisplayName',sprintf('ML-Based: PAM %d',M_format(m)),'LineStyle',':','Color',p.Color);
|
||||||
|
end
|
||||||
|
ylabel('BER');
|
||||||
|
xlabel('SNR')
|
||||||
|
title('BER vs. SNR');
|
||||||
|
set(gca, 'XScale', 'linear', ...
|
||||||
|
'YScale', 'log', ...
|
||||||
|
'TickLabelInterpreter', 'latex', ...
|
||||||
|
'FontSize', 11);
|
||||||
|
|
||||||
|
%%
|
||||||
|
figure();hold on
|
||||||
|
for m = 1:length(M_format)
|
||||||
|
plot(snr,GMI(m,:),'DisplayName',sprintf('GMI PAM %d',M_format(m)))
|
||||||
|
end
|
||||||
|
ylabel('GMI');
|
||||||
|
xlabel('SNR')
|
||||||
|
title('GMI vs. SNR');
|
||||||
|
set(gca, 'XScale', 'linear', ...
|
||||||
|
'YScale', 'linear', ...
|
||||||
|
'TickLabelInterpreter', 'latex', ...
|
||||||
|
'FontSize', 11);
|
||||||
|
|
||||||
|
function symbols = pammap(bits,M)
|
||||||
|
bits = logical(bits);
|
||||||
|
if M == 2
|
||||||
|
symbols = bits;
|
||||||
|
elseif M == 4
|
||||||
|
symbols= 2*bits(:,1) + (bits(:,1)==bits(:,2));
|
||||||
|
symbols=2*symbols-3;
|
||||||
|
|
||||||
|
elseif M == 6
|
||||||
|
|
||||||
|
m = 1;
|
||||||
|
|
||||||
|
if size(bits,2)>size(bits,1)
|
||||||
|
bits = bits'; %vector aufrecht stellen
|
||||||
|
end
|
||||||
|
bits = reshape(bits',1,[])';
|
||||||
|
thres = [-3 5;-1 5;-3 -5;-1 -5;-5 3;-5 1;-5 -3;-5 -1;-1 3;-1 1;-1 -3;-1 -1;-3 3;-3 1;-3 -3;-3 -1;3 5;1 5;3 -5;1 -5;5 3;5 1;5 -3;5 -1;1 3;1 1;1 -3;1 -1;3 3;3 1;3 -3;3 -1];
|
||||||
|
% LUT based mapping
|
||||||
|
for k = 1:5:fix(length(bits)/5)*5
|
||||||
|
symbols(m:m+1,1) = thres(bin2dec(int2str(bits(k:k+4)'))+1,:);
|
||||||
|
m = m+2;
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif M == 8
|
||||||
|
x1 = bits(:,1);
|
||||||
|
x2 = (bits(:,1)==bits(:,3));
|
||||||
|
x3 = x2~=bits(:,2);
|
||||||
|
|
||||||
|
symbols = 4*x1 + 2*x2 + x3;
|
||||||
|
symbols=2*symbols-7;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function bits = pamdemap(symbols,M)
|
||||||
|
|
||||||
|
if M == 2
|
||||||
|
thres=0;
|
||||||
|
elseif M == 4
|
||||||
|
thres=[-2,0,2];
|
||||||
|
elseif M == 6
|
||||||
|
thres = [-3 5;-1 5;-3 -5;-1 -5;-5 3;-5 1;-5 -3;-5 -1;-1 3;-1 1;-1 -3;-1 -1;-3 3;-3 1;-3 -3;-3 -1;3 5;1 5;3 -5;1 -5;5 3;5 1;5 -3;5 -1;1 3;1 1;1 -3;1 -1;3 3;3 1;3 -3;3 -1];
|
||||||
|
elseif M == 8
|
||||||
|
thres=-6:2:6;
|
||||||
|
end
|
||||||
|
|
||||||
|
if M ~= 6
|
||||||
|
symbols = symbols';
|
||||||
|
a = squeeze(repmat(real(symbols),[1 1 length(thres)])); %Eingangssignal in 3 spalten
|
||||||
|
b = squeeze(repmat(reshape(thres(:).',[1 1 length(thres)]),[1 length(symbols) 1])); %Threshold in 3 Spalten
|
||||||
|
comp_real = a > b; %check for each symbol/ sampling if it exeeds the obj.thresholdseshold 1, 2 or 3
|
||||||
|
comp_real=repmat(real(symbols),[1 1 length(thres)]) > repmat(reshape(thres(:).',[1 1 length(thres)]),[1 length(symbols) 1]);
|
||||||
|
s1=size(comp_real,1);
|
||||||
|
s2=size(comp_real,2);
|
||||||
|
end
|
||||||
|
|
||||||
|
if M == 2
|
||||||
|
data_out=abs(comp_real(:,:,1));
|
||||||
|
elseif M == 4
|
||||||
|
data_out=[comp_real(:,:,2); ones(s1,s2) - comp_real(:,:,1) + comp_real(:,:,3)];
|
||||||
|
elseif M == 6
|
||||||
|
|
||||||
|
if size(symbols,2) > 1
|
||||||
|
symbols = symbols.';
|
||||||
|
end
|
||||||
|
|
||||||
|
if length(symbols)/2 ~= round(length(symbols)/2)
|
||||||
|
symbols = [symbols;0];
|
||||||
|
end
|
||||||
|
|
||||||
|
m = 1;
|
||||||
|
for n = 1:2:length(symbols)
|
||||||
|
dist = sqrt((symbols(n)-thres(:,1)).^2+(symbols(n+1)-thres(:,2)).^2);
|
||||||
|
[~,dd_idx] = min(dist);
|
||||||
|
% dec_out(n:n+1) = LUT(dd_idx,:);
|
||||||
|
data_out(m:m+4) = bitget(dd_idx-1,5:-1:1);
|
||||||
|
m = m+5;
|
||||||
|
end
|
||||||
|
|
||||||
|
data_out = reshape(data_out',5,[]);
|
||||||
|
|
||||||
|
elseif M == 8
|
||||||
|
data_out=[comp_real(:,:,4);
|
||||||
|
comp_real(:,:,1)-comp_real(:,:,3)+comp_real(:,:,5)-comp_real(:,:,7);
|
||||||
|
1-comp_real(:,:,2)+comp_real(:,:,6)];
|
||||||
|
end
|
||||||
|
|
||||||
|
bits = data_out';
|
||||||
|
|
||||||
|
end
|
||||||
473
projects/ML_based_MLSE/minimal_example_huawei/ml_mlse_pam.m
Normal file
473
projects/ML_based_MLSE/minimal_example_huawei/ml_mlse_pam.m
Normal file
@@ -0,0 +1,473 @@
|
|||||||
|
classdef ml_mlse_pam < handle
|
||||||
|
|
||||||
|
% ALGORITHM DESCRIBED IN:
|
||||||
|
% W. Lanneer and Y. Lefevre, “Machine Learning-Based Pre-Equalizers for
|
||||||
|
% Maximum Likelihood Sequence Estimation in High-Speed PONs,”
|
||||||
|
% in 2023 31st European Signal Processing Conference
|
||||||
|
|
||||||
|
% Further ML Refs:
|
||||||
|
% https://machinelearningmastery.com/cross-entropy-for-machine-learning/
|
||||||
|
% https://docs.pytorch.org/docs/stable/generated/torch.nn.CrossEntropyLoss.html
|
||||||
|
|
||||||
|
% The central idea is to overcome the (white-) noise assumption within the previously described
|
||||||
|
% Viterbi algorithm, more precisely a closed-loop optimization is proposed that finds a suitable
|
||||||
|
% filter-set to directly compute the branch metrics c_k (s,s^' ). These can directly be used to
|
||||||
|
% carry out the conventional Viterbi algorithm. The system consists of S^L S=F linear FIR filters,
|
||||||
|
% combined with one bias coefficient respectively. These filters take the received input samples to
|
||||||
|
% compute the branch metrics estimates (c_k ) ̂(s,s^' ) according toThe central idea is to overcome
|
||||||
|
% the (white-) noise assumption within the previously described Viterbi algorithm, more precisely
|
||||||
|
% a closed-loop optimization is proposed that finds a suitable filter-set to directly compute the
|
||||||
|
% branch metrics c_k (s,s^' ). These can directly be used to carry out the conventional Viterbi
|
||||||
|
% algorithm. The system consists of S^L S=F linear FIR filters, combined with one bias coefficient
|
||||||
|
% respectively. These filters take the received input samples to compute the branch metrics
|
||||||
|
% estimates. Finally, the usual Viterbi is carried out...
|
||||||
|
|
||||||
|
% Recommended Settings and some findings:
|
||||||
|
|
||||||
|
% Requires many training epochs. According to ML people, 100,200 or
|
||||||
|
% even up to 1000 epochs are normal for ML-convergence
|
||||||
|
|
||||||
|
% The mu parameter _can_ be adaptive - using the cross entropy and when
|
||||||
|
% analyzing the isolated training it looks very promisig. However, is
|
||||||
|
% later use I found this is not as stable as a fixed learning rate.
|
||||||
|
% mu = 0.1 worked good for me
|
||||||
|
|
||||||
|
% Longer orders/ filter length are not always better. For me order=11
|
||||||
|
% was good.
|
||||||
|
|
||||||
|
% Delay factor (delta) is good when the order is also increased. With
|
||||||
|
% order = 11, a delta of =4 shows good results
|
||||||
|
|
||||||
|
properties
|
||||||
|
sps % usually 2
|
||||||
|
order
|
||||||
|
e
|
||||||
|
e_tr
|
||||||
|
error
|
||||||
|
|
||||||
|
len_tr
|
||||||
|
mu_tr
|
||||||
|
epochs_tr
|
||||||
|
|
||||||
|
% dd_mode -> not implemented here!
|
||||||
|
mu_dd %weight update in dd mode
|
||||||
|
epochs_dd
|
||||||
|
|
||||||
|
adaptive_mu
|
||||||
|
|
||||||
|
constellation
|
||||||
|
|
||||||
|
L %viterbi memory length
|
||||||
|
|
||||||
|
alpha
|
||||||
|
DIR
|
||||||
|
DIR_flip
|
||||||
|
trellis_states
|
||||||
|
|
||||||
|
traceback_depth
|
||||||
|
|
||||||
|
S
|
||||||
|
Nf
|
||||||
|
delta
|
||||||
|
nStates
|
||||||
|
nFeasible
|
||||||
|
combs
|
||||||
|
first_sym
|
||||||
|
last_sym
|
||||||
|
valid
|
||||||
|
valid_to_idx
|
||||||
|
valid_from_idx
|
||||||
|
w
|
||||||
|
nbiasTerms
|
||||||
|
|
||||||
|
true_to_state_idx
|
||||||
|
state_dict % containers.Map: key(sequence)->state index
|
||||||
|
key_fmt = '%.8g_'; % key format for sequence strings
|
||||||
|
nSym % |constellation|
|
||||||
|
|
||||||
|
ber = []
|
||||||
|
ce = ones(1,1);
|
||||||
|
end
|
||||||
|
|
||||||
|
methods
|
||||||
|
function obj = ml_mlse_pam(options)
|
||||||
|
arguments(Input)
|
||||||
|
|
||||||
|
options.sps = 2;
|
||||||
|
options.order = 15;
|
||||||
|
|
||||||
|
options.len_tr = 4096;
|
||||||
|
options.mu_tr = 0;
|
||||||
|
options.epochs_tr = 5;
|
||||||
|
|
||||||
|
% options.dd_mode = 1;
|
||||||
|
options.mu_dd = 1e-5;
|
||||||
|
options.epochs_dd = 5;
|
||||||
|
|
||||||
|
options.adaptive_mu = 1;
|
||||||
|
|
||||||
|
options.delta = 0;
|
||||||
|
options.traceback_depth = 1024;
|
||||||
|
|
||||||
|
options.L = 1
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
fn = fieldnames(options);
|
||||||
|
for n = 1:numel(fn)
|
||||||
|
obj.(fn{n}) = options.(fn{n});
|
||||||
|
end
|
||||||
|
|
||||||
|
obj.e = zeros(obj.order,1);
|
||||||
|
obj.error = 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
function [x_viterbi,x_ref] = process(obj, X, D)
|
||||||
|
|
||||||
|
% actual processing of the signal (steps 1. - 3.)
|
||||||
|
% 1 normalize RMS
|
||||||
|
X = X./rms(X);
|
||||||
|
|
||||||
|
% Use sorted constellation for deterministic mapping
|
||||||
|
obj.constellation = sort(unique(D),'ascend');
|
||||||
|
obj.nSym = numel(obj.constellation);
|
||||||
|
|
||||||
|
if length(X)/length(D) ~= obj.sps
|
||||||
|
warning('Signal length does not fit to reference!');
|
||||||
|
end
|
||||||
|
|
||||||
|
% ==============================================================
|
||||||
|
% INITIALIZATION
|
||||||
|
% ==============================================================
|
||||||
|
|
||||||
|
% --- Parameters
|
||||||
|
obj.S = numel(obj.constellation); % Num of Symbols
|
||||||
|
obj.Nf = obj.order*obj.sps; % filter length (auto adapt for n-SPS...)
|
||||||
|
obj.nStates = obj.S^obj.L; % S^L states
|
||||||
|
obj.nFeasible = obj.nStates*obj.S; % S^(L+1) feasible states
|
||||||
|
|
||||||
|
% --- Trellis mapping
|
||||||
|
obj.trellis_states = reshape(obj.constellation,1,[]); % make row vector
|
||||||
|
pre_comb_mat = repmat(obj.trellis_states, obj.L, 1);
|
||||||
|
pre_comb_cell = mat2cell(pre_comb_mat, ones(1,obj.L), size(pre_comb_mat,2));
|
||||||
|
obj.combs = fliplr(combvec(pre_comb_cell{:}).'); % rows: states, columns: [x_k, x_{k-1}, ...]
|
||||||
|
obj.first_sym = obj.combs(:,1);
|
||||||
|
obj.last_sym = obj.combs(:,end);
|
||||||
|
obj.nStates = size(obj.combs,1);
|
||||||
|
|
||||||
|
% --- Valid transitions; adapted from the old Viterbi in
|
||||||
|
% Move-It where the "noise free received" states are calculated
|
||||||
|
% using the same loop and clause
|
||||||
|
obj.valid = false(obj.nStates);
|
||||||
|
for from = 1:obj.nStates
|
||||||
|
for to = 1:obj.nStates
|
||||||
|
if all(obj.combs(to,2:end) == obj.combs(from,1:end-1))
|
||||||
|
obj.valid(to,from) = true;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
[obj.valid_to_idx, obj.valid_from_idx] = find(obj.valid);
|
||||||
|
|
||||||
|
% Allocate vectors and weights
|
||||||
|
% !! IF SHAPE FIT, then we already have smth there an we want
|
||||||
|
% to start with the existing filter-set (saves comp. time/ or to test fixed filter on new data)
|
||||||
|
obj.nbiasTerms = 1;
|
||||||
|
if isempty(obj.w) || any(size(obj.w) ~= [obj.Nf+obj.nbiasTerms,obj.nFeasible])
|
||||||
|
obj.w = zeros(obj.Nf+obj.nbiasTerms,obj.nFeasible); % filter weights per transition + bias tap
|
||||||
|
% obj.w = randn(obj.Nf+obj.nbiasTerms,obj.nFeasible);
|
||||||
|
end
|
||||||
|
|
||||||
|
% This is a weird workaround - but it works and is much faster
|
||||||
|
% than findig the state indices every time:
|
||||||
|
% Precompute dictionary for fast state lookup (sequence -> state)
|
||||||
|
keys = cell(obj.nStates,1);
|
||||||
|
for i = 1:obj.nStates
|
||||||
|
keys{i} = obj.seq_key(obj.combs(i,:)); % combs row is already [x_k, x_{k-1}, ...]
|
||||||
|
end
|
||||||
|
obj.state_dict = containers.Map(keys, 1:obj.nStates);
|
||||||
|
|
||||||
|
% ==============================================================
|
||||||
|
% TRAINING
|
||||||
|
% ==============================================================
|
||||||
|
|
||||||
|
n = obj.len_tr;
|
||||||
|
training = 1;
|
||||||
|
obj.equalize(X, D,obj.mu_tr,obj.epochs_tr,n,training);
|
||||||
|
obj.e_tr = obj.e;
|
||||||
|
|
||||||
|
% ==============================================================
|
||||||
|
% Testing; Fixed Mode
|
||||||
|
% ==============================================================
|
||||||
|
|
||||||
|
n = length(X);
|
||||||
|
training = 0;
|
||||||
|
obj.mu_dd = obj.mu_tr; %For now no DD mode is implemented...
|
||||||
|
[x_viterbi,x_ref]=obj.equalize(X, D,obj.mu_dd,obj.epochs_dd,n,training);
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function [y,y_ref] = equalize(obj,x,d,mu,epochs,N,training)
|
||||||
|
% ==============================================================
|
||||||
|
% ML-Based Branch Metric Estimation + Viterbi
|
||||||
|
% ==============================================================
|
||||||
|
debug = 1;
|
||||||
|
showPlots = 1;
|
||||||
|
|
||||||
|
nSymbols = ceil(N/obj.sps);
|
||||||
|
|
||||||
|
for epoch = 1:epochs
|
||||||
|
|
||||||
|
% state metrics (log-domain costs): keep as column [nStatesx1]
|
||||||
|
pm = zeros(obj.nStates,1);
|
||||||
|
v_tilde = zeros(1,obj.nFeasible);
|
||||||
|
pred = zeros(nSymbols, obj.nStates);
|
||||||
|
pm_sto = nan(obj.nStates, nSymbols);
|
||||||
|
CE_accum = 0;
|
||||||
|
|
||||||
|
% START IDX can be randomized during training, but this
|
||||||
|
% requires some testing - it is not better, maybe a
|
||||||
|
% solutiuon is to use the same window for 10-20 epochs
|
||||||
|
% and then switch to another window
|
||||||
|
% for now: simply use the first parts of the signal for
|
||||||
|
% training and also for testing... not "the
|
||||||
|
randomize_training_window = 0;
|
||||||
|
if randomize_training_window && training
|
||||||
|
max_start = length(x) - ( (ceil(N/obj.sps)-1)*obj.sps + 1 );
|
||||||
|
max_start = max(1, max_start); % safety
|
||||||
|
start_sample = randi([1, max_start], 1); %rnd training; not really good
|
||||||
|
else
|
||||||
|
start_sample = 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
end_sample = start_sample + (ceil(N/obj.sps)-1)*obj.sps;
|
||||||
|
start_symbol = 1 + floor((start_sample - 1)/obj.sps); % ABSOLUTE symbol index
|
||||||
|
|
||||||
|
symbol = 0;
|
||||||
|
for sample = start_sample:obj.sps:end_sample
|
||||||
|
symbol = symbol + 1;
|
||||||
|
k = symbol;
|
||||||
|
sym_idx = start_symbol + (symbol - 1);
|
||||||
|
|
||||||
|
% input signal window y_k; delayed by delta
|
||||||
|
i1 = sample - obj.Nf + 1 + obj.delta;
|
||||||
|
i2 = sample + obj.delta;
|
||||||
|
buf = x(max(1,i1):min(length(x),i2));
|
||||||
|
padL = max(0,1 - i1);
|
||||||
|
padR = max(0,i2 - length(x));
|
||||||
|
yk = [zeros(padL,1); buf(:); zeros(padR,1)]; % Nfx1
|
||||||
|
yk = [yk;ones( obj.nbiasTerms,1)];
|
||||||
|
|
||||||
|
% Apply Filter; Predict branch metrics for all feasible transitions: c_hat
|
||||||
|
% Formula (8)
|
||||||
|
c_hat = (yk.' * obj.w); % [1xnFeasible]
|
||||||
|
c_hat = c_hat.'; % [nFeasiblex1]
|
||||||
|
|
||||||
|
% Extended path metrics: v_tilde = pm(from) + c_hat
|
||||||
|
v_tilde = pm(obj.valid_from_idx) + c_hat; % [nFeasiblex1]
|
||||||
|
|
||||||
|
% ===== Cross Entropy Loss Update =====
|
||||||
|
|
||||||
|
if 1 %training
|
||||||
|
% --- allocate storage once
|
||||||
|
if epoch == 1 && symbol == 1
|
||||||
|
obj.true_to_state_idx = ones(ceil(N/obj.sps),1,'uint32');
|
||||||
|
end
|
||||||
|
|
||||||
|
% --- previous "to" becomes current "from"
|
||||||
|
if symbol > 1
|
||||||
|
true_from_state_idx = obj.true_to_state_idx(symbol-1);
|
||||||
|
else
|
||||||
|
true_from_state_idx = 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
% --- compute or reuse "to" state
|
||||||
|
if epoch == 1
|
||||||
|
% only compute in first epoch
|
||||||
|
if sym_idx >= obj.L
|
||||||
|
key_to = obj.seq_key(flip(d(sym_idx-obj.L+1 : sym_idx)));
|
||||||
|
if isKey(obj.state_dict, key_to)
|
||||||
|
obj.true_to_state_idx(symbol) = obj.state_dict(key_to);
|
||||||
|
else
|
||||||
|
obj.true_to_state_idx(symbol) = true_from_state_idx;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
obj.true_to_state_idx(symbol) = true_from_state_idx;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
% --- ensure valid (from,to)
|
||||||
|
dirac = zeros(obj.nFeasible,1);
|
||||||
|
mask = obj.valid_from_idx==true_from_state_idx & ...
|
||||||
|
obj.valid_to_idx == obj.true_to_state_idx(symbol);
|
||||||
|
if any(mask)
|
||||||
|
dirac(mask) = 1;
|
||||||
|
else
|
||||||
|
idx = find(obj.valid_from_idx==true_from_state_idx,1,'first');
|
||||||
|
dirac(idx) = 1;
|
||||||
|
obj.true_to_state_idx(symbol) = obj.valid_to_idx(idx);
|
||||||
|
end
|
||||||
|
|
||||||
|
% softmax over -v_tilde (numerically safe shift)
|
||||||
|
v_shift = -(v_tilde - min(v_tilde)); % shift to small positive numbers
|
||||||
|
v_shift = min(v_shift, 100); % clamp exponent argument to avoid extreme numbers/ overflow (exp(50)=5e21)
|
||||||
|
expv = exp(v_shift);
|
||||||
|
p = expv ./ (sum(expv) + eps);
|
||||||
|
|
||||||
|
% Cross entropy
|
||||||
|
CE_symbol(symbol) = -log(p(dirac==1) + eps);
|
||||||
|
|
||||||
|
if sym_idx > obj.L
|
||||||
|
CE_smooth(symbol) = 0.01*CE_symbol(symbol) + 0.99*CE_smooth(symbol-1);
|
||||||
|
else
|
||||||
|
if epoch > 1
|
||||||
|
CE_smooth(symbol) = obj.ce(end); %stitch together ce from last epoch? or =1 for very first round?!
|
||||||
|
else
|
||||||
|
CE_smooth(symbol) = CE_symbol(symbol);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
CE_accum = CE_symbol(symbol) + CE_accum;
|
||||||
|
|
||||||
|
% Formula (10)
|
||||||
|
% gradient term (t - p)
|
||||||
|
dmp = (dirac - p)'; % 1xnFeasible
|
||||||
|
|
||||||
|
% Formula (10)
|
||||||
|
dL_Dw = (yk) .* dmp;
|
||||||
|
|
||||||
|
% Start updates only when the symbol index has ≥ L history
|
||||||
|
if sym_idx >= obj.L
|
||||||
|
if obj.adaptive_mu
|
||||||
|
mu_eff = CE_smooth(sym_idx);
|
||||||
|
mu_eff = max(min(mu_eff, 0.2), 1e-4);
|
||||||
|
else
|
||||||
|
mu_eff = mu;
|
||||||
|
end
|
||||||
|
|
||||||
|
% see Algorithm 1 in paper
|
||||||
|
obj.w = obj.w - mu_eff .* dL_Dw; % (Nf+1)xnFeasible
|
||||||
|
end
|
||||||
|
|
||||||
|
% if debug && epoch > 2
|
||||||
|
% figure(100);
|
||||||
|
% subplot(4,1,1);
|
||||||
|
% heatmap(p');
|
||||||
|
% title('Probs')
|
||||||
|
% subplot(4,1,2);
|
||||||
|
% heatmap(dmp);
|
||||||
|
% title('Update')
|
||||||
|
% subplot(4,1,3);
|
||||||
|
% heatmap(dL_Dw);
|
||||||
|
% title('Update')
|
||||||
|
% subplot(4,1,4);
|
||||||
|
% heatmap(bj.w);
|
||||||
|
% title('Update')
|
||||||
|
%
|
||||||
|
% end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
% Compare-Select
|
||||||
|
v_tilde_mat = inf(obj.nStates, obj.nStates);
|
||||||
|
v_tilde_mat(obj.valid) = v_tilde; %reshapes to usual (from x to) matrix
|
||||||
|
[pm_next, pred(k,:)] = min(v_tilde_mat, [], 2); %here, calc min for each column
|
||||||
|
|
||||||
|
% re-center, otherwise it will overflow
|
||||||
|
pm_next = pm_next - min(pm_next);
|
||||||
|
|
||||||
|
pm = pm_next;
|
||||||
|
pm_sto(:,symbol) = pm;
|
||||||
|
end
|
||||||
|
|
||||||
|
% Traceback
|
||||||
|
[~, s_end] = min(pm);
|
||||||
|
viterbi_path = zeros(symbol,1);
|
||||||
|
viterbi_path(symbol) = s_end;
|
||||||
|
for n = symbol:-1:2
|
||||||
|
viterbi_path(n-1) = pred(n, viterbi_path(n));
|
||||||
|
end
|
||||||
|
|
||||||
|
% cut here to have the same indices when shuffling/
|
||||||
|
% starting the start_symbol indx != 1
|
||||||
|
y_ref = d(start_symbol:end);
|
||||||
|
y = obj.first_sym(viterbi_path);
|
||||||
|
|
||||||
|
% Debug and Plots
|
||||||
|
if debug && training
|
||||||
|
sym_start = start_symbol;
|
||||||
|
sym_end = start_symbol + symbol - 1;
|
||||||
|
ref_slice = d(sym_start : sym_end);
|
||||||
|
err = sum(y ~= ref_slice(1:numel(y)));
|
||||||
|
|
||||||
|
try %works with demapper, not provided in Deliverable
|
||||||
|
ref_bits = PAMmapper(obj.S,0).demap(ref_slice);
|
||||||
|
eq_bits = PAMmapper(obj.S,0).demap(y);
|
||||||
|
[~, ~, ber, ~] = calc_ber(ref_bits, eq_bits, "skip_front", 10, "skip_end", 10, "returnErrorLocation", 1);
|
||||||
|
fprintf('Epoch: %d - BER: %.1e \n',epoch, ber);
|
||||||
|
obj.ber(epoch) = ber;
|
||||||
|
berlabel = 'BER';
|
||||||
|
catch %fallback ser
|
||||||
|
ser = err./length(y);
|
||||||
|
fprintf('Epoch: %d - SER: %.1e \n',epoch, ser);
|
||||||
|
obj.ber(epoch) = ser;
|
||||||
|
berlabel = 'BER';
|
||||||
|
end
|
||||||
|
|
||||||
|
obj.ce(epoch) = CE_accum./symbol;
|
||||||
|
|
||||||
|
if showPlots
|
||||||
|
figure(10);clf
|
||||||
|
subplot(3,2,1:2);
|
||||||
|
heatmap(obj.w);
|
||||||
|
title('Filter')
|
||||||
|
|
||||||
|
subplot(3,2,3);
|
||||||
|
v_tildemat = NaN(obj.nStates, obj.nStates);
|
||||||
|
v_tildemat(obj.valid) = v_tilde; % log-domain scores
|
||||||
|
heatmap(v_tildemat);
|
||||||
|
title('Extended Path Metrics v-tilde')
|
||||||
|
|
||||||
|
subplot(3,2,4);
|
||||||
|
scatter(1:symbol,pm_sto,1,'.')
|
||||||
|
title('Path Metric Winners v')
|
||||||
|
|
||||||
|
subplot(3,2,5);hold on
|
||||||
|
scatter(1:symbol,CE_symbol,1,'.');
|
||||||
|
scatter(1:symbol,CE_smooth,1,'.')
|
||||||
|
title('Cross Entropy')
|
||||||
|
ylabel('Cross Entropy')
|
||||||
|
xlabel('Symbols')
|
||||||
|
|
||||||
|
subplot(3,2,6); hold on
|
||||||
|
% Left y-axis: Cross Entropy
|
||||||
|
yyaxis left
|
||||||
|
scatter(1:length(obj.ce), obj.ce, 10, 's', 'filled')
|
||||||
|
ylabel('Cross Entropy')
|
||||||
|
|
||||||
|
% Right y-axis: BER
|
||||||
|
yyaxis right
|
||||||
|
scatter(1:length(obj.ber), obj.ber, 10, 'd', 'filled')
|
||||||
|
set(gca, 'YScale', 'log')
|
||||||
|
ylabel(berlabel)
|
||||||
|
|
||||||
|
xlim([1, epochs])
|
||||||
|
xlabel('Epoch')
|
||||||
|
title('Cross Entropy // BER')
|
||||||
|
grid on
|
||||||
|
|
||||||
|
drawnow
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
methods (Access=private)
|
||||||
|
function k = seq_key(obj, seq)
|
||||||
|
% Build a stable key string for a sequence row vector in the *same order as combs rows* ([x_k, x_{k-1}, ...])
|
||||||
|
% Use rounding via sprintf to avoid floating-point issues.
|
||||||
|
% seq must be a row vector.
|
||||||
|
k = sprintf(obj.key_fmt, seq);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -5,14 +5,14 @@ ber_dbtgt = [];
|
|||||||
ber_ml = [];
|
ber_ml = [];
|
||||||
|
|
||||||
mlse = 1;
|
mlse = 1;
|
||||||
dbtgt = 1;
|
dbtgt = 0;
|
||||||
|
duob_mode = db_mode.no_db;
|
||||||
baudrates = [136:8:224].*1e9;
|
baudrates = [136:8:224].*1e9;
|
||||||
parfor i = 1:length(baudrates)
|
for i = 1:length(baudrates)
|
||||||
|
|
||||||
rop = -8;
|
rop = -8;
|
||||||
M = 4;
|
M = 4;
|
||||||
[Rx_sig_2sps_v1, Symbols_v1, Tx_bits_v1] = standard_link_model("M",M,"fsym",baudrates(i),"rop",rop,"laser_linewidth",1300,"link_length_m",0,"random_key",1,"apply_pulsef",0);
|
[Rx_sig_2sps_v1, Symbols_v1, Tx_bits_v1] = standard_link_model("M",M,"fsym",baudrates(i),"rop",rop,"laser_linewidth",1310,"link_length_m",0,"random_key",1,"apply_pulsef",1);
|
||||||
% [Rx_sig_2sps_v2, Symbols_v2, Tx_bits_v2] = standard_link_model("M",M,"fsym",200e9,"rop",rop,"laser_linewidth",1300,"link_length_m",0,"random_key",2);
|
% [Rx_sig_2sps_v2, Symbols_v2, Tx_bits_v2] = standard_link_model("M",M,"fsym",200e9,"rop",rop,"laser_linewidth",1300,"link_length_m",0,"random_key",2);
|
||||||
% [Rx_sig_2sps_v3, Symbols_v3, Tx_bits_v3] = standard_link_model("M",M,"fsym",200e9,"rop",rop,"laser_linewidth",1300,"link_length_m",0,"random_key",3);
|
% [Rx_sig_2sps_v3, Symbols_v3, Tx_bits_v3] = standard_link_model("M",M,"fsym",200e9,"rop",rop,"laser_linewidth",1300,"link_length_m",0,"random_key",3);
|
||||||
|
|
||||||
@@ -25,6 +25,7 @@ parfor i = 1:length(baudrates)
|
|||||||
eq_ = EQ("Ne",ffe_order,"Nb",[0,0,0],"training_length",2^13,"training_loops",5,"dd_loops",5,"K",2,"DCmu",0.005,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",1);
|
eq_ = EQ("Ne",ffe_order,"Nb",[0,0,0],"training_length",2^13,"training_loops",5,"dd_loops",5,"K",2,"DCmu",0.005,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",1);
|
||||||
pf_ = Postfilter("ncoeff",pf_ncoeffs,"useBurg",1);
|
pf_ = Postfilter("ncoeff",pf_ncoeffs,"useBurg",1);
|
||||||
mlse_ = MLSE("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels,'scale_mode',2,'trellis_exclusion',0,'trellis_state_mode',2,'debug',0,'DIR',pf_.coefficients);
|
mlse_ = MLSE("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels,'scale_mode',2,'trellis_exclusion',0,'trellis_state_mode',2,'debug',0,'DIR',pf_.coefficients);
|
||||||
|
|
||||||
[ffe_results, mlse_results] = vnle_postfilter_mlse(eq_, pf_, mlse_, M, Rx_sig_2sps_v1, Symbols_v1, Tx_bits_v1, ...
|
[ffe_results, mlse_results] = vnle_postfilter_mlse(eq_, pf_, mlse_, M, Rx_sig_2sps_v1, Symbols_v1, Tx_bits_v1, ...
|
||||||
"precode_mode", duob_mode,...
|
"precode_mode", duob_mode,...
|
||||||
'showAnalysis', 0, ...
|
'showAnalysis', 0, ...
|
||||||
@@ -33,6 +34,9 @@ parfor i = 1:length(baudrates)
|
|||||||
|
|
||||||
ber_ffe(i) = ffe_results.metrics.BER;
|
ber_ffe(i) = ffe_results.metrics.BER;
|
||||||
ber_mlse(i) = mlse_results.metrics.BER;
|
ber_mlse(i) = mlse_results.metrics.BER;
|
||||||
|
|
||||||
|
fprintf('BER FFE: %.2e \n',ber_ffe(i));
|
||||||
|
fprintf('BER MLSE: %.2e \n',ber_mlse(i));
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -69,11 +73,14 @@ parfor i = 1:length(baudrates)
|
|||||||
%% RUN ML-Based MLSE
|
%% RUN ML-Based MLSE
|
||||||
|
|
||||||
mu_lms = 0.15;
|
mu_lms = 0.15;
|
||||||
ml_mlse_equalizer = ML_MLSE("epochs_tr",30,"epochs_dd",1,"len_tr",2^15,...
|
ml_mlse_equalizer = ML_MLSE("epochs_tr",50,"epochs_dd",1,"len_tr",2^16,...
|
||||||
"mu_dd",mu_lms,"mu_tr",mu_lms,"order",5,"sps",1,...
|
"mu_dd",mu_lms,"mu_tr",mu_lms,"order",4,"sps",2,...
|
||||||
"traceback_depth",128,"L",3,"delta",0);
|
"traceback_depth",128,"L",2,"delta",0);
|
||||||
|
|
||||||
[y_ml_mlse,~] = ml_mlse_equalizer.process(y_white,Symbols_v1);
|
ml_mlse_equalizer.mu_tr = 0.005;
|
||||||
|
ml_mlse_equalizer.epochs_tr = 2;
|
||||||
|
ml_mlse_equalizer.epochs_dd = 1;
|
||||||
|
[y_ml_mlse,~] = ml_mlse_equalizer.process(Rx_sig_2sps_v1,Symbols_v1);
|
||||||
ml_mlse_bits = PAMmapper(M, 0, "eth_style", 0).demap(y_ml_mlse);
|
ml_mlse_bits = PAMmapper(M, 0, "eth_style", 0).demap(y_ml_mlse);
|
||||||
[~, errors, ber_ml(i), errpos] = calc_ber(ml_mlse_bits.signal, Tx_bits_v1.signal, "skip_front", 10, "skip_end", 10, "returnErrorLocation", 1);
|
[~, errors, ber_ml(i), errpos] = calc_ber(ml_mlse_bits.signal, Tx_bits_v1.signal, "skip_front", 10, "skip_end", 10, "returnErrorLocation", 1);
|
||||||
fprintf('ML MLSE BER: %.2e \n',ber_ml(i));
|
fprintf('ML MLSE BER: %.2e \n',ber_ml(i));
|
||||||
|
|||||||
30
projects/ML_based_MLSE/read_csv.m
Normal file
30
projects/ML_based_MLSE/read_csv.m
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
%% read_wpd_csv.m
|
||||||
|
% Minimal importer for WebPlotDigitizer multi-curve CSV
|
||||||
|
|
||||||
|
filename = 'wpd_datasets.csv'; % <-- set your file path here
|
||||||
|
T = readtable(filename);
|
||||||
|
|
||||||
|
% Read header row manually
|
||||||
|
fid = fopen(filename);
|
||||||
|
hdr1 = strsplit(strrep(fgetl(fid), '"', ''), ','); % curve names
|
||||||
|
hdr2 = strsplit(strrep(fgetl(fid), '"', ''), ','); % X/Y header row
|
||||||
|
fclose(fid);
|
||||||
|
|
||||||
|
% Extract unique curve names
|
||||||
|
names = hdr1(~cellfun('isempty',hdr1));
|
||||||
|
|
||||||
|
% Create struct for each curve
|
||||||
|
mii = struct();
|
||||||
|
for i = 1:numel(names)
|
||||||
|
base = matlab.lang.makeValidName(strrep(names{i},' ','_'));
|
||||||
|
xi = 2*(i-1)+1; % X column
|
||||||
|
yi = xi+1; % Y column
|
||||||
|
mii.(base).X = T{:,xi};
|
||||||
|
mii.(base).Y = T{:,yi};
|
||||||
|
|
||||||
|
% also create workspace variable "name_wpd"
|
||||||
|
assignin('base',[base '_wpd'], mii.(base));
|
||||||
|
end
|
||||||
|
|
||||||
|
disp('Imported datasets:');
|
||||||
|
disp(fieldnames(mii));
|
||||||
@@ -1,95 +1,139 @@
|
|||||||
|
clear; clc;
|
||||||
|
|
||||||
ber_ffe = [];
|
M = 4;
|
||||||
ber_mlse = [];
|
randkey = 1;
|
||||||
ber_dbtgt = [];
|
duob_mode = db_mode.no_db;
|
||||||
ber_ml = [];
|
|
||||||
|
|
||||||
mlse = 1;
|
mlse = 1;
|
||||||
dbtgt = 1;
|
dbtgt = 1;
|
||||||
|
|
||||||
rops = linspace(-15,-5,12);
|
baudrates = 180e9:2e9:220e9; % outer loop
|
||||||
parfor i = 1:length(rops)
|
rops = linspace(-10,0,12); % inner sweep
|
||||||
|
FEC_thr = 3.8e-3; % BER target
|
||||||
rop = rops(i);
|
|
||||||
M = 4;
|
% --- allocate results
|
||||||
[Rx_sig_2sps_v1, Symbols_v1, Tx_bits_v1] = standard_link_model("M",M,"fsym",224e9,"rop",rop,"laser_linewidth",1300,"link_length_m",0,"random_key",1);
|
reqROP_FFE = nan(size(baudrates));
|
||||||
% [Rx_sig_2sps_v2, Symbols_v2, Tx_bits_v2] = standard_link_model("M",M,"fsym",200e9,"rop",rop,"laser_linewidth",1300,"link_length_m",0,"random_key",2);
|
reqROP_MLSE = nan(size(baudrates));
|
||||||
% [Rx_sig_2sps_v3, Symbols_v3, Tx_bits_v3] = standard_link_model("M",M,"fsym",200e9,"rop",rop,"laser_linewidth",1300,"link_length_m",0,"random_key",3);
|
reqROP_DBTGT = nan(size(baudrates));
|
||||||
|
reqROP_ML_MLSE2 = nan(size(baudrates));
|
||||||
%% FFE + MLSE
|
reqROP_ML_MLSE3 = nan(size(baudrates));
|
||||||
if mlse
|
|
||||||
pf_ncoeffs = 1;
|
%% ====================== OUTER LOOP ======================
|
||||||
ffe_order = [50, 0, 0];
|
for b = 1:numel(baudrates)
|
||||||
mu_ffe = [0.0001, 0.0008, 0.001];
|
baudrate = baudrates(b);
|
||||||
mu_dfe = 0.0004;
|
fprintf('\n=== %.0f GBd ===\n', baudrate/1e9);
|
||||||
eq_ = EQ("Ne",ffe_order,"Nb",[0,0,0],"training_length",2^13,"training_loops",5,"dd_loops",5,"K",2,"DCmu",0.005,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",1);
|
|
||||||
pf_ = Postfilter("ncoeff",pf_ncoeffs,"useBurg",1);
|
ber_ffe = nan(size(rops));
|
||||||
mlse_ = MLSE("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels,'scale_mode',2,'trellis_exclusion',0,'trellis_state_mode',2,'debug',0,'DIR',pf_.coefficients);
|
ber_mlse = nan(size(rops));
|
||||||
[ffe_results, mlse_results] = vnle_postfilter_mlse(eq_, pf_, mlse_, M, Rx_sig_2sps_v1, Symbols_v1, Tx_bits_v1, ...
|
ber_dbtgt = nan(size(rops));
|
||||||
"precode_mode", duob_mode,...
|
ber_ml2 = nan(size(rops));
|
||||||
'showAnalysis', 0, ...
|
ber_ml3 = nan(size(rops));
|
||||||
"postFFE", [],...
|
|
||||||
"eth_style_symbol_mapping", 0);
|
%% -------- inner ROP loop --------
|
||||||
|
for i = 1:length(rops)
|
||||||
ber_ffe(i) = ffe_results.metrics.BER;
|
rop = rops(i);
|
||||||
ber_mlse(i) = mlse_results.metrics.BER;
|
|
||||||
end
|
[Rx_sig_2sps_v1, Symbols_v1, Tx_bits_v1] = standard_link_model( ...
|
||||||
|
"M",M,"fsym",baudrate,"rop",rop,"laser_linewidth",1310, ...
|
||||||
|
"link_length_m",0,"random_key",1);
|
||||||
|
|
||||||
|
|
||||||
%% FFE DB tgt. + MLSE
|
|
||||||
if dbtgt
|
|
||||||
mlse_db_ = MLSE("DIR",[1,1],"duobinary_output",0,"M",M,"trellis_states",PAMmapper(M,0).levels,'scale_mode',2,'trellis_exclusion',0,'trellis_state_mode',3);
|
|
||||||
ffe_order = [50, 0, 0];
|
|
||||||
mu_ffe = [0.0001, 0.0008, 0.001];
|
|
||||||
mu_dfe = 0.0004;
|
|
||||||
eq_ = EQ("Ne",ffe_order,"Nb",[0,0,0],"training_length",2^13,"training_loops",5,"dd_loops",5,"K",2,"DCmu",0.005,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",1);
|
|
||||||
|
|
||||||
dbt_results = duobinary_target(eq_, mlse_db_, M, Rx_sig_2sps_v1, Symbols_v1, Tx_bits_v1, ...
|
|
||||||
"precode_mode", duob_mode, ...
|
|
||||||
'showAnalysis', 0,...
|
|
||||||
"postFFE", []);
|
|
||||||
|
|
||||||
ber_dbtgt(i) = dbt_results.metrics.BER;
|
|
||||||
end
|
|
||||||
|
|
||||||
%% RUN ML-Based MLSE
|
|
||||||
|
|
||||||
mu_lms = 0.15;
|
|
||||||
ml_mlse_equalizer = ML_MLSE("epochs_tr",30,"epochs_dd",1,"len_tr",2^14,...
|
|
||||||
"mu_dd",mu_lms,"mu_tr",mu_lms,"order",4,"sps",2,...
|
|
||||||
"traceback_depth",128,"L",2,"delta",0);
|
|
||||||
|
|
||||||
[y_ml_mlse,~] = ml_mlse_equalizer.process(Rx_sig_2sps_v1,Symbols_v1);
|
%% FFE + MLSE
|
||||||
ml_mlse_bits = PAMmapper(M, 0, "eth_style", 0).demap(y_ml_mlse);
|
if mlse
|
||||||
[~, errors, ber_ml(i), errpos] = calc_ber(ml_mlse_bits.signal, Tx_bits_v1.signal, "skip_front", 10, "skip_end", 10, "returnErrorLocation", 1);
|
pf_ncoeffs = 1;
|
||||||
fprintf('ML MLSE BER: %.2e \n',ber_ml(i));
|
ffe_order = [50, 0, 0];
|
||||||
|
mu_ffe = [0.0001, 0.0008, 0.001];
|
||||||
% figure(11);hold on
|
mu_dfe = 0.0004;
|
||||||
% plot(1:numel(ml_mlse_equalizer.ber),ml_mlse_equalizer.ber);
|
eq_ = EQ("Ne",ffe_order,"Nb",[0,0,0],"training_length",2^13, ...
|
||||||
% beautifyBERplot;
|
"training_loops",5,"dd_loops",5,"K",2,"DCmu",0.005, ...
|
||||||
% xlim([1,numel(ml_mlse_equalizer.ber)])
|
"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0, ...
|
||||||
|
"plotfinal",0,"ideal_dfe",1);
|
||||||
|
pf_ = Postfilter("ncoeff",pf_ncoeffs,"useBurg",1);
|
||||||
|
mlse_ = MLSE("duobinary_output",0,'M',M, ...
|
||||||
|
'trellis_states',PAMmapper(M,0).levels,'scale_mode',2, ...
|
||||||
|
'trellis_exclusion',0,'trellis_state_mode',2,'debug',0, ...
|
||||||
|
'DIR',pf_.coefficients);
|
||||||
|
|
||||||
|
[ffe_results, mlse_results] = vnle_postfilter_mlse(eq_, pf_, mlse_, M, ...
|
||||||
|
Rx_sig_2sps_v1, Symbols_v1, Tx_bits_v1, ...
|
||||||
|
"precode_mode", duob_mode,'showAnalysis', 0, "postFFE", [], ...
|
||||||
|
"eth_style_symbol_mapping", 0);
|
||||||
|
|
||||||
|
ber_ffe(i) = ffe_results.metrics.BER;
|
||||||
|
ber_mlse(i) = mlse_results.metrics.BER;
|
||||||
|
end
|
||||||
|
|
||||||
|
%% FFE + duobinary target MLSE
|
||||||
|
if dbtgt
|
||||||
|
mlse_db_ = MLSE("DIR",[1,1],"duobinary_output",0,"M",M, ...
|
||||||
|
"trellis_states",PAMmapper(M,0).levels,'scale_mode',2, ...
|
||||||
|
'trellis_exclusion',0,'trellis_state_mode',3);
|
||||||
|
ffe_order = [50, 0, 0];
|
||||||
|
mu_ffe = [0.0001, 0.0008, 0.001];
|
||||||
|
mu_dfe = 0.0004;
|
||||||
|
eq_ = EQ("Ne",ffe_order,"Nb",[0,0,0],"training_length",2^13, ...
|
||||||
|
"training_loops",5,"dd_loops",5,"K",2,"DCmu",0.005, ...
|
||||||
|
"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0, ...
|
||||||
|
"plotfinal",0,"ideal_dfe",1);
|
||||||
|
|
||||||
|
dbt_results = duobinary_target(eq_, mlse_db_, M, Rx_sig_2sps_v1, ...
|
||||||
|
Symbols_v1, Tx_bits_v1, "precode_mode", duob_mode, ...
|
||||||
|
'showAnalysis', 0, "postFFE", []);
|
||||||
|
ber_dbtgt(i) = dbt_results.metrics.BER;
|
||||||
|
end
|
||||||
|
|
||||||
|
%% ML-based MLSE (L=2)
|
||||||
|
mu_ml = 0.1; training_epochs = 100;
|
||||||
|
ml_mlse_equalizer = ML_MLSE("epochs_tr",training_epochs,"epochs_dd",1, ...
|
||||||
|
"len_tr",2^16,"mu_dd",mu_ml,"mu_tr",mu_ml,"order",11,"sps",2, ...
|
||||||
|
"traceback_depth",128,"L",2,"delta",4,"adaptive_mu",0);
|
||||||
|
[y_ml_mlse,y_ref] = ml_mlse_equalizer.process(Rx_sig_2sps_v1,Symbols_v1);
|
||||||
|
ref_bits = PAMmapper(M,0).demap(y_ref);
|
||||||
|
ml_bits = PAMmapper(M,0).demap(y_ml_mlse);
|
||||||
|
[~,~,ber_ml2(i)] = calc_ber(ml_bits.signal, ref_bits.signal, ...
|
||||||
|
"skip_front",10,"skip_end",10);
|
||||||
|
|
||||||
|
%% ML-based MLSE (L=3)
|
||||||
|
ml_mlse_equalizer = ML_MLSE("epochs_tr",training_epochs,"epochs_dd",1, ...
|
||||||
|
"len_tr",2^16,"mu_dd",mu_ml,"mu_tr",mu_ml,"order",11,"sps",2, ...
|
||||||
|
"traceback_depth",128,"L",3,"delta",4,"adaptive_mu",0);
|
||||||
|
[y_ml_mlse,y_ref] = ml_mlse_equalizer.process(Rx_sig_2sps_v1,Symbols_v1);
|
||||||
|
ref_bits = PAMmapper(M,0).demap(y_ref);
|
||||||
|
ml_bits = PAMmapper(M,0).demap(y_ml_mlse);
|
||||||
|
[~,~,ber_ml3(i)] = calc_ber(ml_bits.signal, ref_bits.signal, ...
|
||||||
|
"skip_front",10,"skip_end",10);
|
||||||
|
end % ROP loop
|
||||||
|
|
||||||
|
%% --- find required ROP (FEC crossing)
|
||||||
|
reqROP_FFE(b) = interp_fec_cross(rops, ber_ffe, FEC_thr);
|
||||||
|
reqROP_MLSE(b) = interp_fec_cross(rops, ber_mlse, FEC_thr);
|
||||||
|
reqROP_DBTGT(b) = interp_fec_cross(rops, ber_dbtgt, FEC_thr);
|
||||||
|
reqROP_ML_MLSE2(b) = interp_fec_cross(rops, ber_ml2, FEC_thr);
|
||||||
|
reqROP_ML_MLSE3(b) = interp_fec_cross(rops, ber_ml3, FEC_thr);
|
||||||
|
|
||||||
|
% --- diagnostic
|
||||||
|
fprintf('Baud %.0f GBd: FFE %.1f, MLSE %.1f, DB %.1f, ML2 %.1f, ML3 %.1f\n', ...
|
||||||
|
baudrate/1e9, reqROP_FFE(b), reqROP_MLSE(b), reqROP_DBTGT(b), ...
|
||||||
|
reqROP_ML_MLSE2(b), reqROP_ML_MLSE3(b));
|
||||||
end
|
end
|
||||||
|
|
||||||
%%
|
%% ====================== PLOT REQUIRED ROP ======================
|
||||||
|
cols = cbrewer2('Set1',8);
|
||||||
figure(3); hold on;
|
colFFE = cols(1,:);
|
||||||
if mlse
|
colMLSE = cols(2,:);
|
||||||
plot(rops,ber_ffe,'DisplayName','FFE');
|
colDBTGT = cols(4,:);
|
||||||
plot(rops,ber_mlse,'DisplayName','MLSE');
|
colML_MLSE = cols(3,:);
|
||||||
end
|
|
||||||
if dbtgt
|
|
||||||
plot(rops,ber_dbtgt,'DisplayName','DB tgt');
|
|
||||||
end
|
|
||||||
plot(rops,ber_ml,'DisplayName','ML-MLSE');
|
|
||||||
beautifyBERplot;
|
|
||||||
legend
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
figure(); hold on
|
||||||
|
plot(baudrates/1e9, reqROP_FFE, '-o','Color',colFFE, 'DisplayName','FFE');
|
||||||
|
plot(baudrates/1e9, reqROP_MLSE, '-s','Color',colMLSE, 'DisplayName','FFE+PF+MLSE');
|
||||||
|
plot(baudrates/1e9, reqROP_DBTGT, '--^','Color',colDBTGT, 'DisplayName','DB tgt. MLSE');
|
||||||
|
plot(baudrates/1e9, reqROP_ML_MLSE2, '-v','Color',colML_MLSE, 'DisplayName','ML-based MLSE (L=2)');
|
||||||
|
plot(baudrates/1e9, reqROP_ML_MLSE3, '-d','Color',colML_MLSE*0.8,'DisplayName','ML-based MLSE (L=3)');
|
||||||
|
|
||||||
|
xlabel('Baud rate [GBd]');
|
||||||
|
ylabel('Required ROP [dBm]');
|
||||||
|
title('ROP required for FEC threshold');
|
||||||
|
grid on; legend('Location','northwest');
|
||||||
|
beautifyBERplot("logscale",0,"polyfit",1,"polyorder",4,"fitmethod",'polyfit');
|
||||||
|
|||||||
140
projects/ML_based_MLSE/rrop_vs_length_evaluation.m
Normal file
140
projects/ML_based_MLSE/rrop_vs_length_evaluation.m
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
clear; clc;
|
||||||
|
|
||||||
|
M = 4;
|
||||||
|
randkey = 1;
|
||||||
|
duob_mode = db_mode.no_db;
|
||||||
|
|
||||||
|
mlse = 1;
|
||||||
|
dbtgt = 1;
|
||||||
|
|
||||||
|
link_lengths = 0:1:8; % [m] --- outer loop
|
||||||
|
rops = linspace(-10, 0, 12); % [dBm] --- inner sweep
|
||||||
|
FEC_thr = 3.8e-3; % BER target
|
||||||
|
baudrate = 200e9;
|
||||||
|
|
||||||
|
% --- allocate results
|
||||||
|
reqROP_FFE = nan(size(link_lengths));
|
||||||
|
reqROP_MLSE = nan(size(link_lengths));
|
||||||
|
reqROP_DBTGT = nan(size(link_lengths));
|
||||||
|
reqROP_ML_MLSE2 = nan(size(link_lengths));
|
||||||
|
reqROP_ML_MLSE3 = nan(size(link_lengths));
|
||||||
|
|
||||||
|
%% ====================== OUTER LOOP ======================
|
||||||
|
for L = 1:numel(link_lengths)
|
||||||
|
link_length_m = link_lengths(L);
|
||||||
|
fprintf('\n=== %.0f m fiber length ===\n', link_length_m);
|
||||||
|
|
||||||
|
ber_ffe = nan(size(rops));
|
||||||
|
ber_mlse = nan(size(rops));
|
||||||
|
ber_dbtgt = nan(size(rops));
|
||||||
|
ber_ml2 = nan(size(rops));
|
||||||
|
ber_ml3 = nan(size(rops));
|
||||||
|
|
||||||
|
%% -------- inner ROP loop --------
|
||||||
|
parfor i = 1:length(rops)
|
||||||
|
rop = rops(i);
|
||||||
|
|
||||||
|
[Rx_sig_2sps_v1, Symbols_v1, Tx_bits_v1] = standard_link_model( ...
|
||||||
|
"M",M,"fsym",baudrate,"rop",rop,"laser_wavelength",1290, ...
|
||||||
|
"link_length_km",link_length_m,"random_key",1);
|
||||||
|
|
||||||
|
Rx_sig_2sps_v1.spectrum("displayname",'Rx Sig','normalizeTo0dB',1);
|
||||||
|
|
||||||
|
%% FFE + MLSE
|
||||||
|
if mlse
|
||||||
|
pf_ncoeffs = 1;
|
||||||
|
ffe_order = [50, 0, 0];
|
||||||
|
mu_ffe = [0.0001, 0.0008, 0.001];
|
||||||
|
mu_dfe = 0.0004;
|
||||||
|
eq_ = EQ("Ne",ffe_order,"Nb",[0,0,0],"training_length",2^13, ...
|
||||||
|
"training_loops",5,"dd_loops",5,"K",2,"DCmu",0.005, ...
|
||||||
|
"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0, ...
|
||||||
|
"plotfinal",0,"ideal_dfe",1);
|
||||||
|
pf_ = Postfilter("ncoeff",pf_ncoeffs,"useBurg",1);
|
||||||
|
mlse_ = MLSE("duobinary_output",0,'M',M, ...
|
||||||
|
'trellis_states',PAMmapper(M,0).levels,'scale_mode',2, ...
|
||||||
|
'trellis_exclusion',0,'trellis_state_mode',2,'debug',0, ...
|
||||||
|
'DIR',pf_.coefficients);
|
||||||
|
|
||||||
|
[ffe_results, mlse_results] = vnle_postfilter_mlse(eq_, pf_, mlse_, M, ...
|
||||||
|
Rx_sig_2sps_v1, Symbols_v1, Tx_bits_v1, ...
|
||||||
|
"precode_mode", duob_mode,'showAnalysis', 0, "postFFE", [], ...
|
||||||
|
"eth_style_symbol_mapping", 0);
|
||||||
|
|
||||||
|
ber_ffe(i) = ffe_results.metrics.BER;
|
||||||
|
ber_mlse(i) = mlse_results.metrics.BER;
|
||||||
|
end
|
||||||
|
|
||||||
|
%% FFE + duobinary target MLSE
|
||||||
|
if dbtgt
|
||||||
|
mlse_db_ = MLSE("DIR",[1,1],"duobinary_output",0,"M",M, ...
|
||||||
|
"trellis_states",PAMmapper(M,0).levels,'scale_mode',2, ...
|
||||||
|
'trellis_exclusion',0,'trellis_state_mode',3);
|
||||||
|
ffe_order = [50, 0, 0];
|
||||||
|
mu_ffe = [0.0001, 0.0008, 0.001];
|
||||||
|
mu_dfe = 0.0004;
|
||||||
|
eq_ = EQ("Ne",ffe_order,"Nb",[0,0,0],"training_length",2^13, ...
|
||||||
|
"training_loops",5,"dd_loops",5,"K",2,"DCmu",0.005, ...
|
||||||
|
"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0, ...
|
||||||
|
"plotfinal",0,"ideal_dfe",1);
|
||||||
|
|
||||||
|
dbt_results = duobinary_target(eq_, mlse_db_, M, Rx_sig_2sps_v1, ...
|
||||||
|
Symbols_v1, Tx_bits_v1, "precode_mode", duob_mode, ...
|
||||||
|
'showAnalysis', 0, "postFFE", []);
|
||||||
|
ber_dbtgt(i) = dbt_results.metrics.BER;
|
||||||
|
end
|
||||||
|
|
||||||
|
%% ML-based MLSE (L=2)
|
||||||
|
mu_ml = 0.1; training_epochs = 100;
|
||||||
|
ml_mlse_equalizer = ML_MLSE("epochs_tr",training_epochs,"epochs_dd",1, ...
|
||||||
|
"len_tr",2^16,"mu_dd",mu_ml,"mu_tr",mu_ml,"order",11,"sps",2, ...
|
||||||
|
"traceback_depth",128,"L",2,"delta",4,"adaptive_mu",0);
|
||||||
|
[y_ml_mlse,y_ref] = ml_mlse_equalizer.process(Rx_sig_2sps_v1,Symbols_v1);
|
||||||
|
ref_bits = PAMmapper(M,0).demap(y_ref);
|
||||||
|
ml_bits = PAMmapper(M,0).demap(y_ml_mlse);
|
||||||
|
[~,~,ber_ml2(i)] = calc_ber(ml_bits.signal, ref_bits.signal, ...
|
||||||
|
"skip_front",10,"skip_end",10);
|
||||||
|
|
||||||
|
%% ML-based MLSE (L=3)
|
||||||
|
ml_mlse_equalizer = ML_MLSE("epochs_tr",training_epochs,"epochs_dd",1, ...
|
||||||
|
"len_tr",2^16,"mu_dd",mu_ml,"mu_tr",mu_ml,"order",11,"sps",2, ...
|
||||||
|
"traceback_depth",128,"L",3,"delta",4,"adaptive_mu",0);
|
||||||
|
[y_ml_mlse,y_ref] = ml_mlse_equalizer.process(Rx_sig_2sps_v1,Symbols_v1);
|
||||||
|
ref_bits = PAMmapper(M,0).demap(y_ref);
|
||||||
|
ml_bits = PAMmapper(M,0).demap(y_ml_mlse);
|
||||||
|
[~,~,ber_ml3(i)] = calc_ber(ml_bits.signal, ref_bits.signal, ...
|
||||||
|
"skip_front",10,"skip_end",10);
|
||||||
|
end % ROP loop
|
||||||
|
|
||||||
|
%% --- find required ROP (FEC crossing)
|
||||||
|
reqROP_FFE(L) = interp_fec_cross(rops, ber_ffe, FEC_thr);
|
||||||
|
reqROP_MLSE(L) = interp_fec_cross(rops, ber_mlse, FEC_thr);
|
||||||
|
reqROP_DBTGT(L) = interp_fec_cross(rops, ber_dbtgt, FEC_thr);
|
||||||
|
reqROP_ML_MLSE2(L) = interp_fec_cross(rops, ber_ml2, FEC_thr);
|
||||||
|
reqROP_ML_MLSE3(L) = interp_fec_cross(rops, ber_ml3, FEC_thr);
|
||||||
|
|
||||||
|
fprintf('Length %.0f m: FFE %.1f, MLSE %.1f, DB %.1f, ML2 %.1f, ML3 %.1f\n', ...
|
||||||
|
link_length_m, reqROP_FFE(L), reqROP_MLSE(L), reqROP_DBTGT(L), ...
|
||||||
|
reqROP_ML_MLSE2(L), reqROP_ML_MLSE3(L));
|
||||||
|
end
|
||||||
|
|
||||||
|
%% ====================== PLOT REQUIRED ROP ======================
|
||||||
|
cols = cbrewer2('Set1',8);
|
||||||
|
colFFE = cols(1,:);
|
||||||
|
colMLSE = cols(2,:);
|
||||||
|
colDBTGT = cols(4,:);
|
||||||
|
colML_MLSE = cols(3,:);
|
||||||
|
|
||||||
|
figure(); hold on
|
||||||
|
plot(link_lengths, reqROP_FFE, '-o','Color',colFFE, 'DisplayName','FFE');
|
||||||
|
plot(link_lengths, reqROP_MLSE, '-s','Color',colMLSE, 'DisplayName','FFE+PF+MLSE');
|
||||||
|
plot(link_lengths, reqROP_DBTGT, '--^','Color',colDBTGT, 'DisplayName','DB tgt. MLSE');
|
||||||
|
plot(link_lengths, reqROP_ML_MLSE2, '-v','Color',colML_MLSE, 'DisplayName','ML-based MLSE (L=2)');
|
||||||
|
plot(link_lengths, reqROP_ML_MLSE3, '-d','Color',colML_MLSE*0.8,'DisplayName','ML-based MLSE (L=3)');
|
||||||
|
|
||||||
|
xlabel('Link length [km]');
|
||||||
|
ylabel('Required ROP [dBm]');
|
||||||
|
title(sprintf('Required ROP the reach FEC threshold (3.8e-3); %.0f GBd PAM-%d', baudrate.*1e-9, M));
|
||||||
|
legend('Location','northwest');
|
||||||
|
grid on;
|
||||||
|
beautifyBERplot("logscale",0,"polyfit",1,"polyorder",3,"fitmethod",'smoothingspline');
|
||||||
@@ -22,7 +22,7 @@ function [Rx_sig_2sps,Symbols,Tx_bits] = standard_link_model(options)
|
|||||||
options.laser_linewidth (1,1) double = 1e6
|
options.laser_linewidth (1,1) double = 1e6
|
||||||
|
|
||||||
% --- Channel parameters ---
|
% --- Channel parameters ---
|
||||||
options.link_length_m (1,1) double = 0
|
options.link_length_km (1,1) double = 0
|
||||||
options.rop (1,:) double = -5
|
options.rop (1,:) double = -5
|
||||||
options.fsym (1,:) double = (212:16:256)*1e9
|
options.fsym (1,:) double = (212:16:256)*1e9
|
||||||
options.doub_mode (1,1) db_mode = db_mode.no_db
|
options.doub_mode (1,1) db_mode = db_mode.no_db
|
||||||
@@ -57,7 +57,7 @@ function [Rx_sig_2sps,Symbols,Tx_bits] = standard_link_model(options)
|
|||||||
"randomkey",options.random_key+1).process(El_sig);
|
"randomkey",options.random_key+1).process(El_sig);
|
||||||
|
|
||||||
% --- Fiber ---
|
% --- Fiber ---
|
||||||
Opt_sig = Fiber("fsimu",Opt_sig.fs,"fiber_length",options.link_length_m, ...
|
Opt_sig = Fiber("fsimu",Opt_sig.fs,"fiber_length",options.link_length_km, ...
|
||||||
"alpha",0.3,"D",0,"lambda0",1310,"gamma",0,"Dslope",0.07).process(Opt_sig);
|
"alpha",0.3,"D",0,"lambda0",1310,"gamma",0,"Dslope",0.07).process(Opt_sig);
|
||||||
|
|
||||||
% --- Amplifier (ROP set) ---
|
% --- Amplifier (ROP set) ---
|
||||||
@@ -90,6 +90,10 @@ function [Rx_sig_2sps,Symbols,Tx_bits] = standard_link_model(options)
|
|||||||
[~,Scpe_cell,~,found_sync] = Scpe_sig_2sps.tsynch( ...
|
[~,Scpe_cell,~,found_sync] = Scpe_sig_2sps.tsynch( ...
|
||||||
"reference",Symbols,"fs_ref",options.fsym,"debug_plots",0);
|
"reference",Symbols,"fs_ref",options.fsym,"debug_plots",0);
|
||||||
|
|
||||||
Rx_sig_2sps = Scpe_cell{1}.normalize("mode","rms");
|
try
|
||||||
|
Rx_sig_2sps = Scpe_cell{1}.normalize("mode","rms");
|
||||||
|
catch
|
||||||
|
Rx_sig_2sps = Scpe_sig_2sps.normalize("mode","rms");
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
157
projects/ML_based_MLSE/theoretic_channel_evaluation.m
Normal file
157
projects/ML_based_MLSE/theoretic_channel_evaluation.m
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
|
||||||
|
M = 4;
|
||||||
|
order = 18;
|
||||||
|
randkey = 1;
|
||||||
|
|
||||||
|
bitpattern = [];
|
||||||
|
s = RandStream('twister','Seed',randkey);
|
||||||
|
for i = 1:log2(M)
|
||||||
|
N = 2^(order-1); %length of prbs
|
||||||
|
bitpattern(:,i) = randi(s,[0 1], N, 1);
|
||||||
|
end
|
||||||
|
|
||||||
|
if M == 6
|
||||||
|
bitpattern = reshape(bitpattern',[],1);
|
||||||
|
bitpattern = bitpattern(1:end-mod(length(bitpattern),5));
|
||||||
|
end
|
||||||
|
|
||||||
|
Bits = Informationsignal(bitpattern);
|
||||||
|
|
||||||
|
Symbols = PAMmapper(M,0).map(Bits);
|
||||||
|
Symbols.fs = 200e9;
|
||||||
|
|
||||||
|
Bits_ = PAMmapper(M, 0, "eth_style", 0).demap(Symbols);
|
||||||
|
|
||||||
|
% --- Channel: minimal ISI response + AWGN ---
|
||||||
|
h = [0.3 0.9 0.3,0.1]; % impulse response (normalized later if desired)
|
||||||
|
h = h / norm(h); % optional normalization for unit energy
|
||||||
|
|
||||||
|
symbols_filt = Symbols.filter(h,1);
|
||||||
|
|
||||||
|
|
||||||
|
%% SHOW FIG 3 in Paper: "ML Base Pre-Eq"
|
||||||
|
|
||||||
|
SNR_dB = [20:1:25];
|
||||||
|
SNR_db = linspace(12,25,12);
|
||||||
|
|
||||||
|
ber_ffe = zeros(size(SNR_dB));
|
||||||
|
ber_mlse_l5 = zeros(size(SNR_dB));
|
||||||
|
ber_nwf_mlse_l2 = zeros(size(SNR_dB));
|
||||||
|
ber_ml_mlse_l2 = zeros(size(SNR_dB));
|
||||||
|
ber_ml_mlse_l3 = zeros(size(SNR_dB));
|
||||||
|
ber_ml_mlse_l4 = zeros(size(SNR_dB));
|
||||||
|
|
||||||
|
epochs_training = 100;
|
||||||
|
|
||||||
|
for i = 1:numel(SNR_dB)
|
||||||
|
|
||||||
|
symbols_noi = symbols_filt;
|
||||||
|
symbols_noi.signal = awgn(symbols_filt.signal, SNR_dB(i), 'measured'); % AWGN with given SNR
|
||||||
|
|
||||||
|
% Sequence Est L=5
|
||||||
|
mlse_ = MLSE("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels,'scale_mode',0,'trellis_exclusion',0,'trellis_state_mode',2,'debug',0,'DIR',h);
|
||||||
|
mlse_.DIR = h;
|
||||||
|
[y_mlse] = mlse_.process(symbols_noi,Symbols);
|
||||||
|
mlse_bits = PAMmapper(M, 0, "eth_style", 0).demap(y_mlse);
|
||||||
|
[~, ~, ber_mlse_l5(i), ~] = calc_ber(mlse_bits.signal, Bits.signal, "skip_front", 10, "skip_end", 10, "returnErrorLocation", 1);
|
||||||
|
fprintf('MLSE L5: %.2e \n',ber_mlse_l5(i));
|
||||||
|
|
||||||
|
% 2nd Approach
|
||||||
|
mu_lms = 0.0005;
|
||||||
|
pf_ncoeffs = 1;
|
||||||
|
eq_ = FFE("epochs_tr",5,"epochs_dd",5,"len_tr",2^13,"mu_dd",mu_lms,"mu_tr",mu_lms,"order",16,"sps",1,"dd_mode",1,"adaption_technique","lms");
|
||||||
|
pf_ = Postfilter("ncoeff",pf_ncoeffs,"useBurg",1);
|
||||||
|
|
||||||
|
% FFE
|
||||||
|
[y_ffe, ffe_noise] = eq_.process(symbols_noi, Symbols);
|
||||||
|
|
||||||
|
Eq_bits = PAMmapper(M, 0, "eth_style", 0).demap(y_ffe);
|
||||||
|
[~, ~, ber_ffe(i), ~] = calc_ber(Eq_bits.signal, Bits.signal, "skip_front", 0, "skip_end", 0, "returnErrorLocation", 1);
|
||||||
|
fprintf('FFE: %.2e \n',ber_ffe(i));
|
||||||
|
|
||||||
|
% Postfilter
|
||||||
|
[y_white,~] = pf_.process(y_ffe, ffe_noise);
|
||||||
|
|
||||||
|
% Sequence Est
|
||||||
|
mlse_ = MLSE("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels,'scale_mode',0,'trellis_exclusion',0,'trellis_state_mode',2,'debug',0,'DIR',pf_.coefficients);
|
||||||
|
[y_mlse] = mlse_.process(y_white,Symbols);
|
||||||
|
mlse_bits = PAMmapper(M, 0, "eth_style", 0).demap(y_mlse);
|
||||||
|
[~, errors, ber_nwf_mlse_l2(i), errpos] = calc_ber(mlse_bits.signal, Bits.signal, "skip_front", 10, "skip_end", 10, "returnErrorLocation", 1);
|
||||||
|
fprintf('MLSE: %.2e \n',ber_nwf_mlse_l2(i));
|
||||||
|
|
||||||
|
% ML-base MLSE L=2
|
||||||
|
adaptive_mu = 0;
|
||||||
|
mu_lms = 0.15;
|
||||||
|
ml_mlse_equalizer = ML_MLSE("epochs_tr",epochs_training,"epochs_dd",1,"len_tr",2^15,...
|
||||||
|
"mu_dd",mu_lms,"mu_tr",mu_lms,"order",11,"sps",1,...
|
||||||
|
"traceback_depth",128,"L",2,"delta",4,"adaptive_mu",adaptive_mu);
|
||||||
|
[y_ml_mlse,~] = ml_mlse_equalizer.process(symbols_noi,Symbols);
|
||||||
|
ml_mlse_bits = PAMmapper(M, 0, "eth_style", 0).demap(y_ml_mlse);
|
||||||
|
[~, errors, ber_ml_mlse_l2(i), errpos] = calc_ber(ml_mlse_bits.signal, Bits.signal, "skip_front", 10, "skip_end", 10, "returnErrorLocation", 1);
|
||||||
|
fprintf('ML MLSE BER: %.2e \n',ber_ml_mlse_l2(i));
|
||||||
|
|
||||||
|
% ML-base MLSE L=3
|
||||||
|
mu_lms = 0.15;
|
||||||
|
ml_mlse_equalizer = ML_MLSE("epochs_tr",epochs_training,"epochs_dd",1,"len_tr",2^16,...
|
||||||
|
"mu_dd",mu_lms,"mu_tr",mu_lms,"order",11,"sps",1,...
|
||||||
|
"traceback_depth",128,"L",3,"delta",4,"adaptive_mu",adaptive_mu);
|
||||||
|
[y_ml_mlse,~] = ml_mlse_equalizer.process(symbols_noi,Symbols);
|
||||||
|
ml_mlse_bits = PAMmapper(M, 0, "eth_style", 0).demap(y_ml_mlse);
|
||||||
|
[~, errors, ber_ml_mlse_l3(i), errpos] = calc_ber(ml_mlse_bits.signal, Bits.signal, "skip_front", 10, "skip_end", 10, "returnErrorLocation", 1);
|
||||||
|
fprintf('ML MLSE BER: %.2e \n',ber_ml_mlse_l3(i));
|
||||||
|
|
||||||
|
% % ML-base MLSE L=5
|
||||||
|
% mu_lms = 0.15;
|
||||||
|
% ml_mlse_equalizer = ML_MLSE("epochs_tr",epochs_training,"epochs_dd",1,"len_tr",2^15,...
|
||||||
|
% "mu_dd",mu_lms,"mu_tr",mu_lms,"order",11,"sps",1,...
|
||||||
|
% "traceback_depth",128,"L",5,"delta",4);
|
||||||
|
% [y_ml_mlse,~] = ml_mlse_equalizer.process(symbols_noi,Symbols);
|
||||||
|
% ml_mlse_bits = PAMmapper(M, 0, "eth_style", 0).demap(y_ml_mlse);
|
||||||
|
% [~, errors, ber_ml_mlse_l5(i), errpos] = calc_ber(ml_mlse_bits.signal, Bits.signal, "skip_front", 10, "skip_end", 10, "returnErrorLocation", 1);
|
||||||
|
% fprintf('ML MLSE BER: %.2e \n',ber_ml_mlse_l5(i));
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
%%
|
||||||
|
figure(); hold on;
|
||||||
|
|
||||||
|
% --- define scheme colors (consistent palette)
|
||||||
|
cols = cbrewer2('SET1',8);
|
||||||
|
colFFE = cols(1,:); % blue
|
||||||
|
colMLSE = cols(2,:); % orange
|
||||||
|
colML_MLSE = cols(3,:); % green
|
||||||
|
colNWF_MLSE = cols(4,:); % purple
|
||||||
|
|
||||||
|
% --- local simulation results
|
||||||
|
plot(SNR_dB, ber_ffe, '-o', 'Color', colFFE, 'DisplayName','FFE (N=16)');
|
||||||
|
if M==2, plot(FFE_wpd.X, FFE_wpd.Y, ':', 'LineWidth',1.5, 'Color', colFFE, 'DisplayName','Paper FFE'); end
|
||||||
|
|
||||||
|
|
||||||
|
plot(SNR_dB, ber_mlse_l5, '-s', 'Color', colMLSE, 'DisplayName','MLSE (L=5)');
|
||||||
|
if M==2, plot(MLSE_wpd.X, MLSE_wpd.Y, ':', 'LineWidth',1.5, 'Color', colMLSE, 'DisplayName','Paper MLSE L=5'); end
|
||||||
|
|
||||||
|
plot(SNR_dB, ber_nwf_mlse_l2,'--^','Color', colNWF_MLSE, 'DisplayName','FFE+PF+MLSE (L=2)');
|
||||||
|
plot(SNR_dB, ber_ml_mlse_l2, '-v', 'Color', colML_MLSE, 'DisplayName','ML-based MLSE (L=2)');
|
||||||
|
if M==2, plot(ML_MLSE_L_2_wpd.X,ML_MLSE_L_2_wpd.Y,':', 'LineWidth',1.5, 'Color', colML_MLSE, 'DisplayName','Paper ML-based MLSE L=2'); end
|
||||||
|
|
||||||
|
|
||||||
|
plot(SNR_dB, ber_ml_mlse_l3, '-d', 'Color', colML_MLSE, 'DisplayName','ML-based MLSE (L=3)');
|
||||||
|
|
||||||
|
if M==2, plot(SNR_dB, ber_ml_mlse_l5, '-p', 'Color', colML_MLSE, 'DisplayName','ML-based MLSE (L=5)'); end
|
||||||
|
if M==2, plot(ML_MLSE_L_5_wpd.X,ML_MLSE_L_5_wpd.Y,':', 'LineWidth',1.5, 'Color', colML_MLSE, 'DisplayName','Paper ML-based MLSE L=5'); end
|
||||||
|
% --- imported WebPlotDigitizer data (dotted)
|
||||||
|
|
||||||
|
yline(3.8e-3,'HandleVisibility','off');
|
||||||
|
yline(2.2e-4,'HandleVisibility','off');
|
||||||
|
|
||||||
|
% --- formatting
|
||||||
|
beautifyBERplot;
|
||||||
|
xlim([SNR_dB(1), SNR_dB(end)]);
|
||||||
|
ylim([1e-5 0.1]);
|
||||||
|
xlabel('Input SNR [dB]');
|
||||||
|
ylabel('Bit Error Rate (BER)');
|
||||||
|
title('PAM-4; M=4; AWGN Channel');
|
||||||
|
legend('Location','southwest');
|
||||||
|
grid on;
|
||||||
|
|
||||||
Reference in New Issue
Block a user