Merge branch 'main' of cau-git.rz.uni-kiel.de:nt/mitarbeiter/silas/imdd_simulation
This commit is contained in:
68
Functions/Theory/Dispersion/power_fading_gif.m
Normal file
68
Functions/Theory/Dispersion/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)));
|
||||
@@ -1,120 +0,0 @@
|
||||
function loss_curve_digitized(filename)
|
||||
% PLOT_WPD_DATASETS Reads and plots scattering data from a CSV file.
|
||||
% filename: String containing the path to the CSV file (e.g., 'wpd_datasets.csv')
|
||||
%
|
||||
% This function expects a CSV with the following structure:
|
||||
% Row 1: Dataset Names (every 2nd column)
|
||||
% Row 2: Variable Names (X, Y, X, Y...)
|
||||
% Row 3+: Numeric Data (potentially with NaNs for unequal lengths)
|
||||
|
||||
% --- 1. Import Data ---
|
||||
if nargin < 1
|
||||
filename = 'wpd_datasets.csv'; % Default filename
|
||||
end
|
||||
|
||||
% Read the numeric data, skipping the first 2 header lines
|
||||
% 'TreatAsMissing' ensures empty cells become NaNs
|
||||
raw_data = readmatrix(filename, 'NumHeaderLines', 2);
|
||||
|
||||
% Read the first line separately to parse Dataset Names
|
||||
fid = fopen(filename, 'r');
|
||||
if fid == -1
|
||||
error('Could not open file: %s', filename);
|
||||
end
|
||||
header_line = fgetl(fid);
|
||||
fclose(fid);
|
||||
|
||||
% Split header by comma to get names
|
||||
raw_names = split(header_line, ',');
|
||||
|
||||
% Extract non-empty names (assuming names are in col 1, 3, 5...)
|
||||
dataset_names = raw_names(~cellfun('isempty', raw_names));
|
||||
|
||||
% --- 2. Setup Plot ---
|
||||
figure('Color', 'w', 'Position', [100, 100, 800, 600]);
|
||||
ax = gca;
|
||||
hold(ax, 'on');
|
||||
|
||||
|
||||
line_styles = {'-', '-', '-', '-'};
|
||||
|
||||
% --- 3. Iterate and Plot Each Dataset ---
|
||||
num_datasets = length(dataset_names);
|
||||
|
||||
for i = 1:num_datasets
|
||||
% Calculate column indices for X and Y
|
||||
% Dataset 1: Cols 1,2 | Dataset 2: Cols 3,4 | etc.
|
||||
col_x = (i-1)*2 + 1;
|
||||
col_y = (i-1)*2 + 2;
|
||||
|
||||
% Extract data
|
||||
if col_y > size(raw_data, 2)
|
||||
warning('Data columns missing for dataset %d', i);
|
||||
break;
|
||||
end
|
||||
|
||||
X = raw_data(:, col_x);
|
||||
Y = raw_data(:, col_y);
|
||||
|
||||
|
||||
|
||||
% Remove NaNs (missing data due to unequal lengths)
|
||||
valid_mask = ~isnan(X) & ~isnan(Y);
|
||||
X = X(valid_mask);
|
||||
Y = Y(valid_mask);
|
||||
|
||||
[X, sortIdx] = sort(X);
|
||||
Y = Y(sortIdx);
|
||||
|
||||
% 3. Smooth the Data
|
||||
|
||||
if numel(X) > 20
|
||||
if 1
|
||||
Y = smoothdata(Y, 'sgolay', 15);
|
||||
else
|
||||
Y = movmean(Y, 15);
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
% Plotting
|
||||
% Using semilogy because scattering data often spans orders of magnitude
|
||||
% (Adjust to 'plot' if linear scale is preferred)
|
||||
p = plot(ax, X, Y, ...
|
||||
'LineStyle', line_styles{mod(i-1, length(line_styles)) + 1}, ...
|
||||
'Marker', 'none', ...
|
||||
'Color', 'black', ...
|
||||
'LineWidth', 1.5, ...
|
||||
'MarkerSize', 6, ...
|
||||
'DisplayName', dataset_names{i});
|
||||
|
||||
% Optional: Fill marker faces for better visibility
|
||||
% p.MarkerFaceColor = p.Color;
|
||||
% p.MarkerFaceAlpha = 0.3; % Semi-transparent fill
|
||||
end
|
||||
|
||||
% --- 4. Styling and Formatting ---
|
||||
|
||||
% Axis Labels (Inferred from typical scattering plots)
|
||||
xlabel(ax, 'Wavelength (\mu m)', 'FontSize', 12, 'FontWeight', 'bold');
|
||||
ylabel(ax, 'Intensity / Cross-Section (a.u.)', 'FontSize', 12, 'FontWeight', 'bold');
|
||||
|
||||
% Title
|
||||
title(ax, 'Dataset Comparison', 'FontSize', 14);
|
||||
|
||||
% Legend
|
||||
legend(ax, 'Location', 'best', 'Interpreter', 'none', 'Box', 'on');
|
||||
|
||||
% Grid
|
||||
grid(ax, 'on');
|
||||
ax.GridAlpha = 0.3;
|
||||
ax.MinorGridAlpha = 0.1;
|
||||
|
||||
% Set Log Scale for Y (likely required for this data type)
|
||||
set(ax, 'YScale', 'log');
|
||||
|
||||
% Enhance axis appearance
|
||||
set(ax, 'Box', 'on', 'LineWidth', 1.2, 'FontSize', 10);
|
||||
|
||||
hold(ax, 'off');
|
||||
end
|
||||
@@ -1,189 +0,0 @@
|
||||
Rayleigh,,Experimental,,Infrared Absorption,
|
||||
X,Y,X,Y,X,Y
|
||||
0.7066005680911753,3.651009696525016,0.7072188355785799,4.848577786727532,1.4943918372804705,0.009324755400827079
|
||||
0.7362740977034739,3.1008424465551374,0.7104385926007812,5.059236053617898,1.5870823136443164,0.04795688074913024
|
||||
0.7704634954089999,2.559836201011587,0.7143024334187478,5.3165954733738054,1.6443739975494367,0.12666181795273013
|
||||
0.8246453070916075,1.9963763545469397,0.7194723146571098,4.679249634272495,1.6900695253042852,0.3029389206853443
|
||||
0.8846384359818439,1.4197559292837703,0.7194729766137344,4.646181068667172,1.7344762235109785,0.7194296259968607
|
||||
0.9375334039861705,1.0762856922437043,0.7227053108118038,4.236869693191961,1.7975573800551148,2.1896107578891244
|
||||
0.9929980876073115,0.9010620061822204,0.7272205169484065,4.147543538340177,,
|
||||
1.0420225952274251,0.6977835411732736,0.7291487965959542,4.420849736815974,,
|
||||
1.0845923638007697,0.5842349714248559,0.7310784001567514,4.645798669234298,,
|
||||
1.129741777340298,0.4856980392071641,0.7355902965102309,4.71201487210429,,
|
||||
1.1981066716622326,0.3841608204561696,0.738821306795051,4.358286713153517,,
|
||||
1.24841405122088,0.31935666463679646,0.7414069093708566,4.059822180897163,,
|
||||
1.289688370679823,0.2850148847474179,0.742705668268381,3.676053825899206,,
|
||||
1.3541801567910463,0.23691184007300667,0.7440031032526563,3.376112267508452,,
|
||||
1.4083573347772815,0.19416797258075097,0.7452965664971838,3.235432943532804,,
|
||||
1.4618851333147547,0.16723647350379714,0.7459426361628229,3.1898499103097238,,
|
||||
1.50315548103395,0.15574103754742674,0.7549743723492774,3.0137121806723157,,
|
||||
1.5386251028515106,0.1419883611511702,0.7620678995388148,2.971117042589562,,
|
||||
1.596665459699088,0.12316075278891304,0.765291628300764,2.971049114206588,,
|
||||
1.6437444767994136,0.10759838849626362,0.7756075603390012,2.9708317538173317,,
|
||||
1.683725994970454,0.09949510555249974,0.7762523060913911,2.9708181693210105,,
|
||||
1.717258069747722,0.09398483395032568,0.7839919029465676,2.8875658983600925,,
|
||||
1.7636903552257834,0.08387517688001396,0.7885090949530442,2.767180560538318,,
|
||||
1.7940013490676008,0.07701567091052414,0.7917348095848672,2.7088647150205,,
|
||||
,,0.7936723566251598,2.6144535948583694,,
|
||||
,,0.7962546494178423,2.5233214143921474,,
|
||||
,,0.8085087904529968,2.417989089048743,,
|
||||
,,0.8104423657535417,2.435165393892523,,
|
||||
,,0.8201175237791369,2.3335556930105406,,
|
||||
,,0.8285065000830756,2.158298098247211,,
|
||||
,,0.8317335386281479,2.083056634772393,,
|
||||
,,0.8356046609689853,2.024737963659226,,
|
||||
,,0.8407639509013534,1.996148150112612,,
|
||||
,,0.8459232408337212,1.967962031984024,,
|
||||
,,0.854951005280428,1.9401206794865944,,
|
||||
,,0.8601116191260452,1.8857864945455538,,
|
||||
,,0.8691446792257491,1.7565635929668848,,
|
||||
,,0.8743052930713663,1.7073700288086895,,
|
||||
,,0.8788211611645935,1.6595617469926904,,
|
||||
,,0.8826916215488064,1.624580544751916,,
|
||||
,,0.8891397410293294,1.6130257674984603,,
|
||||
,,0.896234592132116,1.5678305544227285,,
|
||||
,,0.903974850943917,1.5131252291764425,,
|
||||
,,0.90784531132813,1.4812307005435945,,
|
||||
,,0.9155829223134326,1.470682044636039,,
|
||||
,,0.9220303798373308,1.4706147972609174,,
|
||||
,,0.9310574823274131,1.460128389693264,,
|
||||
,,0.9349259568417521,1.4600883304432553,,
|
||||
,,0.9433056657529459,1.4913980336424177,,
|
||||
,,0.9516853746641398,1.5233791328756299,,
|
||||
,,0.956844002639883,1.512557980118849,,
|
||||
,,0.9671632444612435,1.4597545460975296,,
|
||||
,,0.9710370146285795,1.379199997932108,,
|
||||
,,0.9736206313345113,1.3123773159521164,,
|
||||
,,0.9774937395452226,1.2487807938448074,,
|
||||
,,0.9826543533908398,1.213807976266501,,
|
||||
,,0.9903926263327669,1.1966468122906808,,
|
||||
,,0.9942630867169798,1.171423198750918,,
|
||||
,,1.0045796807118417,1.1630595787371243,,
|
||||
,,1.0097376467309604,1.163017033545686,,
|
||||
,,1.0219851681998686,1.1963787227370668,,
|
||||
,,1.0290753856062829,1.2220446908209617,,
|
||||
,,1.0348774354211667,1.2306917801168409,,
|
||||
,,1.0471421677623152,1.052809309517664,,
|
||||
,,1.0510159379296513,0.9947114748787712,,
|
||||
,,1.0445565651865096,1.1302083245776995,,
|
||||
,,1.0458487045177878,1.0985863367418764,,
|
||||
,,1.0542449623445975,0.9398239868494617,,
|
||||
,,1.0613444471437565,0.8692481092753317,,
|
||||
,,1.0690886776953055,0.8039684355922487,,
|
||||
,,1.0768322462902296,0.7488836107091129,,
|
||||
,,1.0800586228786773,0.7279206840193796,,
|
||||
,,1.0858633205200596,0.7125673758820761,,
|
||||
,,1.1013418522737881,0.677981252075927,,
|
||||
,,1.105210326788127,0.6779626513688453,,
|
||||
,,1.1193973811672016,0.6589337368401503,,
|
||||
,,1.1206888585418553,0.6450561487842132,,
|
||||
,,1.123272475247787,0.613802971613336,,
|
||||
,,1.129077834845794,0.5966103416145675,,
|
||||
,,1.1335910551125228,0.5965912453535225,,
|
||||
,,1.1413266802279516,0.6050805792103379,,
|
||||
,,1.147134687652457,0.5716821968068484,,
|
||||
,,1.1581006610960811,0.5401075330241505,,
|
||||
,,1.167774495208427,0.524964710284852,,
|
||||
,,1.17357786893656,0.521233298948351,,
|
||||
,,1.1890511050372914,0.5248855006959243,,
|
||||
,,1.1974327998183592,0.5248543002000403,,
|
||||
,,1.2051671010205385,0.5399272739697006,,
|
||||
,,1.2161264548979165,0.5475977747039503,,
|
||||
,,1.2225739124218147,0.5475727356323816,,
|
||||
,,1.2232186581742046,0.5475702317881956,,
|
||||
,,1.2257923455307669,0.5795255128326332,,
|
||||
,,1.2264284858470365,0.635494312878344,,
|
||||
,,1.2264218662807902,0.6822012488404363,,
|
||||
,,1.2322133247896798,0.7695840678419278,,
|
||||
,,1.2354304339853828,0.8261273126225834,,
|
||||
,,1.2386382757883407,0.9793976812064772,,
|
||||
,,1.2399224716401234,1.0365631680970249,,
|
||||
,,1.2405632456527655,1.0816189618908738,,
|
||||
,,1.2457119442791393,1.1944819289049535,,
|
||||
,,1.2508619668187624,1.3005429730851226,,
|
||||
,,1.2521488104970433,1.3379536598639075,,
|
||||
,,1.2586068593269357,1.1943726953174758,,
|
||||
,,1.2605516878900995,1.0662340854711274,,
|
||||
,,1.263782036218295,0.9932116176633944,,
|
||||
,,1.267659116168754,0.9057092045091463,,
|
||||
,,1.2721796179583538,0.8377104911187728,,
|
||||
,,1.277345527456968,0.7693377754021644,,
|
||||
,,1.2818653672899432,0.7166420946785479,,
|
||||
,,1.2954156193961235,0.639704291832398,,
|
||||
,,1.298640672071322,0.6306801565443763,,
|
||||
,,1.3018657247465204,0.6217833222901857,,
|
||||
,,1.3147579919678183,0.6396165438362177,,
|
||||
,,1.3179764250767705,0.6769403979817149,,
|
||||
,,1.3244132912946747,0.7582491296621654,,
|
||||
,,1.3295613279644238,0.8433295073010272,,
|
||||
,,1.336000180052202,0.9247376324361347,,
|
||||
,,1.3430738485430005,1.1278180580973283,,
|
||||
,,1.3449988184074253,1.2455302076050567,,
|
||||
,,1.3482112939067554,1.4050952527481475,,
|
||||
,,1.351423769406086,1.585102197634859,,
|
||||
,,1.3533487392705106,1.7505418140103943,,
|
||||
,,1.3565618767264658,1.9608478952847546,,
|
||||
,,1.3604177740649368,2.243642151072621,,
|
||||
,,1.3681421459177467,2.5671506730013776,,
|
||||
,,1.3720059867357133,2.6977396395227498,,
|
||||
,,1.3700631440424236,2.9583331848749403,,
|
||||
,,1.3745670969164077,3.267039328784058,,
|
||||
,,1.3758446732019438,3.711862721055264,,
|
||||
,,1.377124897313979,4.099294432098773,,
|
||||
,,1.381620906708467,4.929210899363566,,
|
||||
,,1.381610315402473,5.521521237053952,,
|
||||
,,1.382885243861511,6.453816707451638,,
|
||||
,,1.3828733286422676,7.332602493027707,,
|
||||
,,1.3835048352621646,8.450022001983974,,
|
||||
,,1.3847837354609505,9.465318121186383,,
|
||||
,,1.3892850405084358,10.753821633797266,,
|
||||
,,1.3950817946703227,11.46214012981349,,
|
||||
,,1.406041810504325,11.542823048802346,,
|
||||
,,1.4086254272102567,10.983569572223233,,
|
||||
,,1.4125144223799593,8.815541223987582,,
|
||||
,,1.4138145051907332,7.8697993951128655,,
|
||||
,,1.4164106990725327,6.544455667464655,,
|
||||
,,1.4170686839574151,5.678973743658009,,
|
||||
,,1.419664877839215,4.722584406045411,,
|
||||
,,1.422267691287261,3.6583795017467264,,
|
||||
,,1.4274475018749921,2.894876829955794,,
|
||||
,,1.4293982880477776,2.4244991059437035,,
|
||||
,,1.4319891862765801,2.133892660567146,,
|
||||
,,1.4365249130685465,1.6766244945281037,,
|
||||
,,1.442346821582169,1.3648832144532748,,
|
||||
,,1.44946086942707,1.0800176935856405,,
|
||||
,,1.4539886527395407,0.9239641429706197,,
|
||||
,,1.4617467843802068,0.7363233849854021,,
|
||||
,,1.4701536335130105,0.5623407795094862,,
|
||||
,,1.477900511891058,0.5055620724926202,,
|
||||
,,1.4856487141823544,0.44811473438788657,,
|
||||
,,1.4940482817922873,0.3699994982234866,,
|
||||
,,1.5005089784486785,0.32105511462339426,,
|
||||
,,1.5089019264923649,0.2845721176091456,,
|
||||
,,1.5166481429137875,0.2576601983353233,,
|
||||
,,1.5179396202884412,0.2522337011156551,,
|
||||
,,1.5359997828782272,0.23327413205434572,,
|
||||
,,1.5430966198508878,0.22196482072259285,,
|
||||
,,1.5469697280615993,0.21120862244291763,,
|
||||
,,1.5501980905199209,0.20097457800069773,,
|
||||
,,1.565674636403775,0.1953318790229525,,
|
||||
,,1.5688977032090996,0.19671762962317987,,
|
||||
,,1.5785662416684487,0.20236426842871638,,
|
||||
,,1.5837215598610688,0.2081796533603784,,
|
||||
,,1.5914545371499988,0.21721757235346942,,
|
||||
,,1.5991901622654274,0.22030852031094905,,
|
||||
,,1.6088620105078997,0.21873658192521878,,
|
||||
,,1.61208309144335,0.22502554836218797,,
|
||||
,,1.6262602164730557,0.2432590831170723,,
|
||||
,,1.626903638312196,0.2467330049135315,,
|
||||
,,1.6281904819904773,0.25383038758817866,,
|
||||
,,1.6410748057322797,0.28430548752659124,,
|
||||
,,1.660414530477476,0.29244621369149987,,
|
||||
,,1.6642816810785659,0.29661578287603696,,
|
||||
,,1.6707152375133467,0.34423590359793155,,
|
||||
,,1.6739290369259265,0.3828666146961718,,
|
||||
,,1.6758540067903511,0.4228270071256609,,
|
||||
,,1.690028483993558,0.4702407837690221,,
|
||||
,,1.6964732936909575,0.48374976893430716,,
|
||||
,,1.6996923887565347,0.5083600695634991,,
|
||||
,,1.7003318388559272,0.5380344919079171,,
|
||||
|
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