Files
imdd_silas/Classes/04_DSP/Coding/MRDS_coding.m

270 lines
8.0 KiB
Matlab

classdef MRDS_coding
%MRDS implementation according to:
% Optical Multi-Path Interference Mitigation for PAM4-IMDD Systems Using Balanced Coding
% Journal of Lightwave Technology; 2024
properties(Access=public)
blocklength
delta
end
methods (Access=public)
function obj = MRDS_coding(options)
%NAME Construct an instance of this class
% Detailed explanation goes here
arguments
options.blocklength = 8;
end
%
fn = fieldnames(options);
for n = 1:numel(fn)
try
obj.(fn{n}) = options.(fn{n});
end
end
end
function process(~)
error("MRDS_coding has no process function. Use .encode(signal) and .dc_remove(signal) and .decode(signal)");
end
function signalclass_out = encode(obj,signalclass_in)
data_in = signalclass_in.signal';
if mean(unique(data_in)) < 0.01 % --> check for bipolar
data_in = int32(data_in.*sqrt(5));
data_in = double(data_in);
else % unipolar
data_in = int32(data_in.*sqrt(5)*2-3); % make bipolar [-3, -1, 1, 3]
data_in = double(data_in);
end
data_out = obj.mrds_encoding(data_in, obj.blocklength);
data_out = data_out./sqrt(5); % normalized to Power=1
signalclass_in.signal = data_out';
% append to logbook
lbdesc = ['MRDS Coded'];
signalclass_in = signalclass_in.logbookentry(lbdesc);
% write to output
signalclass_out = signalclass_in;
end
function signalclass_out = decode(obj,signalclass_in)
data_in = signalclass_in.signal';
if mean(unique(data_in)) < 0.01 % --> check for bipolar
data_in = int32(data_in.*sqrt(5));
data_in = double(data_in);
else % unipolar
data_in = int32(data_in.*sqrt(5)*2-3); % make bipolar [-3, -1, 1, 3]
data_in = double(data_in);
end
data_oh = obj.oh_decider(data_in, obj.blocklength); % decider for overhead
data_out = obj.mrds_decoding(data_oh, obj.blocklength);
data_out = data_out./sqrt(5); % normalized to Power=1
signalclass_in.signal = data_out';
% append to logbook
lbdesc = ['MRDS Coded'];
signalclass_in = signalclass_in.logbookentry(lbdesc);
% write to output
signalclass_out = signalclass_in;
end
function signalclass_out = dc_remove(obj,signalclass_in,options)
arguments
obj
signalclass_in
options.oversampling_factor = 1;
end
signalclass_in.signal = obj.dcr(signalclass_in.signal, obj.blocklength, options.oversampling_factor);
% append to logbook
lbdesc = ['MRDS DC Removed'];
signalclass_in = signalclass_in.logbookentry(lbdesc);
% write to output
signalclass_out = signalclass_in;
end
end
methods (Access=private)
% Cant be seen from outside! So put all your functions here that can/
% shall not be called from outside
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Function 1 - encoding
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [data_out] = mrds_encoding(~,data_in, blocklength)
% data_in: bipolar PAM4 sequence with levels [-3, -1, 1, 3]
% with length power of two
% blocklength: power of two <= length of data_in
oh_length = log2(blocklength);
data_out = zeros(1,length(data_in)+length(data_in)/blocklength*oh_length);
l = 0;
for j = 1:blocklength:length(data_in)
data = data_in(j:j+blocklength-1);
z_N = zeros(1,blocklength); % RDS
z_rds = 0;
for i = 1:blocklength
z_rds = z_rds + data(i);
z_N(i) = z_rds;
end
z = z_rds/2; % find inversion point k
k = find(z_N == z);
[~, index] = min(abs(blocklength/2 - k));
k = k(index);
if isempty(k) == 1
k = blocklength;
end
if k == blocklength
overhead = ones(1,oh_length)*3;
else
overhead = (decimalToBinaryVector(k-1,log2(blocklength))-0.5)*6; % calculate OH
data(k+1:end) = data(k+1:end)*(-1); % invert
end
data_oh = [data overhead];
data_out(l*(blocklength+oh_length)+1:(l+1)*(blocklength+oh_length)) = data_oh;
l = l+1;
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Function 2 - decoding
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [data_out] = mrds_decoding(~,data_in, blocklength)
oh_length = log2(blocklength);
data_out = zeros(1,length(data_in)-length(data_in)/(blocklength+oh_length)*oh_length);
l = 1;
for j = 1:(blocklength+oh_length):length(data_in)
data = data_in(j:j+blocklength+oh_length-1);
overhead = data(blocklength+1:end)/6+0.5;
k = binaryVectorToDecimal(overhead)+1;
if k == blocklength
data = data(1:blocklength);
else
data = data(1:blocklength);
data(k+1:end) = data(k+1:end)*(-1); % invert
end
data_out(l:l+blocklength-1) = data;
l = l+blocklength;
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Function 3 - decider for overhead values
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [data_out] = oh_decider(~,data_in, blocklength)
oh_length = log2(blocklength);
threshold = 0;
data_out = data_in;
for j = 1:length(data_in)/(blocklength+oh_length)
for k = 1:oh_length
if data_in(j*blocklength+(j-1)*oh_length+k) >= threshold
data_out(j*blocklength+(j-1)*oh_length+k) = 3;
else
data_out(j*blocklength+(j-1)*oh_length+k) = -3;
end
end
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Function 4 - matched DC removal (DCR)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [data_out] = dcr(~,data_in, blocklength, oversampling_factor)
oh_length = log2(blocklength);
winlength = blocklength+oh_length;
if oversampling_factor > 1
winlength = winlength*oversampling_factor;
end
for j = 1:winlength:length(data_in)
try
data = data_in(j:j+winlength-1);
rmean = mean(data);
data_out(j:j+winlength-1) = data - rmean;
catch
if j+winlength > length(data_in)
data = data_in(j:length(data_in));
else
error('indice problem.')
end
rmean = mean(data);
data_out(j:length(data_in)) = data - rmean;
end
end
data_out = data_out';
end
end
end