Add some older Theory projects from the past years
This commit is contained in:
69
Functions/Theory/calcFWM/FWM_products.m
Normal file
69
Functions/Theory/calcFWM/FWM_products.m
Normal file
@@ -0,0 +1,69 @@
|
||||
|
||||
|
||||
|
||||
w0 = [1290:2:1290+15*2]';
|
||||
w0 = [1290:2:1290+15*2]';
|
||||
w0 = [ 1302 1304 1306 1308]';
|
||||
%w0 = [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]';
|
||||
m = 0.5*(numel(w0)^3 - numel(w0)^2);
|
||||
a = [1,1,1]';
|
||||
|
||||
w = w0;
|
||||
|
||||
|
||||
|
||||
|
||||
for o = 2:3
|
||||
|
||||
p = nchoosek(w,3);
|
||||
|
||||
q = [];
|
||||
parfor i = 1:size(p,1)
|
||||
|
||||
q_ = perms(p(i,:));
|
||||
q = [q;q_];
|
||||
|
||||
end
|
||||
p = q;
|
||||
%p = unique(q,"rows");
|
||||
w_ = p(:,1) + p(:,2) - p(:,3);
|
||||
a_ = ones(size(w_)).* 1/o;
|
||||
|
||||
w = [w ; w_];
|
||||
a = [a ; a_];
|
||||
% w = unique(w);
|
||||
% a = unique(a);
|
||||
|
||||
m(end+1) = 0.5*(numel(w)^3 - numel(w)^2);
|
||||
|
||||
end
|
||||
|
||||
figure(11)
|
||||
hold on
|
||||
|
||||
lambda = min(w):max(w);
|
||||
|
||||
gen = sum(lambda == w,1);
|
||||
gen(gen==0) = NaN;
|
||||
stem(lambda,gen,"filled",'LineWidth',1,'Marker','o','MarkerSize',2,'LineStyle',':')
|
||||
|
||||
initial = sum(lambda == w0,1);
|
||||
initial(initial==0) = NaN;
|
||||
stem(lambda,initial,"filled",'LineWidth',1.5,'MarkerSize',5,'Marker','^');
|
||||
|
||||
xlabel('Wavelength');
|
||||
ylabel('number of FWM products');
|
||||
|
||||
grid minor
|
||||
legend('Generated Products', 'Initial Channel Position')
|
||||
AxesMain = gca;
|
||||
fig = gcf;
|
||||
fontsize(AxesMain,8,"points")
|
||||
|
||||
fig.Units = "centimeters";
|
||||
fig.Position = [2 2 8.5 7];
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
43
Functions/Theory/calcFWM/JLT_statistics_laser_and_zdw.m
Normal file
43
Functions/Theory/calcFWM/JLT_statistics_laser_and_zdw.m
Normal file
@@ -0,0 +1,43 @@
|
||||
%% Laser Offset Statistics
|
||||
|
||||
figure
|
||||
for i = 1
|
||||
res = 1.7e6;
|
||||
n_chann = 16;
|
||||
df_T_exact = (-n_chann/2+0.5:n_chann/2).* 200e9;
|
||||
|
||||
for key = 1:100
|
||||
laser_frequency_imperfection(key,:) = res .* round(randn(1,n_chann)*i*100);
|
||||
df_T(key,:) = df_T_exact + laser_frequency_imperfection(key,:);
|
||||
end
|
||||
|
||||
hold on
|
||||
histogram(laser_frequency_imperfection.*1e-6,100,"Normalization","probability","EdgeColor","none","FaceAlpha",0.3,'DisplayName',['Std. Dev.: ',num2str(mean(std(laser_frequency_imperfection))*1e-6),' MHz']);
|
||||
xlabel('Laser Frequency Offset in MHz');
|
||||
ylabel('Probability');
|
||||
title(['Laser deviations from exact grid.'])
|
||||
|
||||
end
|
||||
|
||||
%% ZDW Statistics
|
||||
|
||||
for k = 1:1000
|
||||
|
||||
% Set parameters
|
||||
meanUniformMin = 1309;
|
||||
meanUniformMax = 1315;
|
||||
meanValue = 1310;
|
||||
sigma = 2;
|
||||
|
||||
% Seed the random number generator (assuming Mersenne Twister)
|
||||
rng(k);
|
||||
|
||||
% Generate normally distributed random numbers
|
||||
randomNumbers(k,:) = normrnd(meanValue, sigma, [n_chann, 1]).';
|
||||
|
||||
end
|
||||
|
||||
figure;
|
||||
histogram(randomNumbers,100,"Normalization","probability","EdgeColor","none");
|
||||
xlabel('ZDW in nm');
|
||||
ylabel('Probability');
|
||||
65
Functions/Theory/calcFWM/analytical_calculation_paper.m
Normal file
65
Functions/Theory/calcFWM/analytical_calculation_paper.m
Normal file
@@ -0,0 +1,65 @@
|
||||
%%FWM analysis from "Analytical Calculation of the Number of
|
||||
%%Four-Wave-Mixing Products in Optical Multichannel Communication Systems"
|
||||
|
||||
N_ = [4,8,16];
|
||||
|
||||
df_hz = 400e9;
|
||||
center_nm = 1310;
|
||||
|
||||
figure()
|
||||
for i = 1:length(N_)
|
||||
|
||||
vec = (2*N_(i)-1:-1:2-N_(i)) -(N_(i)/2+0.5);
|
||||
channelplan_hz = nm2hz(center_nm) + (vec * df_hz) ;
|
||||
channelplan_nm = hz2nm(channelplan_hz);
|
||||
|
||||
[Mndg,Mdg] = getProducts(N_(i));
|
||||
total(i) = sum(Mndg) + sum(Mdg);
|
||||
subplot(1,length(N_),i)
|
||||
xline(calcWavelengthPlan(N_(i), df_hz, center_nm));
|
||||
hold on
|
||||
stem(channelplan_nm,(Mndg+Mdg),'filled','LineWidth',1,'Marker','o','MarkerSize',2)
|
||||
stem(channelplan_nm,(Mdg),'filled','LineWidth',1,'Marker','none');
|
||||
ylim([0,100])
|
||||
xlim([1260, 1365]);
|
||||
grid off
|
||||
xlabel('O-band wavelength region in nm');
|
||||
ylabel('Number of FWM products');
|
||||
title([num2str(N_(i)),' ch.'])
|
||||
|
||||
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
|
||||
|
||||
23
Functions/Theory/calcFWM/calcFwmEfficiency.m
Normal file
23
Functions/Theory/calcFWM/calcFwmEfficiency.m
Normal file
@@ -0,0 +1,23 @@
|
||||
function [eta, deltaBeta] = calcFwmEfficiency(f_i, f_j, f_k, f_0, Ds, alphaDbPerKm, Lkm)
|
||||
% FWM efficiency including phase mismatch and attenuation.
|
||||
% alphaDbPerKm is the power attenuation in dB/km, Lkm is the fiber length in km.
|
||||
|
||||
deltaBeta = calcPhaseMatching(f_i, f_j, f_k, f_0, Ds);
|
||||
|
||||
alphaNpPerM = alphaDbPerKm .* log(10) ./ 10 ./ 1e3;
|
||||
Lm = Lkm .* 1e3;
|
||||
|
||||
denominator = alphaNpPerM.^2 + deltaBeta.^2;
|
||||
term1 = alphaNpPerM.^2 ./ denominator;
|
||||
|
||||
loss_term = 1 - exp(-alphaNpPerM .* Lm);
|
||||
|
||||
if abs(alphaNpPerM) < eps
|
||||
term2 = 4 .* sin(deltaBeta .* Lm ./ 2).^2 ./ max((alphaNpPerM .* Lm).^2, eps);
|
||||
else
|
||||
term2 = 1 + 4 .* exp(-alphaNpPerM .* Lm) .* sin(deltaBeta .* Lm ./ 2).^2 ./ (loss_term.^2);
|
||||
end
|
||||
|
||||
eta = term1 .* term2;
|
||||
|
||||
end
|
||||
48
Functions/Theory/calcFWM/calcFwmPower.m
Normal file
48
Functions/Theory/calcFWM/calcFwmPower.m
Normal file
@@ -0,0 +1,48 @@
|
||||
function [P_fwm, eta, deltaBeta, Leff] = calcFwmPower( ...
|
||||
f_i, f_j, f_k, f_0, Ds, alphaDbPerKm, Lkm, ...
|
||||
P_i, P_j, P_k, gammaWInvKmInv, degeneracyFactor)
|
||||
% Calculate FWM power for a fiber with attenuation and phase mismatch.
|
||||
%
|
||||
% Inputs:
|
||||
% f_i, f_j, f_k, f_0 : frequencies in Hz
|
||||
% Ds : dispersion slope in ps / (nm^2 km)
|
||||
% alphaDbPerKm : attenuation in dB/km
|
||||
% Lkm : fiber length in km
|
||||
% P_i, P_j, P_k : launch powers in W
|
||||
% gammaWInvKmInv : nonlinear coefficient in 1/(W km)
|
||||
% degeneracyFactor : typically 3 for degenerate FWM, 6 for non-degenerate
|
||||
|
||||
if nargin < 8 || isempty(P_i)
|
||||
P_i = 1;
|
||||
end
|
||||
if nargin < 9 || isempty(P_j)
|
||||
P_j = P_i;
|
||||
end
|
||||
if nargin < 10 || isempty(P_k)
|
||||
P_k = 1;
|
||||
end
|
||||
if nargin < 11 || isempty(gammaWInvKmInv)
|
||||
gammaWInvKmInv = 1;
|
||||
end
|
||||
if nargin < 12 || isempty(degeneracyFactor)
|
||||
degeneracyFactor = 1;
|
||||
end
|
||||
|
||||
[eta, deltaBeta] = calcFwmEfficiency(f_i, f_j, f_k, f_0, Ds, alphaDbPerKm, Lkm);
|
||||
|
||||
alphaNpPerM = alphaDbPerKm .* log(10) ./ 10 ./ 1e3;
|
||||
Lm = Lkm .* 1e3;
|
||||
gammaWInvMInv = gammaWInvKmInv ./ 1e3;
|
||||
|
||||
if abs(alphaNpPerM) < eps
|
||||
Leff = Lm;
|
||||
else
|
||||
Leff = (1 - exp(-alphaNpPerM .* Lm)) ./ alphaNpPerM;
|
||||
end
|
||||
|
||||
P_fwm = degeneracyFactor .* eta .* ...
|
||||
(gammaWInvMInv .* Leff).^2 .* ...
|
||||
P_i .* P_j .* P_k .* ...
|
||||
exp(-alphaNpPerM .* Lm);
|
||||
|
||||
end
|
||||
20
Functions/Theory/calcFWM/calcPhaseMatching.m
Normal file
20
Functions/Theory/calcFWM/calcPhaseMatching.m
Normal file
@@ -0,0 +1,20 @@
|
||||
function deltaBeta = calcPhaseMatching(f_i, f_j, f_k, f_0, Ds)
|
||||
% Approximate phase mismatch for degenerate FWM close to the ZDW.
|
||||
% Inputs are frequencies in Hz.
|
||||
% f_i, f_j : pump frequencies (equal in the degenerate case)
|
||||
% f_k : signal frequency
|
||||
% f_0 : zero-dispersion frequency
|
||||
% Ds : dispersion slope in ps / (nm^2 km)
|
||||
|
||||
c = physconst('LightSpeed');
|
||||
|
||||
pump_frequency = 0.5 .* (f_i + f_j);
|
||||
lambda_zdw_m = c ./ f_0;
|
||||
dispersion_slope_si = Ds .* 1e3;
|
||||
|
||||
deltaBeta = -(2 .* pi .* lambda_zdw_m.^4 ./ c.^2) .* ...
|
||||
dispersion_slope_si .* ...
|
||||
(pump_frequency - f_0) .* ...
|
||||
(pump_frequency - f_k).^2;
|
||||
|
||||
end
|
||||
104
Functions/Theory/calcFWM/scriptFWM.m
Normal file
104
Functions/Theory/calcFWM/scriptFWM.m
Normal file
@@ -0,0 +1,104 @@
|
||||
clear;
|
||||
clc;
|
||||
|
||||
% Sweep the degenerate pump frequency around its nominal wavelength.
|
||||
pump_detuning_hz = (-800:0.01:800) .* 1e9;
|
||||
|
||||
% Degenerate FWM setup: two pump photons at f_p and one signal at f_s
|
||||
% generate an idler at f_i = 2*f_p - f_s.
|
||||
pump_wavelength_nm = 1310;
|
||||
signal_wavelength_nm = 1308;
|
||||
zdw_wavelength_nm = 1310;
|
||||
|
||||
f_pump_nominal = wavelength2frequency(pump_wavelength_nm, 'nm');
|
||||
f_signal_scalar = wavelength2frequency(signal_wavelength_nm, 'nm');
|
||||
f_zdw_scalar = wavelength2frequency(zdw_wavelength_nm, 'nm');
|
||||
|
||||
f_pump = f_pump_nominal + pump_detuning_hz;
|
||||
f_signal = f_signal_scalar .* ones(size(f_pump));
|
||||
f_zdw = f_zdw_scalar .* ones(size(f_pump));
|
||||
f_idler = 2 .* f_pump - f_signal;
|
||||
|
||||
% Fiber parameters
|
||||
dispersion_slope_ps_nm2_km = 0.07;
|
||||
attenuation_db_per_km = 0.21;
|
||||
fiber_length_km = 10;
|
||||
|
||||
% Launch powers and nonlinear coefficient
|
||||
pump_power_dbm = 10;
|
||||
signal_power_dbm = 10;
|
||||
pump_power_w = dbm2watt(pump_power_dbm);
|
||||
signal_power_w = dbm2watt(signal_power_dbm);
|
||||
gamma_w_inv_km_inv = 1.3;
|
||||
degeneracy_factor = 3;
|
||||
|
||||
[P_fwm, eta, delta_beta, L_eff_m] = calcFwmPower( ...
|
||||
f_pump, f_pump, f_signal, f_zdw, ...
|
||||
dispersion_slope_ps_nm2_km, attenuation_db_per_km, fiber_length_km, ...
|
||||
pump_power_w, pump_power_w, signal_power_w, ...
|
||||
gamma_w_inv_km_inv, degeneracy_factor);
|
||||
|
||||
f_pump_thz = f_pump .* 1e-12;
|
||||
f_zdw_thz = f_zdw_scalar .* 1e-12;
|
||||
f_signal_thz = f_signal_scalar .* 1e-12;
|
||||
idler_power_dbm = 10 .* log10(max(P_fwm, realmin) ./ 1e-3);
|
||||
|
||||
figure;
|
||||
tiledlayout(2,1);
|
||||
|
||||
ax1 = nexttile;
|
||||
plot(ax1, f_pump_thz, eta, 'LineWidth', 2);
|
||||
hold(ax1, 'on');
|
||||
xline(ax1, f_zdw_thz, '--r', 'ZDW', 'LineWidth', 1.2, ...
|
||||
'LabelOrientation', 'horizontal', 'LabelVerticalAlignment', 'bottom');
|
||||
xline(ax1, f_signal_thz, '--k', 'Signal', 'LineWidth', 1.2, ...
|
||||
'LabelOrientation', 'horizontal', 'LabelVerticalAlignment', 'middle');
|
||||
ylabel(ax1, 'FWM efficiency');
|
||||
grid(ax1, 'on');
|
||||
title(ax1, 'FWM Efficiency and Idler Power versus Pump Frequency');
|
||||
|
||||
ax2 = nexttile;
|
||||
plot(ax2, f_pump_thz, idler_power_dbm, 'LineWidth', 2);
|
||||
hold(ax2, 'on');
|
||||
xline(ax2, f_zdw_thz, '--r', 'ZDW', 'LineWidth', 1.2, ...
|
||||
'LabelOrientation', 'horizontal', 'LabelVerticalAlignment', 'bottom');
|
||||
xline(ax2, f_signal_thz, '--k', 'Signal', 'LineWidth', 1.2, ...
|
||||
'LabelOrientation', 'horizontal', 'LabelVerticalAlignment', 'middle');
|
||||
xlabel(ax2, 'Pump frequency (THz)');
|
||||
ylabel(ax2, 'FWM idler power (dBm)');
|
||||
grid(ax2, 'on');
|
||||
|
||||
fprintf('Pump wavelength : %.3f nm -> %.6f THz\n', ...
|
||||
pump_wavelength_nm, f_pump_nominal .* 1e-12);
|
||||
fprintf('Signal wavelength : %.3f nm -> %.6f THz\n', ...
|
||||
signal_wavelength_nm, f_signal_scalar .* 1e-12);
|
||||
fprintf('ZDW wavelength : %.3f nm -> %.6f THz\n', ...
|
||||
zdw_wavelength_nm, f_zdw_scalar .* 1e-12);
|
||||
fprintf('Pump launch power : %.2f dBm -> %.4g W\n', ...
|
||||
pump_power_dbm, pump_power_w);
|
||||
fprintf('Signal launch power : %.2f dBm -> %.4g W\n', ...
|
||||
signal_power_dbm, signal_power_w);
|
||||
fprintf('Peak FWM efficiency : %.4g\n', max(eta));
|
||||
fprintf('Peak FWM idler power : %.4g W (%.2f dBm)\n', ...
|
||||
max(P_fwm), 10 .* log10(max(P_fwm) ./ 1e-3));
|
||||
fprintf('Effective fiber length : %.4f km\n', L_eff_m ./ 1e3);
|
||||
fprintf('Idler wavelength range : %.3f nm to %.3f nm\n', ...
|
||||
min(frequency2wavelength(f_idler, 'nm')), max(frequency2wavelength(f_idler, 'nm')));
|
||||
fprintf('Max |delta beta| : %.4g 1/m\n', max(abs(delta_beta)));
|
||||
|
||||
function wavelength = frequency2wavelength(frequency, outputUnit)
|
||||
c = physconst('LightSpeed');
|
||||
wavelength = c ./ frequency;
|
||||
|
||||
switch lower(outputUnit)
|
||||
case 'm'
|
||||
case 'nm'
|
||||
wavelength = wavelength .* 1e9;
|
||||
otherwise
|
||||
error('Unsupported output unit "%s". Use "m" or "nm".', outputUnit);
|
||||
end
|
||||
end
|
||||
|
||||
function power_w = dbm2watt(power_dbm)
|
||||
power_w = 1e-3 .* 10.^(power_dbm ./ 10);
|
||||
end
|
||||
124
Functions/Theory/calcFWM/validate_fwm.m
Normal file
124
Functions/Theory/calcFWM/validate_fwm.m
Normal file
@@ -0,0 +1,124 @@
|
||||
%% 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
|
||||
18
Functions/Theory/calcFWM/wavelength2frequency.m
Normal file
18
Functions/Theory/calcFWM/wavelength2frequency.m
Normal file
@@ -0,0 +1,18 @@
|
||||
function frequency = wavelength2frequency(wavelength, inputUnit)
|
||||
% Convert wavelength to optical frequency.
|
||||
% Supported units: m, nm.
|
||||
|
||||
c = physconst('LightSpeed');
|
||||
|
||||
switch lower(inputUnit)
|
||||
case 'm'
|
||||
wavelength_m = wavelength;
|
||||
case 'nm'
|
||||
wavelength_m = wavelength .* 1e-9;
|
||||
otherwise
|
||||
error('Unsupported input unit "%s". Use "m" or "nm".', inputUnit);
|
||||
end
|
||||
|
||||
frequency = c ./ wavelength_m;
|
||||
|
||||
end
|
||||
25
Functions/Theory/mutual information rate TUM/LICENSE.txt
Normal file
25
Functions/Theory/mutual information rate TUM/LICENSE.txt
Normal file
@@ -0,0 +1,25 @@
|
||||
Copyright (c) 2019 Francisco Javier Garcia-Gomez <javier.garcia@tum.de>
|
||||
Institute for Communications Engineering (LNT)
|
||||
Technical University of Munich, Germany
|
||||
www.lnt.ei.tum.de
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
24
Functions/Theory/mutual information rate TUM/README.md
Normal file
24
Functions/Theory/mutual information rate TUM/README.md
Normal file
@@ -0,0 +1,24 @@
|
||||
## MI-CG: Numerically Computing Achievable Rates of Memoryless Channels
|
||||
|
||||
This repository provides a MATLAB function mi_cg.m to numerically compute achievable rates for memoryless channels. The function uses a conditionally-Gaussian (CG) channel model to obtain a lower bound on the achievable rate of the true channel. The method is well-known, and it is explained in [this short document](https://mediatum.ub.tum.de/node?id=1533663). Two example scripts that compute several achievable rate curves are also provided.
|
||||
|
||||
### Citation
|
||||
|
||||
This software and the accompanying document are meant as a tutorial to get started with mutual information as a numerical figure of merit for a communications channel. The software is provided under the open-source [MIT license](https://opensource.org/licenses/MIT). If you use the software in your academic work, please cite the accompanying [document](https://mediatum.ub.tum.de/node?id=1533663) as follows:
|
||||
|
||||
> F. J. Garcia-Gomez, “Numerically computing achievable rates of memoryless channels,” TUM University Library, 2019. [Online]. Available: https://mediatum.ub.tum.de/node?id=1533663
|
||||
|
||||
The corresponding BibTeX entry is
|
||||
```
|
||||
@article{garcia2019numerically,
|
||||
author = "Francisco Javier Garcia-Gomez",
|
||||
title = "Numerically Computing Achievable Rates of Memoryless Channels",
|
||||
year = "2019",
|
||||
journal="TUM University Library",
|
||||
url={https://mediatum.ub.tum.de/node?id=1533663}
|
||||
}
|
||||
```
|
||||
|
||||
### Acknowledgment
|
||||
|
||||
This work was supported by the German Research Foundation (DFG) under Grant KR 3517/8-2.
|
||||
156
Functions/Theory/mutual information rate TUM/air.m
Normal file
156
Functions/Theory/mutual information rate TUM/air.m
Normal file
@@ -0,0 +1,156 @@
|
||||
function air = air(x,r,idx_tx,Px,M_training)
|
||||
|
||||
MAX_MEMORY = 200e6; % maximum allowed size for a matrix
|
||||
|
||||
if nargin == 3
|
||||
Px = [];
|
||||
M_training = [];
|
||||
end
|
||||
|
||||
if nargin == 4
|
||||
M_training = [];
|
||||
end
|
||||
|
||||
|
||||
% if input is complex, separate into real and imaginary parts
|
||||
if any(imag(x(:))~=0) || any(imag(r(:))~=0)
|
||||
x = [real(x); imag(x)];
|
||||
r = [real(r); imag(r)];
|
||||
end
|
||||
|
||||
D = size(x, 1); % D = 2 if complex x
|
||||
N = size(x, 2); % number of constellation points
|
||||
M = size(r, 2); % number of samples
|
||||
|
||||
% set default training set size
|
||||
if isempty(M_training)
|
||||
M_training = ceil(0.3*M);
|
||||
end
|
||||
|
||||
M_testing = M - M_training;
|
||||
|
||||
% Training: estimate parameters of the conditionally Gaussian model
|
||||
% sort according to transmit index
|
||||
[idx_tx_training, idx_sort] = sort(idx_tx(1:M_training));
|
||||
r_training = r(:, idx_sort);
|
||||
i_bounds = zeros(1, N+1);
|
||||
|
||||
% compute conditional means and covariance matrices
|
||||
C_n = zeros(D, D, N);
|
||||
det_n = zeros(1, N);
|
||||
|
||||
for n=1:N
|
||||
% find how many times x(:, n) was transmitted and update i_bounds
|
||||
N_current_x = find(idx_tx_training((i_bounds(n)+1):end)==n, 1, 'last');
|
||||
if isempty(N_current_x), N_current_x=0; end
|
||||
i_bounds(n+1) = i_bounds(n) + N_current_x;
|
||||
|
||||
if N_current_x > 0
|
||||
% Compute mu_n=E[Y|X=x_n] according to Eq. (14) and store it in
|
||||
% x(:, n) to save space
|
||||
x(:, n) = sum(r_training(:, (i_bounds(n)+1):i_bounds(n+1)), 2)/(i_bounds(n+1)-i_bounds(n));
|
||||
|
||||
% compute C_n=cov[Y|X=x_n] according to Eq. (15)
|
||||
r_meanfree = r_training(:, (i_bounds(n)+1):i_bounds(n+1)) - x(:, n);
|
||||
C_n(:, :, n) = (r_meanfree*r_meanfree')/(i_bounds(n+1)-i_bounds(n));
|
||||
% store also the determinant of C(:, :, n)
|
||||
det_n(n) = det(C_n(:, :, n));
|
||||
|
||||
% if the determinant is 0, or if the matrix is badly conditioned,
|
||||
% regularize by adding a small identity matrix. Note that we do
|
||||
% need the check for 0 determinant, in case a cloud has exactly 0
|
||||
% variance according to the training set
|
||||
if det_n(n)==0 || cond(C_n(:, :, n))>1e16
|
||||
C_n(:, :, n) = C_n(:, :, n) + 5 * eps * eye(D);
|
||||
det_n(n) = (5*eps)^D;
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
% uniform input pmf Px if not provided
|
||||
if isempty(Px)
|
||||
Px = repmat(1/N, [1, N]);
|
||||
end
|
||||
|
||||
|
||||
% extract testing set and sort it according to transmit index
|
||||
[idx_tx_testing, idx_sort] = sort(idx_tx((M_training+1):M));
|
||||
r_testing = r(:, M_training+idx_sort);
|
||||
|
||||
% computation of h(Y|X)
|
||||
h_Y_X = 0;
|
||||
i_bounds_testing = zeros(1, N+1);
|
||||
% loop over constellation points to compute h(Y|X)
|
||||
for n = 1:N
|
||||
% find how many times x(:, n) was transmitted and update
|
||||
% i_bounds_testing
|
||||
N_current_x = find(idx_tx_testing((i_bounds_testing(n)+1):end)==n, 1, 'last');
|
||||
if isempty(N_current_x), N_current_x=0; end
|
||||
i_bounds_testing(n+1) = i_bounds_testing(n) + N_current_x;
|
||||
% add the corresponding contribution to the mutual information (two
|
||||
% first lines of Eq. (17)). This, together with
|
||||
% D/2*log2(2*pi) after the end of the loop, gives h(Y|X)
|
||||
h_Y_X = h_Y_X + N_current_x * log2(det_n(n))/2+...
|
||||
sum(sum(conj(r_testing(:, (i_bounds_testing(n)+1):i_bounds_testing(n+1))-x(:, n)).*(C_n(:, :, n)\(r_testing(:, (i_bounds_testing(n)+1):i_bounds_testing(n+1))-x(:, n)))))/2/log(2);
|
||||
|
||||
|
||||
end
|
||||
h_Y_X = D/2*log2(2*pi) + h_Y_X/M_testing;
|
||||
|
||||
% When computing log(py), we might run out of memory. If necessary, we
|
||||
% doe the computation in blocks
|
||||
logpy = zeros(1, M_testing);
|
||||
BLOCK_SIZE = floor(MAX_MEMORY/N);
|
||||
N_blocks = ceil(M_testing/BLOCK_SIZE);
|
||||
|
||||
% loop over blocks of symbols. This loop can be replaced by parfor to allow
|
||||
% parallel computation
|
||||
for i_block = 1:N_blocks
|
||||
|
||||
logpy_cur = zeros(1, M_testing);
|
||||
|
||||
% beginning of block
|
||||
i_start = (i_block-1) * BLOCK_SIZE + 1;
|
||||
% end of block
|
||||
i_end = min(M_testing, i_block*BLOCK_SIZE);
|
||||
% block size
|
||||
current_block_size = i_end-i_start+1;
|
||||
|
||||
% compute exponents of third line of (17)
|
||||
exponents = zeros(N, current_block_size);
|
||||
for n = 1:N
|
||||
exponents(n, :) = -log(det_n(n))/2-real(sum(conj(r_testing(:, i_start:i_end)-x(:, n)).*(C_n(:, :, n)\(r_testing(:, i_start:i_end)-x(:, n))), 1))/2;
|
||||
%sum über 2 einträge von r
|
||||
end
|
||||
|
||||
% compute third line of Eq. (17). Use a custom function
|
||||
% that computes log(sum(exp(x))) avoiding overflow errors
|
||||
logpy_cur(i_start:i_end) = math_logsumexp(log(Px(:))+exponents, 1);
|
||||
logpy = logpy + logpy_cur;
|
||||
end
|
||||
|
||||
% output entropy h(Y)
|
||||
h_Y = D/2*log2(2*pi) - mean(logpy)/log(2);%log basis change
|
||||
|
||||
% compute mutual information
|
||||
air = h_Y - h_Y_X;
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
function [y] = math_logsumexp(x, dim)
|
||||
%[y] = math_logsumexp(x, dim)
|
||||
% Computes log(sum(exp(x), dim)), avoiding overflow errors when one of the
|
||||
% x is large.
|
||||
|
||||
if nargin<2 || isempty(dim)
|
||||
m = max(x);
|
||||
y = m + log(sum(exp(x-m)));
|
||||
else
|
||||
m = max(x, [], dim);
|
||||
y = m + log(sum(exp(x-m), dim));
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Copyright (c) 2019 Francisco Javier Garcia-Gomez <javier.garcia@tum.de>
|
||||
% Institute for Communications Engineering (LNT)
|
||||
% Technical University of Munich, Germany
|
||||
% www.lnt.ei.tum.de
|
||||
%
|
||||
% All rights reserved.
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%
|
||||
% Permission is hereby granted, free of charge, to any person obtaining a
|
||||
% copy of this software and associated documentation files (the
|
||||
% "Software"), to deal in the Software without restriction, including
|
||||
% without limitation the rights to use, copy, modify, merge, publish,
|
||||
% distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
% persons to whom the Software is furnished to do so, subject to the
|
||||
% following conditions:
|
||||
%
|
||||
% The above copyright notice and this permission notice shall be included
|
||||
% in all copies or substantial portions of the Software.
|
||||
%
|
||||
% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
% OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
% MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
% NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
% DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
% OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
% USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%% example_mi_cg_complex_16qam.m %%%%%%%%%%%%%%%%%%%%%%
|
||||
%
|
||||
% Example usage of the function mi_cg to numerically compute mutual
|
||||
% information between two complex sequences. This file simulates a
|
||||
% one-dimensional complex AWGN channel with 16-QAM constellation for
|
||||
% different SNRs, and then plots the achievable rate, which is equal to two
|
||||
% times the 4-PAM curve of Fig. 1 of [1].
|
||||
%
|
||||
% Note that using mi_cg with complex sequences assumes that the channel
|
||||
% model q(Y|X) is circularly symmetric for a given X=x (i.e., that the
|
||||
% received clouds are circular). This is not the case in a channel with
|
||||
% phase noise: see example_it_mi_cg.m for an example of how to deal with
|
||||
% non-circularly-symmetric channels.
|
||||
%
|
||||
% [1] G. David Forney and Gottfried Ungerboeck, "Modulation and Coding for
|
||||
% Linear Gaussian Channels", IEEE Trans. Inf. Theory vol. 44, no. 6, pp.
|
||||
% 2384-2415, October 1998
|
||||
%
|
||||
% Technische Universitaet Muenchen - Lehrstuhl fuer Nachrichtentechnik
|
||||
% Date: 12.12.2019
|
||||
% Author: Francisco Javier Garcia-Gomez <javier.garcia@tum.de>
|
||||
%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
clear;
|
||||
% close all;
|
||||
|
||||
%%% Simulation parameters
|
||||
M_QAM=16; % QAM size
|
||||
var_w=1; % noise variance
|
||||
SNR_dB_values=(-5):2:25; % SNR values in dB
|
||||
N=8000; % number of Monte-Carlo points
|
||||
|
||||
%%% Derived parameters
|
||||
n_SNR=length(SNR_dB_values);
|
||||
SNR_values=10.^(SNR_dB_values/10);
|
||||
|
||||
%%% Generation of QAM constellation with power 1
|
||||
M_PAM=sqrt(M_QAM); % number of points per real dimension
|
||||
X_1d=-(M_PAM-1)+2*(0:(M_PAM-1)); % generate PAM
|
||||
X=X_1d+1i*X_1d.'; % transform to QAM
|
||||
X=X(:).'*sqrt(3/2/(M_QAM-1)); % set to unit power
|
||||
X=[real(X); imag(X)]; % separate real and imaginary parts
|
||||
|
||||
%%% Uniformly choose transmit indices
|
||||
idx_tx=randi(M_QAM, [1, N]);
|
||||
|
||||
%%% AWGN noise
|
||||
w=sqrt(var_w)*(randn([2, N]));%+1i*randn([1, N]));
|
||||
|
||||
%%% Loop over the SNR values
|
||||
|
||||
MI_awgn=zeros(1, n_SNR);
|
||||
fig = figure(1);
|
||||
for i_SNR=1:n_SNR
|
||||
|
||||
% transmitted points
|
||||
s=sqrt(SNR_values(i_SNR)*var_w)*X(:, idx_tx);
|
||||
|
||||
% AWGN channel
|
||||
r_awgn = s+w;
|
||||
|
||||
%%%%%%%%%%%%
|
||||
clf
|
||||
hold on
|
||||
xlim([-20, 20]);
|
||||
ylim([-20, 20]);
|
||||
%received signal
|
||||
scatter(r_awgn(1,:),r_awgn(2,:),1,"red",'.');
|
||||
%tx signal constellation
|
||||
scatter(s(1,:),s(2,:),4,"black",'o','filled');
|
||||
%uni power transmit constallation
|
||||
scatter(X(1,:),X(2,:),5,'blue','o','filled');
|
||||
drawnow
|
||||
pause(0.1)
|
||||
%%%%%%%%%%%%
|
||||
|
||||
% Compute MI
|
||||
MI_awgn(i_SNR)=air(X, r_awgn, idx_tx);
|
||||
% The following also works but is slower
|
||||
% MI_awgn(i_SNR)=mi_cg(s, r_awgn);
|
||||
end
|
||||
|
||||
|
||||
I_shannon=log2(1+SNR_values);
|
||||
|
||||
figure(2);
|
||||
hold on
|
||||
plot(SNR_dB_values, I_shannon, '-', 'DisplayName', 'log_2 (1+SNR)');
|
||||
hold on;
|
||||
plot(SNR_dB_values, MI_awgn, '--', 'DisplayName', [num2str(M_QAM) '-QAM, AWGN']);
|
||||
hold off;
|
||||
xlabel('SNR (dB)'); ylabel('Achievable rate (bits/complex dimension)');
|
||||
title(['Achievable rate of ' num2str(M_QAM) '-QAM in AWGN']);
|
||||
legend('Location', 'NorthWest');
|
||||
@@ -0,0 +1,140 @@
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Copyright (c) 2019 Francisco Javier Garcia-Gomez <javier.garcia@tum.de>
|
||||
% Institute for Communications Engineering (LNT)
|
||||
% Technical University of Munich, Germany
|
||||
% www.lnt.ei.tum.de
|
||||
%
|
||||
% All rights reserved.
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%
|
||||
% Permission is hereby granted, free of charge, to any person obtaining a
|
||||
% copy of this software and associated documentation files (the
|
||||
% "Software"), to deal in the Software without restriction, including
|
||||
% without limitation the rights to use, copy, modify, merge, publish,
|
||||
% distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
% persons to whom the Software is furnished to do so, subject to the
|
||||
% following conditions:
|
||||
%
|
||||
% The above copyright notice and this permission notice shall be included
|
||||
% in all copies or substantial portions of the Software.
|
||||
%
|
||||
% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
% OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
% MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
% NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
% DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
% OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
% USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
%%%%%%%%%%%%%%%% example_mi_cg_real_2D_awgn_vs_phasenoise %%%%%%%%%%%%%%%%%
|
||||
%
|
||||
% Example usage of the function mi_cg to numerically compute mutual
|
||||
% information between two sequences. This file simulates a two-dimensional
|
||||
% AWGN channel with 4-PAM constellation (or, equivalently, a complex AWGN
|
||||
% channel with 16-QAM constellation) for different SNRs, and then plots
|
||||
% the achievable rate, reproducing the 4-PAM curve of Fig. 1 of [1]. Note
|
||||
% that this curve can also be reproduced by simulating a 1-dimensional
|
||||
% channel with 4-PAM: this file is an example of how to deal with multiple
|
||||
% dimensions.
|
||||
%
|
||||
% This file also simulates a complex phase-noise channel:
|
||||
% r=s.*exp(1i*theta)+w
|
||||
% where w is complex AWGN and theta is i.i.d. real Gaussian. As q(Y|X) for
|
||||
% this channel is not circularly-symmetric, this complex channel needs to
|
||||
% be separated into two real dimensions to compute the mutual information.
|
||||
% The resulting achievable rate is, as expected, below the rate for the
|
||||
% AWGN channel.
|
||||
%
|
||||
% [1] G. David Forney and Gottfried Ungerboeck, "Modulation and Coding for
|
||||
% Linear Gaussian Channels", IEEE Trans. Inf. Theory vol. 44, no. 6, pp.
|
||||
% 2384-2415, October 1998
|
||||
%
|
||||
% [2]
|
||||
%
|
||||
% Technische Universitaet Muenchen - Lehrstuhl fuer Nachrichtentechnik
|
||||
% Date: 12.12.2019
|
||||
% Author: Francisco Javier Garcia-Gomez <javier.garcia@tum.de>
|
||||
%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
clear;
|
||||
close all;
|
||||
|
||||
%%% Simulation parameters
|
||||
D=1; % number of complex dimensions
|
||||
M_QAM=16; % QAM size
|
||||
var_w=1; % noise variance
|
||||
E_theta=0.2; % phase offset for the phase noise channel
|
||||
var_theta=0.05; % phase noise variance
|
||||
SNR_dB_values=(-5):2:25; % SNR values in dB
|
||||
N=8000; % number of Monte-Carlo points
|
||||
|
||||
%%% Derived parameters
|
||||
n_SNR=length(SNR_dB_values);
|
||||
SNR_values=10.^(SNR_dB_values/10);
|
||||
|
||||
%%% Generation QAM constellation with power 1
|
||||
M_PAM=sqrt(M_QAM); % number of points per real dimension
|
||||
X_1d=-(M_PAM-1)+2*(0:(M_PAM-1)); % generate PAM
|
||||
X=X_1d+1i*X_1d.'; % transform to QAM
|
||||
X=X(:).'*sqrt(3/2/(M_QAM-1)); % set to unit power
|
||||
X=[real(X); imag(X)]; % separate real and imaginary parts
|
||||
|
||||
%%% Uniformly choose transmit indices
|
||||
idx_tx=randi(M_QAM^D, [1, N]);
|
||||
|
||||
%%% AWGN noise (real and imaginary parts)
|
||||
w=sqrt(var_w/2)*randn([2*D, N]);
|
||||
%%% phase noise
|
||||
theta=E_theta+sqrt(var_theta)*randn([D, N]);
|
||||
|
||||
%%% Loop over the SNR values
|
||||
MI_awgn=zeros(1, n_SNR);
|
||||
MI_phasenoise=zeros(1, n_SNR);
|
||||
fig = figure(1);
|
||||
for i_SNR=1:n_SNR
|
||||
% transmitted points
|
||||
s=sqrt(SNR_values(i_SNR)*var_w)*X(:, idx_tx);
|
||||
|
||||
% AWGN channel
|
||||
r_awgn=s+w;
|
||||
|
||||
% Compute MI
|
||||
MI_awgn(i_SNR)=air(X, r_awgn, idx_tx)/D;
|
||||
% The following also works but is slower
|
||||
% MI_awgn(i_SNR)=air(s, r_awgn)/D;
|
||||
|
||||
% Phase-noise channel
|
||||
s_complex=s(1:2:end, :)+1i*s(2:2:end, :); % transform to complex
|
||||
r_phasenoise_complex=s_complex.*exp(1i*theta); % phase noise and AWGN
|
||||
r_phasenoise=zeros(2*D, N); % transform to real
|
||||
r_phasenoise(1:2:end, :)=real(r_phasenoise_complex);
|
||||
r_phasenoise(2:2:end, :)=imag(r_phasenoise_complex);
|
||||
r_phasenoise=r_phasenoise+w; % add AWGN
|
||||
|
||||
clf
|
||||
fig = scatter(r_phasenoise(1,:),r_phasenoise(2,:),1,'.');
|
||||
xlim([-20, 20]);
|
||||
ylim([-20, 20]);
|
||||
drawnow
|
||||
pause(0.1)
|
||||
|
||||
% Compute MI
|
||||
MI_phasenoise(i_SNR)=air(X, r_phasenoise, idx_tx)/D;
|
||||
% The following also works but is slower
|
||||
% MI_phasenoise(i_SNR)=air(s, r_phasenoise)/D;
|
||||
end
|
||||
|
||||
% Shannon capacity of the AWGN channel
|
||||
I_shannon=log2(1+SNR_values);
|
||||
|
||||
figure;
|
||||
plot(SNR_dB_values, I_shannon, '-', 'DisplayName', 'log_2 (1+SNR)');
|
||||
hold on;
|
||||
plot(SNR_dB_values, MI_awgn, '--', 'DisplayName', '16-QAM, AWGN');
|
||||
plot(SNR_dB_values, MI_phasenoise, '-.', 'DisplayName', ['16-QAM, Phase noise, \sigma_\Theta^2=' num2str(var_theta)]);
|
||||
hold off;
|
||||
xlabel('SNR (dB)'); ylabel('Achievable rate (bits/complex dimension)');
|
||||
title(['Achievable rate of 16-QAM in AWGN and in a phase noise channel with \theta~N(' num2str(E_theta) ', ' num2str(var_theta) ')']);
|
||||
legend('Location', 'NorthWest');
|
||||
164
Functions/Theory/mutual information rate TUM/example_silas.m
Normal file
164
Functions/Theory/mutual information rate TUM/example_silas.m
Normal file
@@ -0,0 +1,164 @@
|
||||
colored_noise = true;
|
||||
I_shannon=[];
|
||||
for cmplx = [0,1]
|
||||
cnt = 1;
|
||||
for M_PAM = [4,8,16]
|
||||
|
||||
|
||||
complex_constellation = cmplx;
|
||||
|
||||
%%% Simulation parameters
|
||||
% M_PAM=2; % QAM size
|
||||
var_w=1; % noise variance
|
||||
SNR_dB_values=(-5):1:35; % SNR values in dB
|
||||
N=8000; % number of Monte-Carlo points
|
||||
|
||||
%%% Derived parameters
|
||||
n_SNR=length(SNR_dB_values);
|
||||
SNR_values=10.^(SNR_dB_values/10);
|
||||
|
||||
%%% Generation of QAM constellation with power 1
|
||||
M=sqrt(M_PAM); % number of points per real dimension
|
||||
|
||||
if complex_constellation
|
||||
X_ = qammod(0:M_PAM-1,M_PAM,"gray");
|
||||
else
|
||||
X_ = pammod(0:M_PAM-1,M_PAM,0,'gray');
|
||||
end
|
||||
|
||||
X_ = X_ ./ rms(unique(X_));
|
||||
X_=[real(X_); imag(X_)];
|
||||
|
||||
%%%%%%%%%%%%
|
||||
figure(10);
|
||||
clf
|
||||
hold on
|
||||
scatter(X_(1,:),X_(2,:),15,'red','x','DisplayName','Matlab');
|
||||
%%%%%%%%%%%%
|
||||
|
||||
%%% Uniformly choose transmit indices
|
||||
idx_tx=randi(M_PAM, [1, N]);
|
||||
|
||||
%%% AWGN noise
|
||||
w=sqrt(var_w)*(randn([2, N]));
|
||||
|
||||
%%% Loop over the SNR values
|
||||
|
||||
MI_awgn=zeros(1, n_SNR);
|
||||
fig = figure(2);
|
||||
|
||||
if colored_noise
|
||||
for i_SNR = 1:n_SNR
|
||||
% Transmitted signal for the given indices
|
||||
signal = X_(:, idx_tx);
|
||||
|
||||
% Generate white Gaussian noise of the same size as the signal
|
||||
noise_white = randn(size(signal));
|
||||
|
||||
% Define the filter coefficient for colored noise (adjust as needed)
|
||||
a = 0; % A higher value gives more correlation
|
||||
|
||||
% Filter the white noise to create colored noise.
|
||||
% Here we filter each row (dimension) independently.
|
||||
noise_colored = zeros(size(signal));
|
||||
noise_colored(1,:) = filter(1, [1, -a], noise_white(1,:));
|
||||
noise_colored(2,:) = filter(1, [1, -a], noise_white(2,:));
|
||||
|
||||
% Compute signal and unscaled noise power for proper scaling.
|
||||
signal_power = mean(abs(signal(:)).^2);
|
||||
noise_power = mean(abs(noise_colored(:)).^2);
|
||||
|
||||
% Convert desired SNR from dB to linear scale.
|
||||
SNR_linear = 10^(SNR_dB_values(i_SNR)/10);
|
||||
|
||||
% Scale the colored noise so that signal_power / noise_power equals SNR_linear.
|
||||
scaling_factor = sqrt(signal_power / (SNR_linear * noise_power));
|
||||
noise_colored_scaled = scaling_factor * noise_colored;
|
||||
|
||||
% Received signal is the sum of the signal and the scaled colored noise.
|
||||
r_colored = signal + noise_colored_scaled;
|
||||
|
||||
% For SNR measurement, compute the noise actually added.
|
||||
measured_noise = r_colored - signal;
|
||||
snr_meas_(i_SNR) = snr(signal(1,:) + 1i*signal(2,:), ...
|
||||
measured_noise(1,:) + 1i*measured_noise(2,:));
|
||||
|
||||
% Plotting the transmitted and received signal
|
||||
clf;
|
||||
hold on;
|
||||
xlim([-4, 4]);
|
||||
ylim([-4, 4]);
|
||||
scatter(signal(1,:), signal(2,:), 3, "black", 'o', 'DisplayName','Tx Constellation');
|
||||
scatter(r_colored(1,:), r_colored(2,:), 1, "red", 'x', 'DisplayName', 'Colored Noise Mapping');
|
||||
drawnow;
|
||||
|
||||
% Compute Mutual Information (or any other metric) with the new channel
|
||||
MI_awgn_(i_SNR) = air(X_, r_colored, idx_tx);
|
||||
end
|
||||
else
|
||||
|
||||
|
||||
for i_SNR=1:n_SNR
|
||||
|
||||
|
||||
s_ = sqrt(SNR_values(i_SNR)*var_w) * X_(:, idx_tx);
|
||||
% r_awgn_ = s_ + w;
|
||||
|
||||
r_awgn_ = awgn(X_(:, idx_tx),SNR_dB_values(i_SNR),"measured",10);
|
||||
|
||||
w_awgn_matlab = r_awgn_ - X_(:,idx_tx);
|
||||
snr_meas_(i_SNR) = snr(X_(1, idx_tx)+1i*X_(2, idx_tx) , w_awgn_matlab(1,:)+1i*w_awgn_matlab(2,:));
|
||||
|
||||
%%%%%%%%%%%%
|
||||
clf
|
||||
hold on
|
||||
xlim([-4, 4]);
|
||||
ylim([-4, 4]);
|
||||
%received signal
|
||||
scatter(X_(1, idx_tx),X_(2, idx_tx),3,"black",'o','DisplayName','Tx Constellation');
|
||||
|
||||
|
||||
scatter(r_awgn_(1,:),r_awgn_(2,:),1,"red",'x','DisplayName','Matlab Mapping');
|
||||
|
||||
drawnow
|
||||
%%%%%%%%%%%%
|
||||
|
||||
MI_awgn_(i_SNR)=air(X_, r_awgn_, idx_tx);
|
||||
% The following also works but is slower
|
||||
% MI_awgn(i_SNR)=mi_cg(s, r_awgn);
|
||||
end
|
||||
end
|
||||
|
||||
figure(3);
|
||||
hold on
|
||||
|
||||
if isempty(I_shannon)
|
||||
I_shannon=log2(1+db2pow(snr_meas_));
|
||||
plot(snr_meas_, I_shannon, '-', 'DisplayName', 'log_2 (1+SNR)','Color','black');
|
||||
end
|
||||
|
||||
|
||||
cols = [ 0.9047 0.1918 0.1988
|
||||
0.2941 0.5447 0.7494
|
||||
0.3718 0.7176 0.3612
|
||||
1.0000 0.5482 0.1000
|
||||
0.8650 0.8110 0.4330
|
||||
0.6859 0.4035 0.2412];
|
||||
if complex_constellation
|
||||
plot(snr_meas_, MI_awgn_, ':', 'DisplayName', ['',num2str(M_PAM) '-QAM, AWGN'],'LineWidth',1,'Color',cols(cnt,:));
|
||||
else
|
||||
plot(snr_meas_, MI_awgn_, '-', 'DisplayName', ['',num2str(M_PAM) '-PAM, AWGN'],'LineWidth',1,'Color',cols(cnt,:));
|
||||
end
|
||||
|
||||
hold off;
|
||||
ylim([0,8]);
|
||||
xlim([min(SNR_dB_values) max(SNR_dB_values)])
|
||||
xlabel('SNR (dB)'); ylabel('Achievable rate (bits/complex dimension)');
|
||||
title(['Achievable rate of ' num2str(M_PAM) '-QAM in AWGN']);
|
||||
legend('Location', 'NorthWest');
|
||||
yline(log2(M_PAM),'LineStyle',':','HandleVisibility','off','Color','black');
|
||||
|
||||
cnt = cnt+1;
|
||||
|
||||
end
|
||||
end
|
||||
104
Functions/Theory/mutual information rate TUM/mi_cg.m
Normal file
104
Functions/Theory/mutual information rate TUM/mi_cg.m
Normal file
@@ -0,0 +1,104 @@
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Copyright (c) 2019 Francisco Javier Garcia-Gomez <javier.garcia@tum.de>
|
||||
% Institute for Communications Engineering (LNT)
|
||||
% Technical University of Munich, Germany
|
||||
% www.lnt.ei.tum.de
|
||||
%
|
||||
% All rights reserved.
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%
|
||||
% Permission is hereby granted, free of charge, to any person obtaining a
|
||||
% copy of this software and associated documentation files (the
|
||||
% "Software"), to deal in the Software without restriction, including
|
||||
% without limitation the rights to use, copy, modify, merge, publish,
|
||||
% distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
% persons to whom the Software is furnished to do so, subject to the
|
||||
% following conditions:
|
||||
%
|
||||
% The above copyright notice and this permission notice shall be included
|
||||
% in all copies or substantial portions of the Software.
|
||||
%
|
||||
% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
% OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
% MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
% NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
% DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
% OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
% USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%% example_mi_cg_complex_16qam.m %%%%%%%%%%%%%%%%%%%%%%
|
||||
%
|
||||
% Example usage of the function mi_cg to numerically compute mutual
|
||||
% information between two complex sequences. This file simulates a
|
||||
% one-dimensional complex AWGN channel with 16-QAM constellation for
|
||||
% different SNRs, and then plots the achievable rate, which is equal to two
|
||||
% times the 4-PAM curve of Fig. 1 of [1].
|
||||
%
|
||||
% Note that using mi_cg with complex sequences assumes that the channel
|
||||
% model q(Y|X) is circularly symmetric for a given X=x (i.e., that the
|
||||
% received clouds are circular). This is not the case in a channel with
|
||||
% phase noise: see example_it_mi_cg.m for an example of how to deal with
|
||||
% non-circularly-symmetric channels.
|
||||
%
|
||||
% [1] G. David Forney and Gottfried Ungerboeck, "Modulation and Coding for
|
||||
% Linear Gaussian Channels", IEEE Trans. Inf. Theory vol. 44, no. 6, pp.
|
||||
% 2384-2415, October 1998
|
||||
%
|
||||
% Technische Universitaet Muenchen - Lehrstuhl fuer Nachrichtentechnik
|
||||
% Date: 12.12.2019
|
||||
% Author: Francisco Javier Garcia-Gomez <javier.garcia@tum.de>
|
||||
%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
clear;
|
||||
close all;
|
||||
|
||||
%%% Simulation parameters
|
||||
M_QAM=16; % QAM size
|
||||
var_w=1; % noise variance
|
||||
SNR_dB_values=(-5):2:25; % SNR values in dB
|
||||
N=8000; % number of Monte-Carlo points
|
||||
|
||||
%%% Derived parameters
|
||||
n_SNR=length(SNR_dB_values);
|
||||
SNR_values=10.^(SNR_dB_values/10);
|
||||
|
||||
%%% Generation of QAM constellation with power 1
|
||||
M_PAM=sqrt(M_QAM); % number of points per real dimension
|
||||
X_1d=-(M_PAM-1)+2*(0:(M_PAM-1)); % generate PAM
|
||||
X=X_1d+1i*X_1d.'; % transform to QAM
|
||||
X=X(:).'*sqrt(3/2/(M_QAM-1)); % set to unit power
|
||||
|
||||
%%% Uniformly choose transmit indices
|
||||
idx_tx=randi(M_QAM, [1, N]);
|
||||
|
||||
%%% AWGN noise
|
||||
w=sqrt(var_w/2)*(randn([1, N])+1i*randn([1, N]));
|
||||
|
||||
%%% Loop over the SNR values
|
||||
MI_awgn=zeros(1, n_SNR);
|
||||
for i_SNR=1:n_SNR
|
||||
% transmitted points
|
||||
|
||||
s=sqrt(SNR_values(i_SNR)*var_w)*X(:, idx_tx);
|
||||
|
||||
% AWGN channel
|
||||
r_awgn = s+w;
|
||||
|
||||
% Compute MI
|
||||
MI_awgn(i_SNR)=air(X, r_awgn, idx_tx);
|
||||
% The following also works but is slower: MI_awgn(i_SNR)=air(s, r_awgn);
|
||||
end
|
||||
|
||||
|
||||
I_shannon=log2(1+SNR_values);
|
||||
|
||||
figure;
|
||||
plot(SNR_dB_values, I_shannon, '-', 'DisplayName', 'log_2 (1+SNR)');
|
||||
hold on;
|
||||
plot(SNR_dB_values, MI_awgn, '--', 'DisplayName', [num2str(M_QAM) '-QAM, AWGN']);
|
||||
hold off;
|
||||
xlabel('SNR (dB)'); ylabel('Achievable rate (bits/complex dimension)');
|
||||
title(['Achievable rate of ' num2str(M_QAM) '-QAM in AWGN']);
|
||||
legend('Location', 'NorthWest');
|
||||
@@ -0,0 +1,135 @@
|
||||
|
||||
clear;
|
||||
I_shannon=[];
|
||||
for cmplx = [1,0]
|
||||
cnt = 1;
|
||||
for M_PAM = [2,4,8,16]
|
||||
|
||||
% close all;
|
||||
usegarcia = 0;
|
||||
|
||||
complex_constellation = cmplx;
|
||||
|
||||
%%% Simulation parameters
|
||||
% M_PAM=2; % QAM size
|
||||
var_w=1; % noise variance
|
||||
SNR_dB_values=(-5):1:35; % SNR values in dB
|
||||
N=8000; % number of Monte-Carlo points
|
||||
|
||||
%%% Derived parameters
|
||||
n_SNR=length(SNR_dB_values);
|
||||
SNR_values=10.^(SNR_dB_values/10);
|
||||
|
||||
%%% Generation of QAM constellation with power 1
|
||||
M=sqrt(M_PAM); % number of points per real dimension
|
||||
|
||||
if complex_constellation
|
||||
X_ = qammod(0:M_PAM-1,M_PAM,"gray");
|
||||
else
|
||||
X_ = pammod(0:M_PAM-1,M_PAM,0,'gray');
|
||||
end
|
||||
|
||||
X_ = X_ ./ rms(unique(X_));
|
||||
X_=[real(X_); imag(X_)];
|
||||
|
||||
%%%%%%%%%%%%
|
||||
figure(10);
|
||||
clf
|
||||
hold on
|
||||
scatter(X_(1,:),X_(2,:),15,'red','x','DisplayName','Matlab');
|
||||
%%%%%%%%%%%%
|
||||
|
||||
%%% Uniformly choose transmit indices
|
||||
idx_tx=randi(M_PAM, [1, N]);
|
||||
|
||||
%%% AWGN noise
|
||||
w=sqrt(var_w)*(randn([2, N]));
|
||||
|
||||
%%% Loop over the SNR values
|
||||
|
||||
MI_awgn=zeros(1, n_SNR);
|
||||
fig = figure(2);
|
||||
for i_SNR=1:n_SNR
|
||||
|
||||
if usegarcia
|
||||
|
||||
|
||||
%scale transmitted points acc. to SNR condition (this is not correct I think, the papaer also show diff results)
|
||||
% s=sqrt(SNR_values(i_SNR)*var_w)*X(:, idx_tx);
|
||||
|
||||
%scale nosie acc. to snr condition
|
||||
noise_power = mean(abs(X_(1, idx_tx)+1i*X_(2, idx_tx)).^2) / SNR_values(i_SNR); % Noise power
|
||||
w_ = sqrt(noise_power) .* w / sqrt(2);
|
||||
|
||||
% AWGN channel
|
||||
r_awgn = X(:, idx_tx)+w_;
|
||||
% snr_meas(i_SNR) = snr(s(1,:)+1i*s(2,:),w(1,:)+1i*w(2,:));
|
||||
snr_meas(i_SNR) = snr(X_(1, idx_tx)+1i*X_(2, idx_tx),w_(1,:)+1i*w_(2,:));
|
||||
end
|
||||
|
||||
s_ = sqrt(SNR_values(i_SNR)*var_w) * X_(:, idx_tx);
|
||||
% r_awgn_ = s_ + w;
|
||||
|
||||
if cmplx
|
||||
r_awgn_ = awgn(X_(:, idx_tx),SNR_dB_values(i_SNR),"measured",10);
|
||||
w_awgn_matlab = r_awgn_ - X_(:,idx_tx);
|
||||
snr_meas_(i_SNR) = snr(X_(1, idx_tx)+1i*X_(2, idx_tx) , w_awgn_matlab(1,:)+1i*w_awgn_matlab(2,:));
|
||||
else
|
||||
r_awgn_ = awgn(X_(1, idx_tx),SNR_dB_values(i_SNR),"measured",10);
|
||||
w_awgn_matlab = r_awgn_ - X_(1,idx_tx);
|
||||
snr_meas_(i_SNR) = snr(X_(1, idx_tx) , w_awgn_matlab(1,:));
|
||||
end
|
||||
|
||||
%%%%%%%%%%%%
|
||||
clf
|
||||
hold on
|
||||
xlim([-4, 4]);
|
||||
ylim([-4, 4]);
|
||||
%received signal
|
||||
scatter(X_(1, idx_tx),X_(2, idx_tx),3,"black",'o','DisplayName','Tx Constellation');
|
||||
|
||||
|
||||
if cmplx
|
||||
scatter(r_awgn_(1,:),r_awgn_(2,:),1,"red",'x','DisplayName','Matlab Mapping');
|
||||
else
|
||||
scatter(r_awgn_,zeros(size(r_awgn_)),1,"red",'x','DisplayName','Matlab Mapping');
|
||||
end
|
||||
drawnow
|
||||
|
||||
MI_awgn_(i_SNR)=air(X_, r_awgn_, idx_tx);
|
||||
% The following also works but is slower
|
||||
% MI_awgn(i_SNR)=mi_cg(s, r_awgn);
|
||||
end
|
||||
|
||||
figure(4);
|
||||
hold on
|
||||
|
||||
if isempty(I_shannon)
|
||||
I_shannon=log2(1+db2pow(snr_meas_));
|
||||
plot(snr_meas_, I_shannon, '-', 'DisplayName', 'log_2 (1+SNR)','Color','black');
|
||||
end
|
||||
|
||||
if usegarcia
|
||||
plot(SNR_dB_values, MI_awgn, '--', 'DisplayName', ['GARCIA ',num2str(M_PAM) '-QAM, AWGN']);
|
||||
end
|
||||
|
||||
cols = linspecer(6);
|
||||
if complex_constellation
|
||||
plot(snr_meas_, MI_awgn_, ':', 'DisplayName', ['',num2str(M_PAM) '-QAM, AWGN'],'LineWidth',1,'Color',cols(cnt,:));
|
||||
else
|
||||
plot(snr_meas_, MI_awgn_, '-', 'DisplayName', ['',num2str(M_PAM) '-PAM, AWGN'],'LineWidth',1,'Color',cols(cnt,:));
|
||||
end
|
||||
|
||||
hold off;
|
||||
ylim([0,8]);
|
||||
xlim([min(SNR_dB_values) max(SNR_dB_values)])
|
||||
xlabel('SNR (dB)'); ylabel('Achievable rate (bits/complex dimension)');
|
||||
title(['Achievable rate of ' num2str(M_PAM) '-QAM in AWGN']);
|
||||
legend('Location', 'NorthWest');
|
||||
yline(log2(M_PAM),'LineStyle',':','HandleVisibility','off','Color','black');
|
||||
|
||||
autoArrangeFigures;
|
||||
cnt = cnt+1;
|
||||
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user