This reverts commit 798a0ca3b3
This commit is contained in:
Magnus Fischer
2026-02-02 12:12:33 +00:00
parent 005e821131
commit 9093fb2452
31 changed files with 385 additions and 2067 deletions

View File

@@ -1,72 +1,41 @@
function [opt_out_x,opt_out_y,state] = CNLSE_plain(opt_in_x,opt_in_y,state,useGPU,useSingle)
function [opt_out_x,opt_out_y,state] = CNLSE_plain(opt_in_x,opt_in_y,state)
% GPU auto-detection if not specified
if nargin < 4 || isempty(useGPU)
useGPU = canUseGPU();
end
if nargin < 5 || isempty(useSingle)
useSingle = false;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% pre calculations
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% pre calculations
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
state.common_beta=struct('X',0,'Y',0);
state.common_beta=struct('X',0,'Y',0);
for n=1:2
% get current polarization name and contrary one
curPol = state.polNames{n};
for n=1:2
% get current polarization name and contrary one
curPol = state.polNames{n};
% extend linear transfer function depending on beta values for the current polarization
% Was ist der Sinn dieser komischen beta notation? zB. state.beta.X = [0.3142 0 -9.1105e-28 5.1068e-41]
for n_beta = 1:length(state.beta.(curPol))
state.common_beta.(curPol) = state.common_beta.(curPol) + state.beta.(curPol)(n_beta) * (state.omega).^(n_beta-1) / factorial(n_beta-1);
% extend linear transfer function depending on beta values for the current polarization
% Was ist der Sinn dieser komischen beta notation? zB. state.beta.X = [0.3142 0 -9.1105e-28 5.1068e-41]
for n_beta = 1:length(state.beta.(curPol))
state.common_beta.(curPol) = state.common_beta.(curPol) + state.beta.(curPol)(n_beta) * (state.omega).^(n_beta-1) / factorial(n_beta-1);
end
%opt_out_struct.(curPol)=opt_in_struct.(curPol).envelope;
end
%opt_out_struct.(curPol)=opt_in_struct.(curPol).envelope;
end
beta_const = state.beta.('X')(1);
beta_1 = state.beta.('X')(2);
beta_2 = state.beta.('X')(3);
beta_3 = state.beta.('X')(4);
deltaomega = state.omega;
beta_x = beta_const + beta_1 * deltaomega + 1/2 * beta_2 * deltaomega.^2 + 1/6 *beta_3 * deltaomega.^3;
% opt_in_x = gpuArray(opt_in_x);
% opt_in_y = gpuArray(opt_in_y);
beta_const = state.beta.('X')(1);
beta_1 = state.beta.('X')(2);
beta_2 = state.beta.('X')(3);
beta_3 = state.beta.('X')(4);
deltaomega = state.omega;
beta_x = beta_const + beta_1 * deltaomega + 1/2 * beta_2 * deltaomega.^2 + 1/6 *beta_3 * deltaomega.^3;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% GPU Transfer (if enabled)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if useGPU
% Convert to single precision if requested (faster on most GPUs)
if useSingle
opt_in_x = gpuArray(single(opt_in_x));
opt_in_y = gpuArray(single(opt_in_y));
state.common_beta.X = gpuArray(single(state.common_beta.X));
state.common_beta.Y = gpuArray(single(state.common_beta.Y));
state.brf.db1 = gpuArray(single(state.brf.db1));
state.brf.db0 = gpuArray(single(state.brf.db0));
for k = 1:numel(state.brf.matR)
state.brf.matR{k} = gpuArray(single(state.brf.matR{k}));
end
else
opt_in_x = gpuArray(opt_in_x);
opt_in_y = gpuArray(opt_in_y);
state.common_beta.X = gpuArray(state.common_beta.X);
state.common_beta.Y = gpuArray(state.common_beta.Y);
state.brf.db1 = gpuArray(state.brf.db1);
state.brf.db0 = gpuArray(state.brf.db0);
for k = 1:numel(state.brf.matR)
state.brf.matR{k} = gpuArray(state.brf.matR{k});
end
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Split Step Method
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Split Step Method
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% [opt_out_x,opt_out_y] = split_step_loop(state.L,opt_in_x,opt_in_y,state.gamma,state.SS_dzmin,state.SS_dzmax,state.SS_dphimax,state.alpha_lin,...
% state.lin_z_test,state.corr_length,state.n_plates_done,state.missing_dz,state.brf,state.common_beta,....
@@ -75,33 +44,35 @@ end
% [opt_out_x,opt_out_y] = split_step_loop_mex(state.L,opt_in_x,opt_in_y,state.gamma,state.SS_dzmin,state.SS_dzmax,state.SS_dphimax,state.alpha_lin,...
% state.lin_z_test,state.corr_length,state.n_plates_done,state.missing_dz,state.brf,state.common_beta,....
% state.chi,state.manakov,state.beat_len);
% get nonlinear step size
[state.dz] = getNLstepsize(opt_in_x,opt_in_y,state.gamma,state.SS_dzmin,state.SS_dzmax,state.SS_dphimax,state.alpha_lin);
%[state.dz] = getNLstepsize_original(state,opt_out_struct);
state.n_step = 0;
state.z_prop = 0;
state.test_dz = [];
state.powers = [];
% get nonlinear step size
[state.dz] = getNLstepsize(opt_in_x,opt_in_y,state.gamma,state.SS_dzmin,state.SS_dzmax,state.SS_dphimax,state.alpha_lin);
%[state.dz] = getNLstepsize_original(state,opt_out_struct);
tic
state.n_step = 0;
state.z_prop = 0;
state.test_dz = [];
state.powers = [];
while state.z_prop < state.L
while state.z_prop < state.L
% reduce step length (dz) if we are to overshoot the fiber length
% (L) in the next step
if state.z_prop + state.dz > state.L
state.dz = state.L - state.z_prop;
end
% update step number (n)
state.n_step=state.n_step+1;
% reduce step length (dz) if we are to overshoot the fiber length
% (L) in the next step
if state.z_prop + state.dz > state.L
state.dz = state.L - state.z_prop;
end
% append current step length to logbook (dzs)
state.dzs(state.n_step)=state.dz;
% update step number (n)
state.n_step=state.n_step+1;
% append current step length to logbook (dzs)
state.dzs(state.n_step)=state.dz;
% half linear step
[opt_in_x,opt_in_y,state.z_prop,state.lin_z_test,...
% half linear step
[opt_in_x,opt_in_y,state.z_prop,state.lin_z_test,...
state.corr_length,state.n_plates_done,state.missing_dz,state.n_step,...
state.test_plates,state.test_plate_numbers,state.brf,state.common_beta.X,...
state.common_beta.Y,state.alpha_lin.X,state.alpha_lin.X]...
@@ -111,12 +82,12 @@ while state.z_prop < state.L
state.test_plates,state.test_plate_numbers,state.brf,state.common_beta.X,...
state.common_beta.Y,state.alpha_lin.X,state.alpha_lin.X);
% complete nonlinear step
[opt_in_x,opt_in_y] = nl_step(opt_in_x,opt_in_y, state.dz, state.gamma, state.chi, state.manakov, state.beat_len ,state.alpha_lin.X, state.alpha_lin.Y);
% half linear step
[opt_in_x,opt_in_y,state.z_prop,state.lin_z_test,...
% complete nonlinear step
[opt_in_x,opt_in_y] = nl_step(opt_in_x,opt_in_y, state.dz, state.gamma, state.chi, state.manakov, state.beat_len ,state.alpha_lin.X, state.alpha_lin.Y);
% half linear step
[opt_in_x,opt_in_y,state.z_prop,state.lin_z_test,...
state.corr_length,state.n_plates_done,state.missing_dz,state.n_step,...
state.test_plates,state.test_plate_numbers,state.brf,state.common_beta.X,...
state.common_beta.Y,state.alpha_lin.X,state.alpha_lin.X]...
@@ -126,34 +97,24 @@ while state.z_prop < state.L
state.test_plates,state.test_plate_numbers,state.brf,state.common_beta.X,...
state.common_beta.Y,state.alpha_lin.X,state.alpha_lin.X);
% get nonlinear step size
[state.dz] = getNLstepsize(opt_in_x,opt_in_y,state.gamma,state.SS_dzmin,state.SS_dzmax,state.SS_dphimax,state.alpha_lin);
%[state.dz] = getNLstepsize_original(state,opt_out_struct);
% get nonlinear step size
[state.dz] = getNLstepsize(opt_in_x,opt_in_y,state.gamma,state.SS_dzmin,state.SS_dzmax,state.SS_dphimax,state.alpha_lin);
%[state.dz] = getNLstepsize_original(state,opt_out_struct);
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% GPU Gather (if enabled)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if useGPU
opt_out_x = gather(opt_in_x);
opt_out_y = gather(opt_in_y);
% Gather state arrays back to CPU
state.common_beta.X = gather(state.common_beta.X);
state.common_beta.Y = gather(state.common_beta.Y);
state.brf.db1 = gather(state.brf.db1);
state.brf.db0 = gather(state.brf.db0);
for k = 1:numel(state.brf.matR)
state.brf.matR{k} = gather(state.brf.matR{k});
end
else
opt_out_x = opt_in_x;
opt_out_y = opt_in_y;
end
toc
opt_out_x = (opt_in_x);
opt_out_y = (opt_in_y);
% opt_out_x = gather(opt_in_x);
% opt_out_y = gather(opt_in_y);
end

View File

@@ -1,20 +0,0 @@
function canUse = canUseGPU()
%CANUSEGPU Check if a compatible GPU is available for parallel computing
% Returns true if MATLAB Parallel Computing Toolbox is available and
% a CUDA-capable GPU is detected.
canUse = false;
% Check if Parallel Computing Toolbox is installed
if ~license('test', 'Distrib_Computing_Toolbox')
return;
end
% Check for GPU device
try
gpu = gpuDevice();
canUse = gpu.DeviceSupported;
catch
canUse = false;
end
end

View File

@@ -1,25 +1,25 @@
function [rDZ] = getNLstepsize(ux,uy,gamma,dzmin,dzmax,dphimax,alpha_lin)
% gather() handles gpuArray inputs - ensures scalar is on CPU for comparisons
maxPow = gather(max(gamma.*max(real(ux).^2+imag(ux).^2+real(uy).^2+imag(uy).^2)));
Leff = dphimax/maxPow;
alpha_lin = max([alpha_lin.X alpha_lin.Y]);
nl_att_len_ratio = alpha_lin*Leff;
if nl_att_len_ratio >= 1
rDZ = dzmax;
else
if alpha_lin == 0
step = Leff;
maxPow = max(gamma.*max(real(ux).^2+imag(ux).^2+real(uy).^2+imag(uy).^2));
Leff = dphimax/maxPow;
alpha_lin = max([alpha_lin.X alpha_lin.Y]);
nl_att_len_ratio = alpha_lin*Leff;
if nl_att_len_ratio >= 1
rDZ = dzmax;
else
%effective length?
step = -1/alpha_lin*log(1-nl_att_len_ratio);
end
rDZ = min([step dzmax]);
rDZ = max([rDZ dzmin]);
end
if alpha_lin == 0
step = Leff;
else
%effective length?
step = -1/alpha_lin*log(1-nl_att_len_ratio);
end
rDZ = min([step dzmax]);
rDZ = max([rDZ dzmin]);
end
end

View File

@@ -22,37 +22,37 @@ n_plates_left = n_plates - n_plates_done;
% compute last plate size ( if it fits, it should be 0)
if missing_dz > aStepSize
last_plate = aStepSize;
missing_dz = missing_dz-aStepSize;
plate_sizes = last_plate;
plate_numbers = n_plates;
else
last_plate = aStepSize - missing_dz - (n_plates_left-1)*corr_length;
if missing_dz == 0
missing_dz = [];
end
%build vector of plate lengths with missing plate part from prev.
%iterartion , then some normal plates and finally a fraction of a plate
%to fit into the step length
plate_sizes = [missing_dz corr_length*ones(1,n_plates_left-1) last_plate];
if n_plates_done == 0
plate_numbers =[(n_plates_done+1):(n_plates-1) n_plates];
else
plate_numbers = [n_plates_done (n_plates_done+1):(n_plates-1) n_plates]; % not wrking yet
end
%remember for next step
%remember for next step
missing_dz = corr_length - last_plate;
end
plate_steps = repmat(n_step,1,length(plate_sizes)); %#ok<NASGU>
plate_steps = repmat(n_step,1,length(plate_sizes));
%
%figure;stem(plate_sizes);
@@ -66,39 +66,50 @@ test_plate_numbers = [test_plate_numbers, plate_numbers];
opt_x=fft(opt_x);
opt_y=fft(opt_y);
% Note: db1, db0, common_beta_x, common_beta_y are already on GPU when
% useGPU=true (transferred in CNLSE_plain)
db1 = brf.db1;
db0 = brf.db0;
% db1 = gpuArray(brf.db1);
% db0 = gpuArray(brf.db0);
% common_beta_x = gpuArray(common_beta_x);
% common_beta_y = gpuArray(common_beta_y);
db1 = (brf.db1);
db0 = (brf.db0);
common_beta_x = (common_beta_x);
common_beta_y = (common_beta_y);
% process every waveplate with given sizes in plate_sizes
for n=1:length(plate_sizes)
dz = plate_sizes(n);
% figure(87);subplot(2,1,1);plot(real(x(900:1150)));subplot(2,1,2);plot(real(y(900:1150)));
% MOV1=[MOV1 getframe(87)];
% extract rotation matrix from pre calculated matrices
matR = brf.matR{plate_numbers(n)};
% transform to eigenvalue of of fiber segment
tOpt.X = conj(matR(1,1))*opt_x + conj(matR(2,1))*opt_y;
tOpt.Y = conj(matR(1,2))*opt_x + conj(matR(2,2))*opt_y;
% calculate statistical delta beta for pmd
delta_beta = 0.5*(db1+db0(n))/corr_length;
% build transfer function with delta beta
%common.beta = beta1+beta2*omega^2
%accumulate delta beta for log...
brf.simdgd = brf.simdgd + (db1(length(db1)/2+1)+db0(n))/corr_length;
h.X = exp(-1j*(common_beta_x-delta_beta)*dz);
h.Y = exp(-1j*(common_beta_y+delta_beta)*dz);
% delta_beta has to be added to the transfer function
% process with transfer function
tOpt.X = h.X.*tOpt.X ;
tOpt.Y = h.Y.*tOpt.Y ;
% rotate back
opt_x = matR(1,1)*tOpt.X + matR(1,2)*tOpt.Y;
opt_y = matR(2,1)*tOpt.X + matR(2,2)*tOpt.Y;
end
lin_z_test = lin_z_test + sum(plate_sizes,2);
@@ -106,8 +117,9 @@ lin_z_test = lin_z_test + sum(plate_sizes,2);
%update the number of processed plates so far
n_plates_done = n_plates_done + n_plates_left;
% attenuate the signal each linear step with alpha
rOpt_x=ifft(exp(-alpha_lin_x*aStepSize/2).*opt_x);
rOpt_y=ifft(exp(-alpha_lin_y*aStepSize/2).*opt_y);
% attanuate the signal each linear state with alpha
% ( 0.2dB = 4.6052e-05 )
rOpt_x=ifft(exp(-alpha_lin_x*aStepSize/2).*opt_x); % /2 not sure why (have to find it in formulas)
rOpt_y=ifft(exp(-alpha_lin_y*aStepSize/2).*opt_y); % but not relevant for now
end
end