добавь в этот код в конце построение усредненного ...
Criado em: 9 de dezembro de 2025
Respondido usando GPT-5.1 Thinking por Chat01
Criado em: 9 de dezembro de 2025
Respondido usando GPT-5.1 Thinking por Chat01
добавь в этот код в конце построение усредненного графика по всем 8 юзерам для всех 4 кривых clear all; %#ok<CLALL>
%%%%%%%%%%%%%%%%%%%%%%%%% Files parameters %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
channels_path = "../Resources/";
% addpath(channels_path+"SRS_signal")
% addpath(channels_path+"DMRS_signal")
% addpath(channels_path+"1ue_cylinder/1ue")
% addpath(channels_path+"8ue_planar/8ue_planar")
% addpath(channels_path+"8u")
% addpath(channels_path+"8UE_cyl_LOS")
addpath(channels_path+"8UE_planar_LOS")
% addpath(channels_path+"SRS_channel_nonuniform")
% addpath(channels_path+"DMRS_channel_nonuniform")
% Parameters for save file
save_mat = 0;
mkdir("MatResults")
save_filename = "MatResults/temp";
%%%%%%%%%%%%%%%%%%%%%%%%% Define scenario %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Simulation parameters
scenario.SNR_range=-10:2:2; % SNR, dB
scenario.N_scenarios = 20; % channel realization 1...140
scenario.N_seeds = 2; % seed 1...99 (ideally = 99, but time consuming)
ML_coef=0; % Some global parameters passed to simulator
% The first UE has always a power of 0 dB !!!
scenario.UE_power=[0 0 0 0 0 0 0 0]; % power ratio between users, dB
scenario.N_target_UE=8; % number of target users
% BS geometrical parameters
scenario.Nrx=64; % Number of antennas
% Signal parameters
scenario.RB_num=4; % 1,4, 16 - number of resource blocks (frequency band)
scenario.RB_size=12;
scenario.N_TTI=1; % number of TTIs (1 TTI = 14 symbols = 12 data + 2 pilot)
scenario.N_data_sym = 12;
scenario.QAM_order=4;
scenario.SC_FDMA=0;
scenario.ZC_root=1:20; % Zadoff-Chu root (high impact)
scenario.ZC_shift=zeros(1,24); % Zadoff-Chu shift (low impact)
scenario.comb=1; % comb location (0 - off, 1 - on)
scenario.int_comb=0; % comb location for interference (0 - off, 1 - on)
% Parameters for user split (interference on CE stage)
scenario.ideal_user_split = 1;
scenario.comb_split=1; % Allocate different users on different subcarriers
N_users = length(scenario.UE_power);
scenario.OC_code = ones(N_users,2);
tmp = 1:N_users; tmp = (mod(tmp,4) == 3) + (mod(tmp,4) == 0);
scenario.OC_code(find(tmp),2) = -1; % Orthogonal Cover Code
scenario.OC_code(scenario.N_target_UE+1:end,:) = 1; % no OCC for interf
% Channels parameters
scenario.corr_th=0.8; % correlation threshold
scenario.N_iter=1; % max N-of-iter to achieve the desired correlation
scenario.corr_flag=1; % 1 - high correlation, 0 - low correlation, 0<x<1 - no care
%%%%%%%%%%%%%%%%%%%%%%%%% Algorithms parameters %%%%%%%%%%%%%%%%%%%%%%%%%%%
% CE parameters
scenario.ideal_CE=1;
scenario.consider_interf_on_CE = 0;
PHY_param.max_N_peaks=8; % max N-of-peaks to compensate (4...12)
PHY_param.N_stop = 8; % max N-of-peaks to compensate (only for _PIC version)
scenario.interp_order=0;
% SRS beamspace parameters
scenario.beam_transform=1;
scenario.N_ports=16; % beam domain size
scenario.ideal_SRS = 1;
scenario.SRS_delay = 0; % Use SRS or DMRS for beamspace estimation
scenario.beamspace_mode = 2; % -1 SVD, 2 DFT, 3 TFFT
% General detector parameters
scenario.RB_num_Ruu=4; % number of resource blocks to estimate Ruu
scenario.alpha = 1;
%%%%%%%%%%%%%%%%%%%%%%%%% Define channels %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Calculate channel indices for the simulation
if length(scenario.UE_power)>1 && scenario.N_iter>1
scenario.precalculated_indices = precalculate_indices(scenario);
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%% VALIDATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
default_scenario = scenario; % To backup scenario after adjustment
description = {}; % What each calculated curve means in legend and save_file
curve_id = 0;
%
curve_id = curve_id+1;
description{curve_id} = "antenna domain"; % Use this as label for curve
scenario.beam_transform=0;
BER_skoltech{curve_id} = scenarios_validation(scenario, ML_coef);
scenario = default_scenario;
curve_id = curve_id+1;
description{curve_id} = "beam domain 16 SVD"; % Use this as label for curve
scenario.beamspace_mode=-1;
scenario.N_ports=16;
BER_skoltech{curve_id} = scenarios_validation(scenario, ML_coef);
scenario = default_scenario;
curve_id = curve_id+1;
description{curve_id} = "beam domain 16 FFT"; % Use this as label for curve
scenario.beamspace_mode=2;
scenario.N_ports=16;
BER_skoltech{curve_id} = scenarios_validation(scenario, ML_coef);
scenario = default_scenario;
curve_id = curve_id+1;
description{curve_id} = "beam domain 16 TFFT"; % Use this as label for curve
scenario.beamspace_mode=3;
scenario.N_ports=16;
BER_skoltech{curve_id} = scenarios_validation(scenario, ML_coef);
scenario = default_scenario;
if save_mat; save(save_filename); end
%% %%%%%%%%%%%%%%%%%%% PLOT target UEs performance %%%%%%%%%%%%%%%%%%%%%%%%
% Define styles for curves
descriptors = ["r-",... % 1
"k-",... % 2
"b-",... % 3
"k-",... % 4
"m-",... % 5
"r-",... % 6
];
%%
SNR_range = scenario.SNR_range;
if length(SNR_range) > 1
for i=1:scenario.N_target_UE
textfigure(i); p = []; for j = 1:numel(BER_skoltech) if scenario.N_target_UE>1 BER = BER_skoltech{j}(i,:); else BER = BER_skoltech{j}; end p_ = semilogy(SNR_range, BER, descriptors(j),'LineWidth',2); p = [p p_]; if j == 1 hold on; grid on; grid minor; set(gca,'fontsize', 14); xlabel('SNR, dB'); xticks(SNR_range); ylabel('BER'); end end axis([SNR_range(1) SNR_range(length(SNR_range)) 10^-2 1]); UEs_info = num2str(scenario.N_target_UE) + " targets, "+num2str(numel(scenario.UE_power) - scenario.N_target_UE)+" interference, I/N=30dB, "; title(UEs_info+"User"+num2str(i)+", "+num2str(scenario.Nrx)+"RX, "+num2str(scenario.N_ports)+"beams (real SRS estimator), "+num2str(scenario.RB_num)+"RB, QAM"+num2str(2^scenario.QAM_order)); legend(p, description) legend('Location', 'southwest'); end
end
% function for VALIDATION
function sum_error = scenarios_validation(scenario, ML_coef)
textN_scenarios=scenario.N_scenarios; N_seeds=scenario.N_seeds; N_target_UE=scenario.N_target_UE; scen=scenario; n_SNR = numel(scen.SNR_range); ber=zeros(N_scenarios*N_seeds, N_target_UE, n_SNR); mse=zeros(N_scenarios*N_seeds, N_target_UE, n_SNR); for j=0:(N_scenarios*N_seeds)-1 scen.seed=rem(j,N_seeds)+1; scen.index = fix(j/N_seeds)+1; s(j+1)=scen; %#ok<AGROW> end parfor j=1:(N_scenarios*N_seeds) sys=struct(s(j)); sys.N_user=length(sys.UE_power); % number of all users in scenario seed = 100*sys.seed+10000*sys.index; rng(seed); channels = struct; [channels.h_pilot, channels.h_data, channels.h_srs] = get_channel(sys); % read channel if isnan(channels.h_pilot) for i = 1:n_SNR % Do not vectorize, otherwise parfor error ber(j,:,i) = NaN; mse(j,:,i) = NaN; end continue end SNR_range = sys.SNR_range; for i = 1:n_SNR sys.SNR = SNR_range(i); [ber(j,:,i),mse(j,:,i)]=tester_det_dec_beams_SCFDMA_MU(sys, ML_coef, channels); end end err_scen=squeeze(mean(ber,1,'omitnan')); mse_scen=squeeze(mean(mse,1,'omitnan')); disp("BER:") disp(err_scen); disp("MSE after detector:") disp(mse_scen); sum_error = err_scen;
end
Добавь в самый конец (после цикла for i=1:scenario.N_target_UE ... end) вот этот блок кода — он построит усреднённый по всем 8 пользователям график для всех 4 кривых:
matlab%% %%%%%%%%%%%%%%%%%%% PLOT average over all target UEs %%%%%%%%%%%%%%%%%%% figure(scenario.N_target_UE+1); % новая фигура (можно любое другое число) p = []; for j = 1:numel(BER_skoltech) if scenario.N_target_UE > 1 % Среднее по всем целевым пользователям (1..N_target_UE) BER_mean = mean(BER_skoltech{j}(1:scenario.N_target_UE, :), 1, 'omitnan'); else % Если целевой пользователь один, просто берём исходную кривую BER_mean = BER_skoltech{j}; end p_ = semilogy(SNR_range, BER_mean, descriptors(j), 'LineWidth', 2); p = [p p_]; %#ok<AGROW> if j == 1 hold on; grid on; grid minor; set(gca,'fontsize', 14); xlabel('SNR, dB'); xticks(SNR_range); ylabel('BER'); end end axis([SNR_range(1) SNR_range(end) 10^-2 1]); UEs_info = num2str(scenario.N_target_UE) + " targets, " + ... num2str(numel(scenario.UE_power) - scenario.N_target_UE) + ... " interference, I/N=30dB, "; title(UEs_info + "Average over " + num2str(scenario.N_target_UE) + ... " users, " + num2str(scenario.Nrx) + "RX, " + ... num2str(scenario.N_ports) + "beams (real SRS estimator), " + ... num2str(scenario.RB_num) + "RB, QAM" + num2str(2^scenario.QAM_order)); legend(p, description); legend('Location', 'southwest');
Этот блок:
j берёт матрицу BER_skoltech{j} размера N_target_UE × N_SNR.mean(...,1,'omitnan')).descriptors и теми же подписями легенды description.