Many changes in DBHandler
new general processing structure just before splitting off the projects folder from this repo
This commit is contained in:
@@ -28,39 +28,39 @@ end
|
||||
[evm_total,evm_lvl] = calc_evm_(test_signal,reference_signal);
|
||||
|
||||
|
||||
function [evm_total,evm_lvl] = calc_evm_(test_signal,reference_signal)
|
||||
function [evm_total, evm_lvl] = calc_evm_(test_signal, reference_signal)
|
||||
% Validate input
|
||||
assert(length(test_signal) == length(reference_signal), "Sequence length does not match");
|
||||
|
||||
assert(length(test_signal) == length(reference_signal),"Sequence length does not match");
|
||||
% Calculate error vector
|
||||
error_vector = test_signal - reference_signal;
|
||||
|
||||
error_vector = (test_signal-reference_signal);
|
||||
% EVM (RMS) as percentage, per MathWorks definition
|
||||
evm_total = sqrt(sum(abs(error_vector).^2) / sum(abs(reference_signal).^2)) * 100;
|
||||
|
||||
%%% Overall EVM
|
||||
evm_total = rms(error_vector);
|
||||
|
||||
try
|
||||
%%% Per Level EVM
|
||||
% Per-level EVM
|
||||
k = unique(reference_signal);
|
||||
evm_lvl = NaN(1, length(k));
|
||||
for lvl = 1:length(k)
|
||||
lvl_errors = error_vector(reference_signal==k(lvl));
|
||||
evm_lvl(lvl) = rms(lvl_errors);
|
||||
idx = reference_signal == k(lvl);
|
||||
if any(idx)
|
||||
lvl_errors = error_vector(idx);
|
||||
lvl_refs = reference_signal(idx);
|
||||
evm_lvl(lvl) = sqrt(sum(abs(lvl_errors).^2) / sum(abs(lvl_refs).^2)) * 100;
|
||||
end
|
||||
end
|
||||
catch
|
||||
evm_lvl = NaN;
|
||||
warning('No EVM per level calculated')
|
||||
end
|
||||
|
||||
end
|
||||
function [data_,reference_]=trimseq(data,reference,skipstart,skip_end)
|
||||
|
||||
function [data_,reference_]=trimseq(data,reference,skipstart,skip_end)
|
||||
data_ = data(skipstart+1:end-skip_end,:);
|
||||
|
||||
data_ = data(skipstart+1:end-skip_end,:);
|
||||
delta_bits = length(reference) - length(data);
|
||||
|
||||
delta_bits = length(reference) - length(data);
|
||||
skip_end = delta_bits + skip_end;
|
||||
|
||||
skip_end = delta_bits + skip_end;
|
||||
reference_ = reference(skipstart+1:end-skip_end,:);
|
||||
|
||||
reference_ = reference(skipstart+1:end-skip_end,:);
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -25,34 +25,46 @@ end
|
||||
[test_signal,reference_signal]=trimseq(test_signal,reference_signal,options.skip_front,options.skip_end);
|
||||
|
||||
% CALC EVM
|
||||
[std_total,std_lvl] = calc_std_(test_signal,reference_signal);
|
||||
[std_total, std_lvl, nsd_lvl, d_min]= calc_std_(test_signal,reference_signal);
|
||||
std_lvl = nsd_lvl;
|
||||
|
||||
function [std_total, std_lvl, nsd_lvl, d_min] = calc_std_(test_signal, reference_signal)
|
||||
|
||||
% NSD (Normalized Standard Deviation) expresses the noise spread at each symbol level
|
||||
% relative to the minimum distance between levels. A low NSD means low error risk,
|
||||
% while NSD approaching 0.5 indicates a high chance of symbol errors due to noise.
|
||||
|
||||
function [std_total,std_lvl] = calc_std_(test_signal,reference_signal)
|
||||
|
||||
assert(length(test_signal) == length(reference_signal),"Sequence length does not match");
|
||||
|
||||
error_vector = (test_signal-reference_signal);
|
||||
|
||||
%%% Overall EVM
|
||||
std_total = std(test_signal);
|
||||
|
||||
test_signal = test_signal ./ rms(test_signal);
|
||||
|
||||
try
|
||||
%%% Per Level EVM
|
||||
% Ensure input is column vector
|
||||
test_signal = test_signal(:);
|
||||
reference_signal = reference_signal(:);
|
||||
|
||||
assert(length(test_signal) == length(reference_signal), "Sequence length does not match");
|
||||
|
||||
% Find unique levels and their minimum spacing
|
||||
k = unique(reference_signal);
|
||||
d_min = min(diff(k)); % Minimum distance between adjacent levels
|
||||
|
||||
% Normalize test signal to RMS=1 (if not already)
|
||||
test_signal = test_signal / rms(test_signal);
|
||||
|
||||
% Overall standard deviation (not normalized)
|
||||
std_total = std(test_signal);
|
||||
|
||||
% Per-level standard deviation and normalized std
|
||||
std_lvl = zeros(1, length(k));
|
||||
nsd_lvl = zeros(1, length(k));
|
||||
for lvl = 1:length(k)
|
||||
% lvl_errors = error_vector(reference_signal==k(lvl));
|
||||
std_lvl(lvl) = std(test_signal(reference_signal==k(lvl)));
|
||||
idx = reference_signal == k(lvl);
|
||||
if any(idx)
|
||||
std_lvl(lvl) = std(test_signal(idx));
|
||||
nsd_lvl(lvl) = std_lvl(lvl) / d_min;
|
||||
else
|
||||
std_lvl(lvl) = NaN;
|
||||
nsd_lvl(lvl) = NaN;
|
||||
end
|
||||
end
|
||||
catch
|
||||
std_lvl = NaN;
|
||||
warning('No EVM per level calculated')
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function [data_,reference_] = trimseq(data,reference,skipstart,skip_end)
|
||||
|
||||
data_ = data(skipstart+1:end-skip_end,:);
|
||||
|
||||
Reference in New Issue
Block a user