% Parameters c0 = physconst('lightspeed'); % [m/s] lambda0 = 1310e-9; % [m] omega0 = 2*pi*c0/lambda0; L = 5e-3; % [m] effective phase section length (set as needed) n_eff = 2.2; % [-] effective index (set as needed) E0 = 1; % field amplitude (arbitrary) Vpi = 3.2; % [V] half-wave voltage (your V_pi) % Drive f0 = 1e9; % [Hz] fs = 200e9; % [Hz] Nper = 2; % number of periods Vpp = 0.6*Vpi; % [V] peak-to-peak of v_drive(t) biasV = 1.1; % [V] differential bias added to v_drive % Time axis + differential drive voltage v_drive(t) T = Nper/f0; t = (0:1/fs:T-1/fs).'; if 1 % SINE v_drive = biasV + (Vpp/2)*sin(2*pi*f0*t); % v_drive(t) (peak = Vpp/2) else % --- Generate PAM-4 Sequence --- symbols = linspace(-0.5, 0.5, 4); num_symbols = 12; % Increased slightly for better visual rng(44); random_data = symbols(randi(4, 1, num_symbols)); % Create time axis (Note: T is your period from the sine code) sps = round(T * fs); t = (0:1/fs:(num_symbols*T)-1/fs).'; % Upsample to rectangular waveform v_pam = repelem(random_data, sps).'; % Apply swing and bias: Resulting range is [biasV-Vpp/2, biasV+Vpp/2] v_drive_rect = biasV + (v_pam * Vpp); % --- Round the edges --- filter_span = round(sps/1.5); % Increased span for smoother "rounding" window = gausswin(filter_span); window = window / sum(window); % Apply filter (using 'same' to keep vector length, but be aware of edge transients) v_drive = conv(v_drive_rect, window, 'same'); end % Analytic v_ = linspace(-1,2, 2001); % Field transfer function (amplitude) Field_mzm_analytic = cos((pi/2)*v_); % Power transfer function (intensity) P_mzm_analytic = Field_mzm_analytic.^2; % Imbalance factor in YOUR notation: rho = 1; % Push-pull branch voltages (consistent with v_drive = v1 - v2) v1 = +0.5*v_drive; % arm 1 v2 = -0.5*v_drive; % arm 2 % Phases phi1, phi2 phi1 = pi * v1 / Vpi; phi2 = pi * v2 / Vpi; % Fields: E_in and E_out (exactly your Eq. (mzm_e_field)) E_in = E0 .* exp(1i*omega0*t); common_phase = exp(-1i * (omega0*L*n_eff/c0)); % exp(-j*omega0*L*n_eff/c0) E_out = E0 .* exp(1i*omega0*t) .* common_phase .* 0.5 .* ... ( exp(-1i*phi1) + rho .* exp(-1i*phi2) ); % Transfer function (numerical): E_out/E_in H_num = E_out ./ E_in; % Power (normalized) Pnorm_num = abs(H_num).^2; % since |E_out/E_in|^2 % Ideal TF (analytic) for comparison (rho=1, push-pull) H_ideal = common_phase .* cos( (pi/2) * (v_drive./Vpi) ); Pnorm_ideal = abs(H_ideal).^2; Pnorm_math = cos( (pi/2) * (v_drive./Vpi) ).^2; set(groot, 'defaultLegendInterpreter', 'tex'); set(groot, 'defaultAxesTickLabelInterpreter', 'tex'); set(groot, 'defaultTextInterpreter', 'tex'); % Normalized voltage axis (multiples of Vpi) v_norm = v_drive./Vpi; colfield = [0,0,0]; %is black colpow = linspecer(2); colpow = colpow(1,:); colvdrive = linspecer(2); colvdrive = colvdrive(2,:); %% SIGNAL IN figure(1); clf plot(v_norm,t*1e9, 'LineWidth', 1.0,'Color',colvdrive); grid on; ylabel('t [ns]'); xlabel('v_{drive}(t)/V_\pi'); title('Drive voltage (normalized)'); xlim([min(v_) max(v_)]); % mat2tikz_improved('C:\Users\Silas\Documents\6971e0b65b380ca6d71c837f\02_IMDD_System\tikz\linear_casee\mzm_input_signal.tex'); %% IN/OUT (static transfer) — normalized x-axis + analytic curve if 0 figure(2); clf plot(v_, Field_mzm_analytic, 'LineWidth', 1.2,'LineStyle','--','Color',colfield); hold on;% analytic power TF plot(v_, P_mzm_analytic, 'LineWidth', 1.2, 'Color',colpow); hold on;% analytic power TF % show input time signal plot(v_norm,-1+t*1e9, 'LineWidth', 1.0,'Color',colvdrive); grid on; % show output time signal plot(2+t*1e9, Pnorm_num, 'LineWidth', 1.0,'DisplayName','Intensity', 'Color',colvdrive); hold on; plot(2+t*1e9, real(H_ideal), '--', 'LineWidth', 1.0,'DisplayName','Field','Color',colfield); hold on; scatter(v_norm, Pnorm_num, 12, '.', 'LineWidth', 1,'MarkerEdgeColor',colvdrive); scatter(biasV./Vpi,(cos((pi/2)*biasV./Vpi)^2),10,'Marker','o'); line([min(v_drive), min(v_drive)]./Vpi,[(cos((pi/2)*min(v_drive)./Vpi)^2), -2],'linewidth',0.5,'color','black','linestyle','--'); line([max(v_drive) max(v_drive)]./Vpi,[(cos((pi/2)*max(v_drive)./Vpi)^2), -2],'linewidth',0.5,'color','black','linestyle','--'); xline([min(v_norm) max(v_norm)]) grid on; xlabel('v_{drive}(t)/V_\pi'); ylabel('|E_{out}/E_{in}|^2'); % legend xlim([min(v_) max(v_)+1]); ylim([-1 1]); % mat2tikz_improved('C:\Users\Silas\Documents\6971e0b65b380ca6d71c837f\02_IMDD_System\tikz\mzm.tex'); end %% figure(3); clf plot(v_, Field_mzm_analytic, 'LineWidth', 1.2,'LineStyle','--','Color',colfield); hold on;% analytic power TF plot(v_, P_mzm_analytic, 'LineWidth', 1.2, 'Color',colpow); hold on;% analytic power TF scatter(v_norm, Pnorm_num, 12, '.', 'LineWidth', 1,'MarkerEdgeColor',colvdrive); scatter(biasV./Vpi,(cos((pi/2)*biasV./Vpi)^2),10,'Marker','o'); line([min(v_drive), min(v_drive)]./Vpi,[(cos((pi/2)*min(v_drive)./Vpi)^2), -2],'linewidth',0.5,'color','black','linestyle','--'); line([max(v_drive) max(v_drive)]./Vpi,[(cos((pi/2)*max(v_drive)./Vpi)^2), -2],'linewidth',0.5,'color','black','linestyle','--'); xline([min(v_norm) max(v_norm)]) grid on; xlabel('v_{drive}(t)/V_\pi'); ylabel('|E_{out}/E_{in}|^2'); % legend xlim([min(v_) max(v_)]); ylim([-1 1]); % mat2tikz_improved('C:\Users\Silas\Documents\6971e0b65b380ca6d71c837f\02_IMDD_System\tikz\mzm_tramsfer_function_matlab.tex'); %% figure(4); clf % plot(v_, Field_mzm_analytic, 'LineWidth', 1.2,'LineStyle','--','Color',colfield); hold on;% analytic power TF plot(v_, P_mzm_analytic, 'LineWidth', 1.2, 'Color','black'); hold on;% analytic power TF input_dots = linspace(min(v_drive),max(v_drive),4)./Vpi; % input_dots = unique(v_drive_rect)./Vpi; output_dots = (cos((pi/2)*input_dots).^2); scatter(input_dots,output_dots,'Marker','x','LineWidth',1,'MarkerEdgeColor','black'); scatter(input_dots,zeros(size(input_dots)),'Marker','^','LineWidth',2,'MarkerEdgeColor','black'); % scatter(ones(size(input_dots)),output_dots,'Marker','<','LineWidth',2,'MarkerEdgeColor','black'); for i = 1:numel(input_dots) % Draw the dashed projection lines line([input_dots(i), input_dots(i)], [output_dots(i), 0], 'linewidth', 0.5, 'color', 'black', 'linestyle', '--', 'handlevisibility', 'off'); line([input_dots(i), 1], [output_dots(i), output_dots(i)], 'linewidth', 0.5, 'color', 'black', 'linestyle', '--', 'handlevisibility', 'off'); % Add the level annotation boxes near the output (y-axis) % Adjust the '1.05' to move the box further right or 'output_dots(i)' for height j = 3-(i-1)*2; text(1, output_dots(i), sprintf('Level %d', j), ... 'FontSize', 8, ... 'EdgeColor', 'black', ... 'BackgroundColor', 'white', ... 'Margin', 2); end xlim([0,1.5]); ylim([0,1]) % line([min(v_drive), min(v_drive)]./Vpi,[(cos((pi/2)*min(v_drive)./Vpi)^2), 0],'linewidth',0.5,'color','black','linestyle','--'); % line([max(v_drive), max(v_drive)]./Vpi,[(cos((pi/2)*max(v_drive)./Vpi)^2), 0],'linewidth',0.5,'color','black','linestyle','--'); % mat2tikz_improved('C:\Users\Silas\Documents\6971e0b65b380ca6d71c837f\02_IMDD_System\tikz\linear_casee\mzm_tf.tex'); % xticks(sort(input_dots)); % yticks(sort(output_dots)); grid off %% % % FIELD TF (only field here; do not mix power into this figure) figure(5); clf % plot(t*1e9, real(H_num), 'LineWidth', 1.0); hold on; % plot(t*1e9, real(H_ideal), '--', 'LineWidth', 1.0,'DisplayName','Field','Color',colfield); hold on; plot(t*1e9, Pnorm_num, 'LineWidth', 1.0,'DisplayName','Intensity', 'Color',colpow); hold on; grid on; xlabel('t [ns]'); ylabel('Re\{E_{out}/E_{in}\}'); legend yticks(sort(output_dots)); % mat2tikz_improved('C:\Users\Silas\Documents\6971e0b65b380ca6d71c837f\02_IMDD_System\tikz\linear_casee\mzm_output_signal.tex');