Theory stuff from sials work pc; minor stuff here and there
This commit is contained in:
@@ -23,12 +23,16 @@ D_lin = S0 .* (lambda_nm - lambda0_nm);
|
||||
|
||||
% plot
|
||||
figure('Color','w'); hold on;
|
||||
cols = cbrewer2('paired',4);
|
||||
plot(lambda_nm, D_lin(1,:), '-', 'LineWidth',2, 'DisplayName','Linearized model','Color',[cols(1,:)]);
|
||||
plot(lambda_nm, D_exact(1,:), 'LineWidth',2, 'DisplayName',sprintf('Exact model'),'Color',[cols(2,:)]);
|
||||
cols = [0.6510 0.8078 0.8902;...
|
||||
0.1216 0.4706 0.7059;...
|
||||
0.6980 0.8745 0.5412;...
|
||||
0.2000 0.6275 0.1725];
|
||||
|
||||
plot(lambda_nm, D_lin(2,:), '-', 'LineWidth',2, 'HandleVisibility','off','Color',[cols(3,:)]);
|
||||
plot(lambda_nm, D_exact(2,:), 'LineWidth',2, 'HandleVisibility','off','Color',[cols(4,:)]);
|
||||
% plot(lambda_nm, D_lin(1,:), '-', 'LineWidth',2, 'DisplayName','Linearized model','Color',[cols(1,:)]);
|
||||
plot(lambda_nm, D_exact(1,:), 'LineWidth',2, 'DisplayName',sprintf('S_0 = 0.07'),'Color',[cols(2,:)]);
|
||||
|
||||
% plot(lambda_nm, D_lin(2,:), '-', 'LineWidth',2, 'HandleVisibility','off','Color',[cols(3,:)]);
|
||||
plot(lambda_nm, D_exact(2,:), 'LineWidth',2, 'HandleVisibility','on', 'DisplayName',sprintf('S_0 = 0.09'),'Color',[cols(4,:)]);
|
||||
|
||||
|
||||
xlabel('Wavelength $\lambda$ [nm]','Interpreter','latex');
|
||||
@@ -36,4 +40,7 @@ ylabel('D($\lambda$) [ps/(nm km)]','Interpreter','latex');
|
||||
title('Chromatic Dispersion Around the ZDW');
|
||||
legend('Location','best');
|
||||
grid on; box on;
|
||||
xlim([min(lambda_nm) max(lambda_nm)])
|
||||
ylim([-5 5]);
|
||||
|
||||
% mat2tikz_improved('C:\Users\Silas\Documents\6971e0b65b380ca6d71c837f\02_IMDD_System\tikz\dispersion\dispersion')
|
||||
|
||||
124
Functions/Theory/Dissertation/photo_diode.m
Normal file
124
Functions/Theory/Dissertation/photo_diode.m
Normal file
@@ -0,0 +1,124 @@
|
||||
%% ============================================================
|
||||
% SNR vs Optical Input Power (dBm) — Shot vs Thermal vs Combined
|
||||
% - Generate optical field as sine with target RMS power (verified)
|
||||
% - Magnitude-square detection -> optical power
|
||||
% - Photocurrent = Rd * P
|
||||
% - Add shot noise + thermal noise (white, PSD-based)
|
||||
% - Compute SNR for: shot-only, thermal-only, combined
|
||||
% ============================================================
|
||||
|
||||
|
||||
% Constants
|
||||
k = Constant.Boltzmann;
|
||||
q = Constant.ElementaryCharge;
|
||||
|
||||
% Receiver / PD parameters
|
||||
T = 20 + 273.15; % K
|
||||
R = 50; % Ohm (front-end/load)
|
||||
Rd = 0.7; % A/W (responsivity)
|
||||
Be = 100e9; % Hz (electrical noise bandwidth)
|
||||
Id = 0; % A (dark current, optional)
|
||||
|
||||
% Sampling for time-domain demo (needs to be >> Be)
|
||||
fs = 1e12; % Hz
|
||||
N = 2^14; % samples
|
||||
t = (0:N-1).'/fs;
|
||||
|
||||
% Choose an electrical tone within bandwidth (arbitrary for demo)
|
||||
f0 = 10e9; % Hz
|
||||
|
||||
% Thermal current PSD (two-sided) and variance in Be
|
||||
Si_th = 4*k*T/R; % A^2/Hz (two-sided)
|
||||
sigma2_th = Si_th * Be; % A^2
|
||||
sigma_th = sqrt(sigma2_th); % A_rms
|
||||
|
||||
% Optical input power sweep (in dBm)
|
||||
P_dBm = linspace(-40, 10, 300);
|
||||
P_W = 10.^((P_dBm - 30)/10); % W
|
||||
|
||||
% Pre-allocate results
|
||||
SNR_shot_dB = zeros(size(P_dBm));
|
||||
SNR_th_dB = zeros(size(P_dBm));
|
||||
SNR_tot_dB = zeros(size(P_dBm));
|
||||
|
||||
% --- Main loop over optical input power
|
||||
for ii = 1:numel(P_W)
|
||||
Pavg = P_W(ii);
|
||||
|
||||
% Optical field with RMS power = Pavg:
|
||||
% Let x(t) be the optical field amplitude such that |x|^2 has mean Pavg.
|
||||
% Use a sinusoid: x(t) = A*sin(2*pi*f0*t), then mean(|x|^2)=A^2/2.
|
||||
A = sqrt(2*Pavg); % -> mean(|x|^2) = Pavg
|
||||
|
||||
x = A * sin(2*pi*f0*t); % "optical field" (real for simplicity)
|
||||
|
||||
% Verify RMS/mean power numerically (optional)
|
||||
P_meas = mean(abs(x).^2); % should be ~ Pavg
|
||||
|
||||
a = P_meas - Pavg;
|
||||
assert(a<1);
|
||||
|
||||
% Magnitude-square detection -> optical power waveform
|
||||
Popt = abs(x).^2; % W (instantaneous)
|
||||
|
||||
% Photocurrent waveform (includes DC + 2f0 component for this demo)
|
||||
I_sig = Rd * Popt; % A
|
||||
|
||||
% Define "signal power" as the mean-squared photocurrent due to signal
|
||||
% (for this sine-squared waveform, it's OK for a demo SNR definition)
|
||||
P_sig = mean(I_sig.^2);
|
||||
|
||||
% -------- Shot noise (white) --------
|
||||
% Two-sided PSD: Si_shot = 2*q*(I_photo + I_dark)
|
||||
% For this demo, use average current to set the white-noise level:
|
||||
Ibar = mean(I_sig) + Id;
|
||||
Si_shot = 2*q*Ibar; % A^2/Hz
|
||||
sigma2_sh = Si_shot * Be; % A^2
|
||||
sigma_sh = sqrt(sigma2_sh); % A_rms
|
||||
|
||||
n_sh = sigma_sh * randn(N,1); % time-domain shot noise
|
||||
|
||||
% -------- Thermal noise (white Gaussian) --------
|
||||
n_th = sigma_th * randn(N,1); % time-domain thermal noise
|
||||
|
||||
% Noise powers (mean-square) in time domain
|
||||
Pn_sh = mean(n_sh.^2);
|
||||
Pn_th = mean(n_th.^2);
|
||||
Pn_tot = mean((n_sh + n_th).^2); % ~ Pn_sh + Pn_th (independent)
|
||||
|
||||
% SNRs
|
||||
SNR_shot = P_sig / Pn_sh;
|
||||
SNR_th = P_sig / Pn_th;
|
||||
SNR_tot = P_sig / Pn_tot;
|
||||
|
||||
SNR_shot_dB(ii) = 10*log10(SNR_shot);
|
||||
SNR_th_dB(ii) = 10*log10(SNR_th);
|
||||
SNR_tot_dB(ii) = 10*log10(SNR_tot);
|
||||
|
||||
% Optional sanity check (can comment out)
|
||||
% if ii == 1
|
||||
% fprintf('Check Pavg target/meas: %.3g W / %.3g W\n', Pavg, P_meas);
|
||||
% end
|
||||
end
|
||||
|
||||
% Plot comparison
|
||||
figure(1); clf; hold on;
|
||||
plot(P_dBm, SNR_shot_dB, 'LineWidth', 1.5);
|
||||
plot(P_dBm, SNR_th_dB, 'LineWidth', 1.5);
|
||||
plot(P_dBm, SNR_tot_dB, 'LineWidth', 1.5);
|
||||
grid on;
|
||||
xlabel('Optical input power [dBm]');
|
||||
ylabel('SNR [dB]');
|
||||
title('SNR vs Optical Input Power: Shot vs Thermal vs Combined');
|
||||
legend('Shot-noise only','Thermal-noise only','Shot + Thermal','Location','best');
|
||||
|
||||
% Print example at 0 dBm
|
||||
[~,idx0] = min(abs(P_dBm - 0));
|
||||
fprintf('At 0 dBm:\n');
|
||||
fprintf(' SNR (shot only) = %.2f dB\n', SNR_shot_dB(idx0));
|
||||
fprintf(' SNR (thermal only) = %.2f dB\n', SNR_th_dB(idx0));
|
||||
fprintf(' SNR (combined) = %.2f dB\n', SNR_tot_dB(idx0));
|
||||
|
||||
% Also print NEP based on thermal PSD (constant NEP_th)
|
||||
NEP_th = sqrt(Si_th)/Rd; % W/sqrt(Hz)
|
||||
fprintf('Thermal NEP = %.3g W/sqrt(Hz)\n', NEP_th);
|
||||
68
Functions/Theory/Dissertation/power_fading_gif.m
Normal file
68
Functions/Theory/Dissertation/power_fading_gif.m
Normal file
@@ -0,0 +1,68 @@
|
||||
%% ============================================================
|
||||
% IM/DD Power Fading Evolution GIF (1 km -> 20 km)
|
||||
% Uses the provided GifWriter (serial mode)
|
||||
% ============================================================
|
||||
|
||||
clear; close all; clc;
|
||||
|
||||
%% Fiber and system parameters
|
||||
lambda0 = 1310e-9; % zero-dispersion wavelength [m]
|
||||
lambda = 1275e-9; % operating wavelength [m]
|
||||
S0 = 0.09; % dispersion slope [ps/(nm^2·km)]
|
||||
c = physconst('lightspeed');
|
||||
|
||||
%% Derived quantities (length-independent)
|
||||
D_lambda = (S0/4) * (lambda*1e9 - (lambda0*1e9)^4/(lambda*1e9)^3); % ps/(nm·km)
|
||||
D_si = D_lambda * 1e-6; % s/m^2
|
||||
b2 = -D_si * lambda^2 / (2*pi*c); % s^2/m
|
||||
|
||||
%% Frequency grid
|
||||
f_max = 150e9;
|
||||
f = linspace(0, f_max, 4000); % [Hz]
|
||||
|
||||
%% Figure setup (keep it stable for nicer GIFs)
|
||||
fig = figure('Color','w');
|
||||
ax = axes(fig); %#ok<LAXES>
|
||||
hold(ax,'on'); grid(ax,'on'); box(ax,'on');
|
||||
xlabel(ax,'Frequency [GHz]');
|
||||
ylabel(ax,'Magnitude [dB]');
|
||||
ylim(ax,[-30 0]);
|
||||
xlim(ax,[0 f_max/1e9]);
|
||||
|
||||
%% GIF writer (serial mode; simplest)
|
||||
g = GifWriter('Name','power_fading_evolution', 'DelayTime',0.12, 'Parallel',false);
|
||||
|
||||
%% Loop: 1 km to 20 km
|
||||
L = [1:20,19:-1:1];
|
||||
for L_km = L
|
||||
L_meter = L_km * 1e3; % [m]
|
||||
|
||||
% IM/DD transfer function (power fading)
|
||||
phi = 2*pi^2 * b2 * f.^2 * L_meter;
|
||||
H = abs(cos(phi));
|
||||
HdB = 10*log10(max(H, 1e-12)); % avoid -Inf for deep notches
|
||||
|
||||
% Clear and redraw (stable axes)
|
||||
cla(ax);
|
||||
|
||||
plot(ax, f/1e9, HdB, 'LineWidth', 1.8, 'Color','black');
|
||||
|
||||
% Analytic first-null frequency marker
|
||||
f_null = sqrt(c*(0.5)/(abs(D_si)*lambda^2*L_meter));
|
||||
xline(ax, f_null/1e9, 'r--', 'LineWidth', 1.2, ...
|
||||
'Label', sprintf('f_{null}=%.1f GHz', f_null/1e9), ...
|
||||
'LabelOrientation','horizontal', ...
|
||||
'LabelVerticalAlignment','bottom');
|
||||
|
||||
title(ax, sprintf('Power Fading for: %.0f km @ 1275 nm', L_km));
|
||||
|
||||
drawnow;
|
||||
|
||||
% Add frame to GIF
|
||||
g.addFrame(fig);
|
||||
end
|
||||
|
||||
%% Done
|
||||
g.compile(fig.Number);
|
||||
|
||||
disp(fullfile(g.OutputDir, sprintf('%s_fig_%d.gif', g.Name, fig.Number)));
|
||||
@@ -0,0 +1,69 @@
|
||||
%% ============================================================
|
||||
% IM/DD Power Fading Evolution vs Wavelength (L = 10 km)
|
||||
% ============================================================
|
||||
|
||||
clear; close all; clc;
|
||||
|
||||
%% Fixed fiber parameters
|
||||
lambda0 = 1310e-9; % zero-dispersion wavelength [m]
|
||||
S0 = 0.09; % dispersion slope [ps/(nm^2·km)]
|
||||
L = 10e3; % fiber length FIXED [m]
|
||||
c = physconst('lightspeed');
|
||||
|
||||
%% Frequency grid
|
||||
f_max = 150e9;
|
||||
f = linspace(0, f_max, 4000); % [Hz]
|
||||
|
||||
%% Figure setup (stable axes for clean GIF)
|
||||
fig = figure('Color','w');
|
||||
ax = axes(fig);
|
||||
hold(ax,'on'); grid(ax,'on'); box(ax,'on');
|
||||
xlabel(ax,'Frequency [GHz]');
|
||||
ylabel(ax,'Magnitude [dB]');
|
||||
ylim(ax,[-30 0]);
|
||||
xlim(ax,[0 f_max/1e9]);
|
||||
|
||||
%% GIF writer
|
||||
g = GifWriter('Name','power_fading_vs_wavelength', ...
|
||||
'DelayTime',0.12, ...
|
||||
'Parallel',false);
|
||||
|
||||
%% Wavelength sweep (around ZDW)
|
||||
lambda_vec = linspace(1260e-9, 1360e-9, 25); % 1260–1360 nm
|
||||
|
||||
for k = 1:length(lambda_vec)
|
||||
|
||||
lambda = lambda_vec(k);
|
||||
|
||||
%% Dispersion for current wavelength
|
||||
D_lambda = (S0/4) * (lambda*1e9 - (lambda0*1e9)^4/(lambda*1e9)^3); % ps/(nm·km)
|
||||
D_si = D_lambda * 1e-6; % s/m^2
|
||||
b2 = -D_si * lambda^2 / (2*pi*c); % s^2/m
|
||||
|
||||
%% Power fading transfer function
|
||||
phi = 2*pi^2 * b2 * f.^2 * L;
|
||||
H = abs(cos(phi));
|
||||
HdB = 10*log10(max(H, 1e-12));
|
||||
|
||||
cla(ax)
|
||||
plot(ax, f/1e9, HdB, 'LineWidth',1.8,'Color','black');
|
||||
|
||||
%% First-null frequency
|
||||
if abs(D_si) > 0
|
||||
f_null = sqrt(c*(0.5)/(abs(D_si)*lambda^2*L));
|
||||
xline(ax, f_null/1e9, 'r--', 'LineWidth',1.2, ...
|
||||
'Label', sprintf('f_{null}=%.1f GHz', f_null/1e9), ...
|
||||
'LabelOrientation','horizontal', ...
|
||||
'LabelVerticalAlignment','bottom');
|
||||
end
|
||||
|
||||
title(ax, sprintf('Power Fading for: 10 km @ %.0f nm', lambda*1e9));
|
||||
|
||||
drawnow;
|
||||
g.addFrame(fig);
|
||||
end
|
||||
|
||||
%% Compile GIF
|
||||
g.compile(fig.Number);
|
||||
|
||||
disp(fullfile(g.OutputDir, sprintf('%s_fig_%d.gif', g.Name, fig.Number)));
|
||||
@@ -8,17 +8,16 @@ c = physconst('lightspeed');
|
||||
S0_si = S0 * 1e3; % s/m³
|
||||
|
||||
Delta_lambda = linspace(5e-9, 80e-9, 300); % [m] detuning
|
||||
f_null_2 = sqrt( c * 0.5 ./ (S0_si .* abs(Delta_lambda) .* lambda0.^2 .* L) );
|
||||
L = 2e3; % m
|
||||
f_null_10 = sqrt( c * 0.5 ./ (S0_si .* abs(Delta_lambda) .* lambda0.^2 .* L) );
|
||||
|
||||
cols = cbrewer2('Paired',10);
|
||||
cols = [0.3467 0.5360 0.6907;...
|
||||
0.9153 0.2816 0.2878;...
|
||||
0.4416 0.7490 0.4322];
|
||||
figure('Color','w');hold on
|
||||
cnt = 2;
|
||||
for L = 10%[2,5,10]
|
||||
cnt = 1;
|
||||
for L = [2,10,40]
|
||||
f_null_10 = sqrt( c * 0.5 ./ (S0_si .* abs(Delta_lambda) .* lambda0.^2 .* L*1e3) );
|
||||
plot(1310-Delta_lambda*1e9, f_null_10/1e9, 'LineWidth',2,'DisplayName',sprintf('%d km',L),'Color',cols(cnt,:));
|
||||
cnt = cnt+2;
|
||||
cnt = cnt+1;
|
||||
end
|
||||
% yticks([56,75,90,112])
|
||||
% tickse = 1310-[7.5, 12, 17, 31.5];
|
||||
@@ -29,4 +28,5 @@ ylabel('$F_{null}$ [GHz]');
|
||||
grid on; box on;
|
||||
lim=1310-[5,60];
|
||||
xlim([lim(2) lim(1)]);
|
||||
ylim([40,130])
|
||||
ylim([10,130])
|
||||
legend
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
%% Fiber and system parameters
|
||||
lambda0 = 1310e-9; % zero-dispersion wavelength [m]
|
||||
lambda = 1275e-9; % operating wavelength [m]
|
||||
lambda = 1290e-9; % operating wavelength [m]
|
||||
S0 = 0.09; % dispersion slope [ps/(nm²·km)]
|
||||
L = 10e3; % fiber length [m]
|
||||
c = physconst('lightspeed');
|
||||
@@ -30,7 +30,7 @@ plot(f/1e9, 10*log10(H), 'LineWidth', 1.8,'Color','black');
|
||||
grid on; box on;
|
||||
xlabel('Frequency [GHz]');
|
||||
ylabel('Magnitude [dB]');
|
||||
title(sprintf('IM/DD Power Fading: 10 km; 1275nm', lambda*1e9, L/1000),"Interpreter","latex");
|
||||
% title(sprintf('IM/DD Power Fading: 10 km; 1275nm', lambda*1e9, L/1000),"Interpreter","latex");
|
||||
ylim([-30 0]);
|
||||
|
||||
%% Mark analytic first-null frequency
|
||||
@@ -38,3 +38,5 @@ f_null = sqrt(c*(0.5)/(abs(D_si)*lambda^2*L));
|
||||
xline(f_null/1e9, 'r--', 'LineWidth', 1.2, ...
|
||||
'Label', sprintf('f_{null}=%.1f GHz', f_null/1e9), ...
|
||||
'LabelOrientation', 'horizontal', 'LabelVerticalAlignment', 'bottom');
|
||||
|
||||
mat2tikz_improved('C:\Users\Silas\Documents\6971e0b65b380ca6d71c837f\02_IMDD_System\tikz\dispersion\power_fading.tikz')
|
||||
Reference in New Issue
Block a user