Changes from mwork PC.

PDP 2025

MPI analysis

new focus on database and SQL
This commit is contained in:
Silas Oettinghaus
2025-03-21 08:11:40 +01:00
parent 402e491506
commit 74066d0669
36 changed files with 2234 additions and 620 deletions

View File

@@ -24,7 +24,7 @@ classdef PAMmapper
obj.M = M;
obj.unipolar = unipolar;
obj.thresholds = obj.get_demodulation_thresholds();
obj.levels = obj.get_levels();
@@ -36,10 +36,10 @@ classdef PAMmapper
end
function out = map(obj,signal_in)
if isa(signal_in,'Signal')
signal_in.signal = obj.map_(signal_in.signal);
signal_in.signal = obj.map_(signal_in.signal);
% signal_in = signal_in.normalize("mode","rms");
lbdesc = ['Map bat stream to PAM ',num2str(obj.M),' symbols'];
signal_in = signal_in.logbookentry(lbdesc,obj);
@@ -47,19 +47,19 @@ classdef PAMmapper
else
out = signal_in;
end
end
function signal_out = demap(obj,signal_in)
issignalclass = 0;
if isa(signal_in,'Signal')
signalclass = signal_in;
signal_in = signal_in.signal;
issignalclass = 1;
signalclass = signal_in;
signal_in = signal_in.signal;
issignalclass = 1;
end
signal_out = obj.demap_(signal_in);
signal_out = obj.demap_(signal_in);
if issignalclass
lbdesc = ['Demap PAM ',num2str(obj.M),' symbols to bit stream'];
@@ -68,7 +68,7 @@ classdef PAMmapper
signal_in.signal = signal_out;
signal_out = signal_in;
end
end
function pam_sig = map_(obj,bitpattern)
@@ -89,7 +89,7 @@ classdef PAMmapper
% 4-ASK:
if ~obj.eth_style
pam_sig=2*bitpattern(:,1)+(bitpattern(:,1)==bitpattern(:,2));
if obj.unipolar==0
pam_sig=2*pam_sig-3;
end
@@ -100,15 +100,65 @@ classdef PAMmapper
pam_sig = pam_sig/sqrt(5);
case 6
m = 1;
if size(bitpattern,2)>size(bitpattern,1)
bitpattern = bitpattern'; %vector aufrecht stellen
end
% LUT based mapping
for k = 1:5:fix(length(bitpattern)/5)*5
pam_sig(m:m+1,1) = obj.thresholds(bin2dec(int2str(bitpattern(k:k+4)'))+1,:);
m = m+2;
if ~obj.eth_style
m = 1;
if size(bitpattern,2)>size(bitpattern,1)
bitpattern = bitpattern'; %vector aufrecht stellen
end
% LUT based mapping
for k = 1:5:fix(length(bitpattern)/5)*5
pam_sig(m:m+1,1) = obj.thresholds(bin2dec(int2str(bitpattern(k:k+4)'))+1,:);
m = m+2;
end
else
bitsPerSymbol = reshape(bitpattern,5,[]).'; % reorder 5 bits per symbol
normFactor = 1;
%====================32 QAM===================%
%=============================================%
% Coding %
% 01000 01001 |11001 11000 %
% | %
% 01010 01110 01100 |11100 11110 11010 %
% | %
% 01011 01111 01101 |11101 11111 11011 %
% --------------------|------------------- %
% 00011 00111 00101 |10101 10111 10011 %
% | %
% 00010 00110 00100 |10100 10110 10010 %
% | %
% 00000 00001 |10001 10000 %
%=============================================%
% modulate three LSB first in first Quadrant
% first bit inverts real part if 0
% second bit inverts imaginary part if 0
LSB_symbols = normFactor*(...
+(1+1i) *(bitsPerSymbol(:,3)==1 & bitsPerSymbol(:,4)==0 & bitsPerSymbol(:,5)==1)...
+(3+1i) *(bitsPerSymbol(:,3)==1 & bitsPerSymbol(:,4)==1 & bitsPerSymbol(:,5)==1)...
+(5+1i) *(bitsPerSymbol(:,3)==0 & bitsPerSymbol(:,4)==1 & bitsPerSymbol(:,5)==1)...
+(1+3i) *(bitsPerSymbol(:,3)==1 & bitsPerSymbol(:,4)==0 & bitsPerSymbol(:,5)==0)...
+(3+3i) *(bitsPerSymbol(:,3)==1 & bitsPerSymbol(:,4)==1 & bitsPerSymbol(:,5)==0)...
+(5+3i) *(bitsPerSymbol(:,3)==0 & bitsPerSymbol(:,4)==1 & bitsPerSymbol(:,5)==0)...
+(1+5i) *(bitsPerSymbol(:,3)==0 & bitsPerSymbol(:,4)==0 & bitsPerSymbol(:,5)==1)...
+(3+5i) *(bitsPerSymbol(:,3)==0 & bitsPerSymbol(:,4)==0 & bitsPerSymbol(:,5)==0));
Re = real(LSB_symbols);
Im = imag(LSB_symbols);
% if first bit== 0 => invert real part
% if second bit== 0 => invert imag part
modData2 = Re.*(bitsPerSymbol(:,1)*2-1) + 1i*Im.*(bitsPerSymbol(:,2)*2-1);
Re = real(modData2(1:end/2));
Im = imag(modData2(1:end/2));
pam_sig = zeros(length(Re)*2,1);
pam_sig(1:2:length(Re)*2) = Re;
pam_sig(2:2:length(Im)*2) = Im;
end
pam_sig = pam_sig/sqrt(10);
@@ -120,9 +170,9 @@ classdef PAMmapper
x1 = bitpattern(:,1);
x2 = (bitpattern(:,1)==bitpattern(:,3));
x3 = x2~=bitpattern(:,2);
pam_sig = 4*x1 + 2*x2 + x3;
if obj.unipolar==0
pam_sig=2*pam_sig-7;
end
@@ -133,7 +183,7 @@ classdef PAMmapper
end
pam_sig = pam_sig/sqrt(21);
case 16
% 16-ASK:
x1 = bitpattern(:,1);
@@ -167,7 +217,7 @@ classdef PAMmapper
% case 16
% thres = [-10 -8 -6 -4 -2 0 2 4 6 8 10];
% end
switch obj.M
@@ -190,12 +240,12 @@ classdef PAMmapper
thres = thres .* 1/sqrt(5);
case 6 %PAM 6
case 6 %PAM 6
thres = [-3 5;-1 5;-3 -5;-1 -5;-5 3;-5 1;-5 -3;-5 -1;-1 3;-1 1;-1 -3;-1 -1;-3 3;-3 1;-3 -3;-3 -1;3 5;1 5;3 -5;1 -5;5 3;5 1;5 -3;5 -1;1 3;1 1;1 -3;1 -1;3 3;3 1;3 -3;3 -1];
% thres = [-4 -2 0 2 4];
% thres = thres ./ sqrt(10);
case 8
% 8-ASK
if obj.unipolar==0
@@ -203,7 +253,7 @@ classdef PAMmapper
elseif obj.unipolar==1
thres=0.5:6.5;
end
thres=thres./sqrt(21);
case 16
@@ -234,23 +284,26 @@ classdef PAMmapper
end
function [data_out] = demap_(obj,data_in)
data_in= data_in';
if obj.M ~= 6
% create output
if ~isempty(obj.thresholds)
a = squeeze(repmat(real(data_in),[1 1 length(obj.thresholds)])); %Eingangssignal in 3 spalten
b = squeeze(repmat(reshape(obj.thresholds(:).',[1 1 length(obj.thresholds)]),[1 length(data_in) 1])); %Threshold in 3 Spalten
comp_real = a > b; %check for each symbol/ sampling if it exeeds the obj.thresholdseshold 1, 2 or 3
comp_real=repmat(real(data_in),[1 1 length(obj.thresholds)]) > repmat(reshape(obj.thresholds(:).',[1 1 length(obj.thresholds)]),[1 length(data_in) 1]);
else
comp_real=[];
end
s1=size(comp_real,1);
s2=size(comp_real,2);
end
switch obj.M
@@ -273,34 +326,70 @@ classdef PAMmapper
case 6
data_in = data_in/(sqrt(mean(abs(data_in).^2)));
data_in = data_in*sqrt(10);
if ~obj.eth_style
data_in = data_in/(sqrt(mean(abs(data_in).^2)));
data_in = data_in*sqrt(10);
if size(data_in,2) > 1
data_in = data_in.';
end
if length(data_in)/2 ~= round(length(data_in)/2)
data_in = [data_in;0];
end
m = 1;
for n = 1:2:length(data_in)
dist = sqrt((data_in(n)-obj.thresholds(:,1)).^2+(data_in(n+1)-obj.thresholds(:,2)).^2);
[~,dd_idx] = min(dist);
% dec_out(n:n+1) = LUT(dd_idx,:);
data_out(m:m+4) = bitget(dd_idx-1,5:-1:1);
m = m+5;
end
else
data_in= data_in';
rxSym = data_in(1:2:end) + 1i*data_in(2:2:end); % 16×1
% Decode the sign bits (bits 1 & 2).
rxBit1 = double(real(rxSym) > 0);
rxBit2 = double(imag(rxSym) > 0);
% Undo the quadrant inversion and normalization.
rxSym_corr = abs(real(rxSym)) + 1i*abs(imag(rxSym));
normFactor = 1/sqrt(10);
rxSym_unscaled = rxSym_corr / normFactor;
cand = [1+1i, 3+1i, 5+1i, 1+3i, 3+3i, 5+3i, 1+5i, 3+5i];
candBits = [1 0 1;
1 1 1;
0 1 1;
1 0 0;
1 1 0;
0 1 0;
0 0 1;
0 0 0];
d = abs(rxSym_unscaled - cand).^2; % 32×8 distances
[~, idx] = min(d, [], 2);
rxLSB = candBits(idx,:); % 32×3
decodedSymbols = [rxBit1, rxBit2, rxLSB];
data_out = reshape(decodedSymbols.', [], 1).';
if size(data_in,2) > 1
data_in = data_in.';
end
if length(data_in)/2 ~= round(length(data_in)/2)
data_in = [data_in;0];
end
m = 1;
for n = 1:2:length(data_in)
dist = sqrt((data_in(n)-obj.thresholds(:,1)).^2+(data_in(n+1)-obj.thresholds(:,2)).^2);
[~,dd_idx] = min(dist);
% dec_out(n:n+1) = LUT(dd_idx,:);
data_out(m:m+4) = bitget(dd_idx-1,5:-1:1);
m = m+5;
end
case 8
% 8-ASK
if ~obj.eth_style
data_out=[comp_real(:,:,4);
comp_real(:,:,1)-comp_real(:,:,3)+comp_real(:,:,5)-comp_real(:,:,7);
1-comp_real(:,:,2)+comp_real(:,:,6)];
data_out=[comp_real(:,:,4);
comp_real(:,:,1)-comp_real(:,:,3)+comp_real(:,:,5)-comp_real(:,:,7);
1-comp_real(:,:,2)+comp_real(:,:,6)];
else
data_out = [(data_in>=0); (abs(data_in)>(4/sqrt(21))); (abs(data_in)>=(2/sqrt(21)))&(abs(data_in)<=(6/sqrt(21)))];
end
@@ -324,21 +413,21 @@ classdef PAMmapper
data_in Signal
options.symbol_levels = []
end
%A) normally return the preproduct of the decision
a = squeeze(repmat(real(data_in.signal),[1 1 length(obj.thresholds)])); %Eingangssignal in 3 spalten
b = squeeze(repmat(reshape(obj.thresholds(:).',[1 1 length(obj.thresholds)]),[1 length(data_in.signal) 1])); %Threshold in 3 Spalten
comp_real = a > b; %check for each symbol/ sampling if it exeeds the obj.thresholdseshold 1, 2 or 3
data_out = data_in;
data_out.signal = sum(comp_real,2);
%Option: return the actual level values/ just map onto given
%symbol levels
if ~isempty(options.symbol_levels)
data_out.signal = options.symbol_levels(data_out.signal+1);
end
end
function [out] = separate_pamlevels(obj,data_in)
@@ -347,7 +436,7 @@ classdef PAMmapper
a = squeeze(repmat(real(data_in.signal),[1 1 length(obj.thresholds)])); %Eingangssignal in 3 spalten
b = squeeze(repmat(reshape(obj.thresholds(:).',[1 1 length(obj.thresholds)]),[1 length(data_in.signal) 1])); %Threshold in 3 Spalten
comp_real = a > b; %check for each symbol/ sampling if it exeeds the obj.thresholdseshold 1, 2 or 3
comp_real_sum = sum(comp_real,2);
comp_real_sum = sum(comp_real,2);
out = NaN(length(data_in),length(obj.thresholds)+1);
@@ -358,7 +447,7 @@ classdef PAMmapper
end
function [Signal_out] = quantize(obj,Signal_in)
constellation = obj.get_levels();
constellation = constellation ./ rms(constellation);
@@ -366,9 +455,9 @@ classdef PAMmapper
if isa(Signal_in,'Signal')
issignalclass = 1;
Sig_class = Signal_in;
Signal_in = Signal_in.signal;
Signal_in = Signal_in.signal;
end
[~,high_dim_sig] = max(size(Signal_in));
[~,high_dim_const] = max(size(constellation));
@@ -381,7 +470,7 @@ classdef PAMmapper
Signal_out = constellation(symbol_idx);
Signal_out = reshape(Signal_out,size(Signal_in));
if issignalclass
if issignalclass
Sig_class.signal = Signal_out;
Signal_out = Sig_class;
end
@@ -390,6 +479,10 @@ classdef PAMmapper
end
function bitmap = showBitMapping(obj)
bitmap = obj.demap([obj.levels ./ obj.scaling]');
end
end
end

View File

@@ -6,8 +6,10 @@ classdef Pulseformer
end
properties(Access=public)
fdac
fs
fsym
matched_sps
output_sps
pulse
pulselength
alpha
@@ -20,8 +22,10 @@ classdef Pulseformer
% Detailed explanation goes here
arguments
options.fdac double
options.fs double
options.fsym double
options.matched_sps double
options.output_sps double
options.pulse pulseform = pulseform.rc
options.pulselength double {mustBeInteger} = 32
options.alpha double = 0.05
@@ -50,7 +54,11 @@ classdef Pulseformer
signalclass_in = signalclass_in.logbookentry(lbdesc);
% write fs to signal
signalclass_in.fs = obj.fdac;%.* (obj.fdac./obj.fsym);
if obj.matched
signalclass_in.fs = obj.fsym .* obj.output_sps;%.* (obj.fdac./obj.fsym);
else
signalclass_in.fs = obj.fs;%.* (obj.fdac./obj.fsym);
end
% write to output
signalclass_out = signalclass_in;
@@ -77,15 +85,19 @@ classdef Pulseformer
data_out
end
if ~rem(obj.fdac,obj.fsym)
if ~isempty(obj.output_sps)
obj.fsym = obj.fsym.*obj.output_sps;
end
if ~rem(obj.fs,obj.fsym)
%ist ein Vielfaches
sps = obj.fdac / obj.fsym;
sps = obj.fs / obj.fsym;
p = sps;
q = 1;
else
%ist kein Vielfaches
p = obj.fsym / gcd(obj.fdac, obj.fsym); %upsampling p->->->
q = obj.fdac/ gcd(obj.fdac, obj.fsym); %downsampling <-q
p = obj.fsym / gcd(obj.fs, obj.fsym); %upsampling p->->->
q = obj.fs/ gcd(obj.fs, obj.fsym); %downsampling <-q
sps= q; %sps während dem pulse shaping
end
@@ -105,6 +117,7 @@ classdef Pulseformer
end
manual_cyclic_convolution = 0;
upsample_filter = 0;
upfirdn_convolution = 1;
if manual_cyclic_convolution
@@ -122,16 +135,28 @@ classdef Pulseformer
data_out=ifft( fft(symbolov.') .* repmat( H,size(data_in,1),1 ).' ).';
data_out = circshift(data_out,[0 -(obj.pulselength*sps)]);
if rem(obj.fdac,obj.fsym)
if rem(obj.fs,obj.fsym)
data_out = data_out(1:q:end);
end
end
if upsample_filter
data_out_ = upsample(data_in,p);
mfOutput = filter(h, 1, data_out_); % Matched filter output
figure()
hold on
stem(mfOutput(1:1000),'Marker','o','MarkerSize',1,'LineStyle','-','LineWidth',1);
stem(data_out_(1:1000),'Marker','o','MarkerSize',1,'LineStyle','-','LineWidth',1);
end
if upfirdn_convolution
%Apply Filter using Matlab build in fctn.
data_out_ = upfirdn(data_in,h,p,q);
%cut signal, which is longer due to fir filter