Merge branch 'main' of cau-git.rz.uni-kiel.de:nt/mitarbeiter/silas/imdd_simulation
This commit is contained in:
@@ -10,6 +10,10 @@ classdef EQ < handle
|
||||
training_length %Number of training symbols
|
||||
training_loops %Number of loops through sequence for training mode
|
||||
ideal_dfe %Error free DFE decisions
|
||||
weighted_DFE %Weighted DFE on/off
|
||||
weighted_DFE_mode %Weighted DFE mode
|
||||
weighted_DFE_d_min %d_min threshold parameter for weighted DFE mode 1
|
||||
weighted_DFE_I_mode %[a_s, b_s, I_max]-parameters for the weighted DFE
|
||||
|
||||
DB_aim %Aim at duobinary output sequence
|
||||
|
||||
@@ -68,6 +72,10 @@ classdef EQ < handle
|
||||
options.training_length = 1024 %Number of training symbols
|
||||
options.training_loops = 1 %Number of loops through sequence for training mode
|
||||
options.ideal_dfe = 0 %Error free DFE decisions
|
||||
options.weighted_DFE = 0;
|
||||
options.weighted_DFE_mode = 'R1';
|
||||
options.weighted_DFE_d_min = 0.5;
|
||||
options.weighted_DFE_I_mode = [5,0.5,0.6];
|
||||
|
||||
options.DB_aim %Aim at duobinary output sequence
|
||||
|
||||
@@ -438,6 +446,43 @@ classdef EQ < handle
|
||||
dd_out(k) = constellation_in_(dd_idx);
|
||||
end
|
||||
|
||||
% Implementation of a weighted DFE in
|
||||
% order to prevent error propagation.
|
||||
% For further details, study [1], chapter 3.2.2 -
|
||||
% Modifications of DFE
|
||||
|
||||
if obj.weighted_DFE
|
||||
% define new constellations
|
||||
const = unique(ref_in);
|
||||
|
||||
% determine reliability factor gamma_k
|
||||
if output_vec(m) > min(const) && output_vec(m) < max(const)
|
||||
gamma_k = 1 - abs(output_vec(m) - dd_out(k));
|
||||
else
|
||||
gamma_k = 1;
|
||||
end
|
||||
|
||||
% select mode
|
||||
if strcmp(obj.weighted_DFE_mode,'R1')
|
||||
if gamma_k >= obj.weighted_DFE_d_min
|
||||
f_gamma_k = 1;
|
||||
else
|
||||
f_gamma_k = 0;
|
||||
end
|
||||
elseif strcmp(obj.weighted_DFE_mode,'R2')
|
||||
f_gamma_k = gamma_k;
|
||||
elseif strcmp(obj.weighted_DFE_mode,'I1')
|
||||
nom = 1-exp(-obj.weighted_DFE_I_mode(1)*((gamma_k/obj.weighted_DFE_I_mode(2))-1));
|
||||
denom = 1+exp(-obj.weighted_DFE_I_mode(1)*((gamma_k/obj.weighted_DFE_I_mode(2))-1));
|
||||
f_gamma_k = (1/2)*((nom/denom) - 1);
|
||||
elseif strcmp(obj.weighted_DFE_mode,'I2')
|
||||
nom = 1-exp(-obj.weighted_DFE_I_mode(1)*((gamma_k/obj.weighted_DFE_I_mode(2))-1));
|
||||
denom = 1+exp(-obj.weighted_DFE_I_mode(1)*((gamma_k/obj.weighted_DFE_I_mode(2))-1));
|
||||
f_gamma_k = (obj.weighted_DFE_I_mode(3)/2)*((nom/denom) - 1);
|
||||
end
|
||||
% calculate weighted output
|
||||
output_vec(m) = f_gamma_k.*dd_out(k)+(1-f_gamma_k).*output_vec(m);
|
||||
end
|
||||
|
||||
if obj.Nb(1) > 0
|
||||
dd_DFE(2:end) = dd_DFE(1:end-1);
|
||||
@@ -739,3 +784,6 @@ classdef EQ < handle
|
||||
end
|
||||
end
|
||||
|
||||
% References
|
||||
% [1] T. J. Wettlin, “Experimental Evaluation of Advanced Digital Signal Processing for Intra-Datacenter Systems using Direct-Detection,” 2023. [Online]. Available: https://nbn-resolving.org/urn:nbn:de:gbv:8:3-2023-00703-8
|
||||
|
||||
|
||||
@@ -597,7 +597,7 @@ classdef ML_MLSE < handle
|
||||
obj.S = obj.nSym;
|
||||
obj.Nf = obj.order * obj.sps;
|
||||
obj.nStates = obj.S^obj.L;
|
||||
obj.nFeasible = obj.nStates * obj.S; %feasible state transitions
|
||||
obj.nFeasible = obj.nStates * obj.S;
|
||||
|
||||
% --- Trellis mapping
|
||||
obj.trellis_states = reshape(obj.constellation,1,[]);
|
||||
|
||||
@@ -135,10 +135,10 @@ Time_Rec = 1;
|
||||
if Time_Rec
|
||||
% [Rx_Time_Rec, Timing_Error] = Timing_Recovery("modulation", 'PAM/PSK/QAM', "timing_error_detector",'Gardner (non-data-aided)','sps',Kov,'damping_factor',1,'normalized_loop_bandwidth',1e-4,'detector_gain',2.7).process(Rx_matched_1);
|
||||
|
||||
[Rx_Time_Rec, Timing_Error_MG] = Godard_Timing_Recovery('mode',3,'num_blocks',1,'fft_length',length(Rx_matched_1),'sps',Kov,'rolloff',0.6,'mu',-0.2,'Ki',1e-4).process(Rx_matched_1);
|
||||
Rx_Time_Rec = Rx_Time_Rec.resample('fs_in',Kov*fsym,'fs_out',fsym);
|
||||
% [Rx_Time_Rec, Timing_Error_MG] = Godard_Timing_Recovery('mode',3,'num_blocks',1,'fft_length',length(Rx_matched_1),'sps',Kov,'rolloff',0.6,'mu',-0.2,'Ki',1e-4).process(Rx_matched_1);
|
||||
% Rx_Time_Rec = Rx_Time_Rec.resample('fs_in',Kov*fsym,'fs_out',fsym);
|
||||
|
||||
% Rx_Time_Rec = MaxVar_Timing_Recovery('mode',0,'fsym',fsym,'fadc',Kov*fsym,'num_tau',Kov*128,'sps',Kov,'comp_signal',Rx_tr_mf,'comp_mode',0).process(Rx_matched_1);
|
||||
Rx_Time_Rec = MaxVar_Timing_Recovery('mode',0,'fsym',fsym,'fadc',Kov*fsym,'num_tau',Kov*128,'sps',Kov,'comp_signal',Rx_tr_mf,'comp_mode',0).process(Rx_matched_1);
|
||||
|
||||
sps = 1;
|
||||
else
|
||||
@@ -232,40 +232,40 @@ for our_signal = 1
|
||||
% end
|
||||
|
||||
%% -------------------- VNLE + MLSE --------------------
|
||||
pf_ncoeffs = 4;
|
||||
eq_v = EQ("Ne",[300, 0, 0],"Nb",[0, 0, 0], ...
|
||||
"training_length",len_tr,"training_loops",5,"dd_loops",5, ...
|
||||
"K",sps,"DCmu",mu_dc,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005, ...
|
||||
"FFEmu",0,"plotfinal",0,"ideal_dfe",1, ...
|
||||
'weighted_DFE',0,'weighted_DFE_d_min',0.5,'weighted_DFE_mode','R2','weighted_DFE_I_mode',[5,0.5,0.6]);
|
||||
% eq_v = FFE_DFE('ffe_order',300,'dfe_order',5,'len_tr',len_tr,'epochs_tr',5,'epochs_dd',5, ...
|
||||
% 'ffe_mu_dd',mu_ffe,'ffe_mu_tr',0,'dfe_mu_dd',mu_dfe,'dfe_mu_tr',0.005,'sps',sps,'decide',0);
|
||||
pf_ = Postfilter("ncoeff",pf_ncoeffs,"useBurg",1);
|
||||
mlse_ = MLSE("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0,"eth_style",mapping_style).levels);
|
||||
|
||||
[vnle_results, mlse_results] = vnle_postfilter_mlse(eq_v, pf_, mlse_, M, Rx_synced, Symbols, Bits, ...
|
||||
"precode_mode", duob_mode, 'showAnalysis', 1, "postFFE", [], "eth_style_symbol_mapping", mapping_style);
|
||||
|
||||
mlse_results.metrics.print
|
||||
if our_signal
|
||||
fprintf('Our Signal: %.1e \n',mlse_results.metrics.BER);
|
||||
fprintf('Paper: %.1e \n \n',ber_in_paper);
|
||||
else
|
||||
fprintf('Their Signal: %.1e \n',mlse_results.metrics.BER);
|
||||
fprintf('Paper: %.1e \n \n',ber_in_paper);
|
||||
end
|
||||
|
||||
%% -------------------- ML-based MLSE (L=2) --------------------
|
||||
% ml_mlse_equalizer = ML_MLSE("epochs_tr",100,"epochs_dd",1, ...
|
||||
% "len_tr",length(Rx_synced),"mu_dd",0.03,"mu_tr",0.03,"order",11,"sps",sps, ...
|
||||
% "traceback_depth",256,"L",4,"delta",4,"adaptive_mu",0);
|
||||
% pf_ncoeffs = 4;
|
||||
% eq_v = EQ("Ne",[300, 0, 0],"Nb",[0, 0, 0], ...
|
||||
% "training_length",len_tr,"training_loops",5,"dd_loops",5, ...
|
||||
% "K",sps,"DCmu",mu_dc,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005, ...
|
||||
% "FFEmu",0,"plotfinal",0,"ideal_dfe",1, ...
|
||||
% 'weighted_DFE',0,'weighted_DFE_d_min',0.5,'weighted_DFE_mode','R2','weighted_DFE_I_mode',[5,0.5,0.6]);
|
||||
% % eq_v = FFE_DFE('ffe_order',300,'dfe_order',5,'len_tr',len_tr,'epochs_tr',5,'epochs_dd',5, ...
|
||||
% % 'ffe_mu_dd',mu_ffe,'ffe_mu_tr',0,'dfe_mu_dd',mu_dfe,'dfe_mu_tr',0.005,'sps',sps,'decide',0);
|
||||
% pf_ = Postfilter("ncoeff",pf_ncoeffs,"useBurg",1);
|
||||
% mlse_ = MLSE("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0,"eth_style",mapping_style).levels);
|
||||
%
|
||||
% [ml_mlse_results] = ml_mlse(ml_mlse_equalizer, M, Rx_synced, Symbols, Bits,"precode_mode",duob_mode,"eth_style_symbol_mapping",mapping_style);
|
||||
% [vnle_results, mlse_results] = vnle_postfilter_mlse(eq_v, pf_, mlse_, M, Rx_synced, Symbols, Bits, ...
|
||||
% "precode_mode", duob_mode, 'showAnalysis', 1, "postFFE", [], "eth_style_symbol_mapping", mapping_style);
|
||||
%
|
||||
% mlse_results.metrics.print
|
||||
% if our_signal
|
||||
% fprintf('Our Signal: %.1e \n',ml_mlse_results.metrics.BER);
|
||||
% fprintf('Our Signal: %.1e \n',mlse_results.metrics.BER);
|
||||
% fprintf('Paper: %.1e \n \n',ber_in_paper);
|
||||
% else
|
||||
% fprintf('Their EQ: %.1e \n',ml_mlse_results.metrics.BER);
|
||||
% fprintf('Their Signal: %.1e \n',mlse_results.metrics.BER);
|
||||
% fprintf('Paper: %.1e \n \n',ber_in_paper);
|
||||
% end
|
||||
|
||||
%% -------------------- ML-based MLSE (L=2) --------------------
|
||||
ml_mlse_equalizer = ML_MLSE("epochs_tr",100,"epochs_dd",1, ...
|
||||
"len_tr",length(Rx_synced),"mu_dd",0.03,"mu_tr",0.03,"order",11,"sps",sps, ...
|
||||
"traceback_depth",256,"L",1,"delta",4,"adaptive_mu",0);
|
||||
|
||||
[ml_mlse_results] = ml_mlse(ml_mlse_equalizer, M, Rx_synced, Symbols, Bits,"precode_mode",duob_mode,"eth_style_symbol_mapping",mapping_style);
|
||||
if our_signal
|
||||
fprintf('Our Signal: %.1e \n',ml_mlse_results.metrics.BER);
|
||||
fprintf('Paper: %.1e \n \n',ber_in_paper);
|
||||
else
|
||||
fprintf('Their EQ: %.1e \n',ml_mlse_results.metrics.BER);
|
||||
fprintf('Paper: %.1e \n \n',ber_in_paper);
|
||||
end
|
||||
end
|
||||
@@ -212,40 +212,40 @@ for our_signal = 1
|
||||
% end
|
||||
|
||||
%% -------------------- VNLE + MLSE --------------------
|
||||
pf_ncoeffs = 4;
|
||||
eq_v = EQ("Ne",[300, 0, 0],"Nb",[0, 0, 0], ...
|
||||
"training_length",len_tr,"training_loops",5,"dd_loops",5, ...
|
||||
"K",sps,"DCmu",mu_dc,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005, ...
|
||||
"FFEmu",0,"plotfinal",0,"ideal_dfe",1, ...
|
||||
'weighted_DFE',0,'weighted_DFE_d_min',0.5,'weighted_DFE_mode','R2','weighted_DFE_I_mode',[5,0.5,0.6]);
|
||||
% eq_v = FFE_DFE('ffe_order',300,'dfe_order',5,'len_tr',len_tr,'epochs_tr',5,'epochs_dd',5, ...
|
||||
% 'ffe_mu_dd',mu_ffe,'ffe_mu_tr',0,'dfe_mu_dd',mu_dfe,'dfe_mu_tr',0.005,'sps',sps,'decide',0);
|
||||
pf_ = Postfilter("ncoeff",pf_ncoeffs,"useBurg",1);
|
||||
mlse_ = MLSE("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0,"eth_style",mapping_style).levels);
|
||||
|
||||
[vnle_results, mlse_results] = vnle_postfilter_mlse(eq_v, pf_, mlse_, M, Rx_synced, Symbols, Bits, ...
|
||||
"precode_mode", duob_mode, 'showAnalysis', 1, "postFFE", [], "eth_style_symbol_mapping", mapping_style);
|
||||
|
||||
mlse_results.metrics.print
|
||||
if our_signal
|
||||
fprintf('Our Signal: %.1e \n',mlse_results.metrics.BER);
|
||||
fprintf('Paper: %.1e \n \n',ber_in_paper);
|
||||
else
|
||||
fprintf('Their Signal: %.1e \n',mlse_results.metrics.BER);
|
||||
fprintf('Paper: %.1e \n \n',ber_in_paper);
|
||||
end
|
||||
|
||||
%% -------------------- ML-based MLSE (L=2) --------------------
|
||||
% ml_mlse_equalizer = ML_MLSE("epochs_tr",100,"epochs_dd",1, ...
|
||||
% "len_tr",length(Rx_synced),"mu_dd",0.03,"mu_tr",0.03,"order",11,"sps",sps, ...
|
||||
% "traceback_depth",256,"L",4,"delta",4,"adaptive_mu",0);
|
||||
% pf_ncoeffs = 4;
|
||||
% eq_v = EQ("Ne",[300, 0, 0],"Nb",[0, 0, 0], ...
|
||||
% "training_length",len_tr,"training_loops",5,"dd_loops",5, ...
|
||||
% "K",sps,"DCmu",mu_dc,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005, ...
|
||||
% "FFEmu",0,"plotfinal",0,"ideal_dfe",1, ...
|
||||
% 'weighted_DFE',0,'weighted_DFE_d_min',0.5,'weighted_DFE_mode','R2','weighted_DFE_I_mode',[5,0.5,0.6]);
|
||||
% % eq_v = FFE_DFE('ffe_order',300,'dfe_order',5,'len_tr',len_tr,'epochs_tr',5,'epochs_dd',5, ...
|
||||
% % 'ffe_mu_dd',mu_ffe,'ffe_mu_tr',0,'dfe_mu_dd',mu_dfe,'dfe_mu_tr',0.005,'sps',sps,'decide',0);
|
||||
% pf_ = Postfilter("ncoeff",pf_ncoeffs,"useBurg",1);
|
||||
% mlse_ = MLSE("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0,"eth_style",mapping_style).levels);
|
||||
%
|
||||
% [ml_mlse_results] = ml_mlse(ml_mlse_equalizer, M, Rx_synced, Symbols, Bits,"precode_mode",duob_mode,"eth_style_symbol_mapping",mapping_style);
|
||||
% [vnle_results, mlse_results] = vnle_postfilter_mlse(eq_v, pf_, mlse_, M, Rx_synced, Symbols, Bits, ...
|
||||
% "precode_mode", duob_mode, 'showAnalysis', 1, "postFFE", [], "eth_style_symbol_mapping", mapping_style);
|
||||
%
|
||||
% mlse_results.metrics.print
|
||||
% if our_signal
|
||||
% fprintf('Our Signal: %.1e \n',ml_mlse_results.metrics.BER);
|
||||
% fprintf('Our Signal: %.1e \n',mlse_results.metrics.BER);
|
||||
% fprintf('Paper: %.1e \n \n',ber_in_paper);
|
||||
% else
|
||||
% fprintf('Their EQ: %.1e \n',ml_mlse_results.metrics.BER);
|
||||
% fprintf('Their Signal: %.1e \n',mlse_results.metrics.BER);
|
||||
% fprintf('Paper: %.1e \n \n',ber_in_paper);
|
||||
% end
|
||||
|
||||
%% -------------------- ML-based MLSE (L=2) --------------------
|
||||
ml_mlse_equalizer = ML_MLSE("epochs_tr",100,"epochs_dd",1, ...
|
||||
"len_tr",length(Rx_synced),"mu_dd",0.03,"mu_tr",0.03,"order",80,"sps",sps, ...
|
||||
"traceback_depth",256,"L",1,"delta",4,"adaptive_mu",0);
|
||||
|
||||
[ml_mlse_results] = ml_mlse(ml_mlse_equalizer, M, Rx_synced, Symbols, Bits,"precode_mode",duob_mode,"eth_style_symbol_mapping",mapping_style);
|
||||
if our_signal
|
||||
fprintf('Our Signal: %.1e \n',ml_mlse_results.metrics.BER);
|
||||
fprintf('Paper: %.1e \n \n',ber_in_paper);
|
||||
else
|
||||
fprintf('Their EQ: %.1e \n',ml_mlse_results.metrics.BER);
|
||||
fprintf('Paper: %.1e \n \n',ber_in_paper);
|
||||
end
|
||||
end
|
||||
6961
tore --source rescue-premerge -- Classes
Normal file
6961
tore --source rescue-premerge -- Classes
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,150 @@
|
||||
[1mdiff --git a/Classes/00_signals/Signal.m b/Classes/00_signals/Signal.m[m
|
||||
[1mindex e06c41f..f09a03e 100644[m
|
||||
[1m--- a/Classes/00_signals/Signal.m[m
|
||||
[1m+++ b/Classes/00_signals/Signal.m[m
|
||||
[36m@@ -172,11 +172,9 @@[m [mclassdef Signal[m
|
||||
[m
|
||||
hold on;[m
|
||||
if isempty(options.color)[m
|
||||
[31m- % plot(t* 1e6, sig(1:length(t)), 'DisplayName', dn, 'LineWidth', 0.1, 'Marker', '.', 'LineStyle','none', 'MarkerSize', 0.1);[m
|
||||
[31m- plot(t* 1e6, sig(1:length(t)), 'DisplayName', dn, 'LineWidth', 0.1);[m
|
||||
[32m+[m[32m plot(t* 1e6, sig(1:length(t)), 'DisplayName', dn, 'LineWidth', 0.1, 'Marker', '.', 'LineStyle','none', 'MarkerSize', 0.1);[m[41m
|
||||
[m
|
||||
else[m
|
||||
[31m- % plot(t* 1e6, sig(1:length(t)), 'DisplayName', dn, 'LineWidth', 0.1, 'Marker', '.', 'LineStyle','none', 'MarkerSize', 0.1,'Color',options.color);[m
|
||||
[31m- plot(t* 1e6, sig(1:length(t)), 'DisplayName', dn, 'LineWidth', 0.1, 'Color',options.color);[m
|
||||
[32m+[m[32m plot(t* 1e6, sig(1:length(t)), 'DisplayName', dn, 'LineWidth', 0.1, 'Marker', '.', 'LineStyle','none', 'MarkerSize', 0.1,'Color',options.color);[m[41m
|
||||
[m
|
||||
end[m
|
||||
% 2 c)[m
|
||||
% - xlabel if not already here: time in readable format (1 ms and not 1e-3 s)[m
|
||||
[1mdiff --git a/Classes/02_optical/DP_Fiber.m b/Classes/02_optical/DP_Fiber.m[m
|
||||
[1mindex a5f3dce..c1f08ea 100644[m
|
||||
[1m--- a/Classes/02_optical/DP_Fiber.m[m
|
||||
[1m+++ b/Classes/02_optical/DP_Fiber.m[m
|
||||
[36m@@ -24,6 +24,8 @@[m [mclassdef DP_Fiber[m
|
||||
SS_dzmax % [m] max dz (adaptive SSFM)[m
|
||||
SS_dzmin % [m] min dz (adaptive SSFM)[m
|
||||
n_waveplates % number of PMD waveplates[m
|
||||
[32m+[m[32m useGPU % GPU acceleration: true, false, or 'auto' (default)[m
|
||||
[32m+[m[32m useSingle % Use single precision on GPU (default: false)[m
|
||||
[m
|
||||
% ---- Internal state (persistent between calls) ----[m
|
||||
state % struct mirroring legacy 'state'[m
|
||||
[36m@@ -56,6 +58,8 @@[m [mclassdef DP_Fiber[m
|
||||
options.SS_dzmax = 2e4 % m[m
|
||||
options.SS_dzmin = 100 % m[m
|
||||
options.n_waveplates = 100[m
|
||||
[32m+[m[32m options.useGPU = 'auto' % 'auto', true, or false[m
|
||||
[32m+[m[32m options.useSingle = false % single precision GPU[m
|
||||
end[m
|
||||
[m
|
||||
% Copy provided options into properties[m
|
||||
[36m@@ -208,7 +212,7 @@[m [mclassdef DP_Fiber[m
|
||||
% Frequency-dependent PMD phase term (legacy form)[m
|
||||
st.brf.db0 = (R.rand(st.wave_plates,1)*2*pi - pi) * brf_multiplier;[m
|
||||
st.brf.db1 = sqrt(3*pi/8)*(st.dgd/obj.fa)/st.wave_plates .* st.omega;[m
|
||||
[31m- st.brf.simdgd = 0; [m
|
||||
[32m+[m[32m st.brf.simdgd = 0;[m
|
||||
% cumsum used in legacy only for debug; keep compatibility variable:[m
|
||||
~cumsum(st.brf.db0); % no-op to mirror legacy path[m
|
||||
[m
|
||||
[36m@@ -228,7 +232,18 @@[m [mclassdef DP_Fiber[m
|
||||
x_in = signal_in(:,1).';[m
|
||||
y_in = signal_in(:,2).';[m
|
||||
[m
|
||||
[31m- [x_out, y_out, obj.state] = CNLSE_plain(x_in, y_in, obj.state);[m
|
||||
[32m+[m[32m % Determine GPU usage[m
|
||||
[32m+[m[32m if ischar(obj.useGPU) || isstring(obj.useGPU)[m
|
||||
[32m+[m[32m if strcmpi(obj.useGPU, 'auto')[m
|
||||
[32m+[m[32m gpuFlag = []; % Let CNLSE_plain auto-detect[m
|
||||
[32m+[m[32m else[m
|
||||
[32m+[m[32m error('DP_Fiber:InvalidGPU', 'useGPU must be true, false, or ''auto''');[m
|
||||
[32m+[m[32m end[m
|
||||
[32m+[m[32m else[m
|
||||
[32m+[m[32m gpuFlag = logical(obj.useGPU);[m
|
||||
[32m+[m[32m end[m
|
||||
[32m+[m
|
||||
[32m+[m[32m [x_out, y_out, obj.state] = CNLSE_plain(x_in, y_in, obj.state, gpuFlag, obj.useSingle);[m
|
||||
[m
|
||||
obj.state.propagated_length = obj.state.propagated_length + obj.state.L;[m
|
||||
[m
|
||||
[1mdiff --git a/Classes/02_optical/Optical_Demultiplex.m b/Classes/02_optical/Optical_Demultiplex.m[m
|
||||
[1mindex 7d7c39e..8e272d2 100644[m
|
||||
[1m--- a/Classes/02_optical/Optical_Demultiplex.m[m
|
||||
[1m+++ b/Classes/02_optical/Optical_Demultiplex.m[m
|
||||
[36m@@ -42,7 +42,7 @@[m [mclassdef Optical_Demultiplex < handle[m
|
||||
[m
|
||||
function signalclasses_out = process(obj, signalclass_in)[m
|
||||
[m
|
||||
[31m- % ---- Infer wavelength: either given or from input total signal [m
|
||||
[32m+[m[32m % ---- Infer wavelength: either given or from input total signal[m
|
||||
if isempty(obj.wavelengthplan)[m
|
||||
obj.wavelengthplan = signalclass_in.lambda; %meter[m
|
||||
else[m
|
||||
[36m@@ -81,7 +81,7 @@[m [mclassdef Optical_Demultiplex < handle[m
|
||||
obj[m
|
||||
signal_in[m
|
||||
end[m
|
||||
[31m- [m
|
||||
[32m+[m
|
||||
w = obj.fs_out ./ obj.fs_in ;[m
|
||||
blocklen_in = length(signal_in);[m
|
||||
blocklen_out = w*blocklen_in;[m
|
||||
[36m@@ -119,30 +119,31 @@[m [mclassdef Optical_Demultiplex < handle[m
|
||||
N = size(lo,1);[m
|
||||
C = size(lo,2);[m
|
||||
[m
|
||||
[31m- x_envelopes = zeros(N, C, 'like', signal_in);[m
|
||||
[31m- y_envelopes = zeros(N, C, 'like', signal_in);[m
|
||||
[32m+[m[32m % ---- VECTORIZED: Process all channels in parallel ----[m
|
||||
[32m+[m[32m % Batched FFT operates on each column simultaneously on GPU[m
|
||||
[m
|
||||
[31m- s1 = signal_in(:,1);[m
|
||||
[31m- s2 = signal_in(:,2);[m
|
||||
[32m+[m[32m % Extract polarization signals[m
|
||||
[32m+[m[32m s1 = signal_in(:,1); % X polarization [N×1][m
|
||||
[32m+[m[32m s2 = signal_in(:,2); % Y polarization [N×1][m
|
||||
[m
|
||||
[31m- % Reusable work buffers (avoid reallocations)[m
|
||||
[31m- wrk_time = zeros(N,1, 'like', signal_in);[m
|
||||
[31m- wrk_freq = zeros(N,1, 'like', signal_in);[m
|
||||
[32m+[m[32m % Broadcast signal to all channels and multiply with LO[m
|
||||
[32m+[m[32m % s1, s2 are [N×1], lo is [N×C] → result is [N×C][m
|
||||
[32m+[m[32m x_mixed = att .* s1 .* lo; % [N×C][m
|
||||
[32m+[m[32m y_mixed = att .* s2 .* lo; % [N×C][m
|
||||
[32m+[m
|
||||
[32m+[m[32m % Batched FFT: each column computed in parallel[m
|
||||
[32m+[m[32m x_freq = fft(x_mixed); % [N×C][m
|
||||
[32m+[m[32m y_freq = fft(y_mixed); % [N×C][m
|
||||
[32m+[m
|
||||
[32m+[m[32m % Apply filter (H is [N×1], broadcasts across columns)[m
|
||||
[32m+[m[32m x_filtered = x_freq .* H; % [N×C][m
|
||||
[32m+[m[32m y_filtered = y_freq .* H; % [N×C][m
|
||||
[32m+[m
|
||||
[32m+[m[32m % Batched IFFT[m
|
||||
[32m+[m[32m x_envelopes = ifft(x_filtered); % [N×C][m
|
||||
[32m+[m[32m y_envelopes = ifft(y_filtered); % [N×C][m
|
||||
[m
|
||||
[31m- for c = 1:C[m
|
||||
[31m- % ---- X branch ----[m
|
||||
[31m- wrk_time(:) = att .* s1 .* lo(:,c); % N×1[m
|
||||
[31m- wrk_freq(:) = fft(wrk_time); % N×1[m
|
||||
[31m- wrk_freq(:) = wrk_freq .* H; % N×1[m
|
||||
[31m- x_envelopes(:,c) = ifft(wrk_freq); % N×1[m
|
||||
[m
|
||||
[31m- % ---- Y branch ----[m
|
||||
[31m- wrk_time(:) = att .* s2 .* lo(:,c);[m
|
||||
[31m- wrk_freq(:) = fft(wrk_time);[m
|
||||
[31m- wrk_freq(:) = wrk_freq .* H;[m
|
||||
[31m- y_envelopes(:,c) = ifft(wrk_freq);[m
|
||||
[31m- end[m
|
||||
[31m- [m
|
||||
end[m
|
||||
end[m
|
||||
end[m
|
||||
[1mdiff --git a/Classes/02_optical/Optical_Multiplex.m b/Classes/02_optical/Optical_Multiplex.m[m
|
||||
[1mindex 1d722b0..7fc8a33 100644[m
|
||||
[1m--- a/Classes/02_optical/Optical_Multiplex.m[m
|
||||
[1m+++ b/Classes/02_optical/Optical_Multiplex.m[m
|
||||
[36m@@ -1,10 +1,10 @@[m
|
||||
Reference in New Issue
Block a user