Files
imdd_silas/Theory/Optical/calcFWM/validate_fwm.m
2026-03-25 10:57:48 +01:00

125 lines
3.8 KiB
Matlab

%% Validate the analytical FWM product count against a brute-force reference
% The paper counts channel combinations, not only unique output frequencies:
% non-degenerate: i < j, k ~= i, k ~= j, n = i + j - k
% degenerate: i == j, k ~= i, n = 2*i - k
clear;
clc;
N_values = [4, 8, 16];
plot_N = 8;
fprintf('Validating analytical FWM product count from Goebel and Hanik (2008)\n');
for idxN = 1:numel(N_values)
N = N_values(idxN);
fprintf('\nN = %d\n', N);
[Mndg_ana, Mdg_ana] = getProducts(N);
[Mndg_brute, Mdg_brute, n_values] = getProductsBruteForce(N);
diff_ndg = Mndg_ana - Mndg_brute;
diff_dg = Mdg_ana - Mdg_brute;
fprintf(' Analytical total : %d\n', sum(Mndg_ana) + sum(Mdg_ana));
fprintf(' Brute-force total : %d\n', sum(Mndg_brute) + sum(Mdg_brute));
if all(diff_ndg == 0) && all(diff_dg == 0)
fprintf(' Match : yes\n');
else
fprintf(' Match : no\n');
fprintf(' Non-degenerate diff: %s\n', mat2str(diff_ndg));
fprintf(' Degenerate diff : %s\n', mat2str(diff_dg));
end
if N == plot_N
plotComparison(n_values, Mndg_ana, Mdg_ana, Mndg_brute, Mdg_brute, N);
end
end
function [Mndg, Mdg, n_values] = getProductsBruteForce(N)
n_values = (2 - N):(2*N - 1);
Mndg = zeros(size(n_values));
Mdg = zeros(size(n_values));
for idx = 1:numel(n_values)
n = n_values(idx);
% Degenerate products: two identical pumps and one different channel.
for i = 1:N
k = 2*i - n;
if isValidChannel(k, N) && (k ~= i)
Mdg(idx) = Mdg(idx) + 1;
end
end
% Non-degenerate products: unordered pump pair plus one third channel.
for i = 1:N
for j = (i + 1):N
k = i + j - n;
if isValidChannel(k, N) && (k ~= i) && (k ~= j)
Mndg(idx) = Mndg(idx) + 1;
end
end
end
end
end
function tf = isValidChannel(channel_idx, N)
tf = (channel_idx >= 1) && (channel_idx <= N) && (channel_idx == round(channel_idx));
end
function plotComparison(n_values, Mndg_ana, Mdg_ana, Mndg_brute, Mdg_brute, N)
figure;
subplot(1,2,1);
stem(n_values, Mndg_ana + Mdg_ana, 'filled', 'LineWidth', 1, 'Marker', 'o', 'MarkerSize', 2);
hold on;
stem(n_values, Mdg_ana, 'filled', 'LineWidth', 1, 'Marker', 'none');
title(['Analytical (N=', num2str(N), ')']);
xlabel('Product index n');
ylabel('Number of FWM products');
legend('Total', 'Degenerate');
grid on;
subplot(1,2,2);
stem(n_values, Mndg_brute + Mdg_brute, 'filled', 'LineWidth', 1, 'Marker', 'o', 'MarkerSize', 2);
hold on;
stem(n_values, Mdg_brute, 'filled', 'LineWidth', 1, 'Marker', 'none');
title(['Brute force (N=', num2str(N), ')']);
xlabel('Product index n');
ylabel('Number of FWM products');
legend('Total', 'Degenerate');
grid on;
end
function [Mndg, Mdg] = getProducts(N)
s = abs(2 - N - 1);
for n = 2 - N:2*N - 1
if n < -N
Mdg(n + s) = 0;
elseif (-N <= n) && (n <= 0)
Mdg(n + s) = N - ceil((N - n)/2);
elseif (1 <= n) && (n <= N)
Mdg(n + s) = N - 1 - floor(n/2) - ceil((N - n)/2);
elseif (N < n) && (n <= 2*N)
Mdg(n + s) = N - floor(n/2);
elseif n > 2*N
Mdg(n + s) = 0;
end
if n < -N
Mndg(n + s) = 0;
elseif (-N <= n) && (n < 1)
Mndg(n + s) = ceil((N^2 + n^2 - 2*N - 2*n + 2*N*n)/4);
elseif (1 <= n) && (n <= N)
Mndg(n + s) = ceil(((N^2 - 6*N - 2*n^2 + 2*n + 4)/4) + floor((N*n)/2));
elseif (N < n) && (n <= 2*N)
Mndg(n + s) = floor(N^2 + n^2/4 - N*n);
elseif n > 2*N
Mndg(n + s) = 0;
end
end
end