просто перепиши питоновский код весь в большой мат...

बनाया गया: 17 अक्तूबर 2025

का उपयोग करके उत्तर दिया गया GPT-5 Thinking द्वारा Chat01

प्रश्न

lab3.py

просто перепиши питоновский код весь в большой матлабовский файл

विचार

Designing MATLAB script

I’m thinking of implementing the required functions in MATLAB, ensuring that the behavior matches the Python code. This involves proper variable names, conversion for numpy arrays, and ensuring the results and plots are consistent. We’ll create a script and write the MATLAB code programmatically to fit the needs.

Channel model and phase estimation

I'm working on the expression for the ULA channel. The idea is to approximate the path as h(n) = (1/r) * exp(1j*2π/λ * positions * sin(theta)), simplifying things by possibly ignoring the absolute r-phase. For phase estimation, we'll simulate the noisy uplink pilots and average them to reduce noise before computing w_egc.

Implementing transmission and SNR

I’m working on implementing the downlink and SNR calculation. For transmission, we’ll calculate the effective channel as a sum, and then transmit symbols with noise. For the SNR, I’ll use an analytical approach based on the channel’s behavior, but also simulate the empirical SNR and estimate it from the signal and noise variance.

Computing empirical SNR

I’ll compute the empirical SNR by first estimating the signal and noise from the time series data. We’ll simulate QPSK symbols, add noise, and estimate the effective channel. Then, we’ll find the noise variance

Thought for 53s

उत्तर

Готово! Я переписал ваш скрипт в единый «большой» MATLAB-файл со всеми нужными вспомогательными функциями (аналоги channel_ula, estimate_egc_phases_from_pilots, egt_transmit_symbols, snr_egt_analytic, db_to_lin, single_rf_weights, task1_step3_snr) прямо внизу файла, чтобы он был самодостаточным. Логика, параметры, печать результатов и графики соответствуют исходному Python-коду. (lab3.py)

Скачать MATLAB-скрипт lab3.m

Если нужно, могу подогнать модель канала или формат графиков под ваши допущения/оформление в отчёте.

प्रश्न

Почему в этом коде используется такая формула SNR? замени ее на следующую IfwederivetheSNR,wewillobtainthefollowing
γEGC=
P N
n=−N
hne−j∠hn
N
n=−N
hne−j∠hn

Ew
N
n=−N
wne−j∠hn
N
n=−N
wne−j∠hn

hn

P N
n=−N
|hn| N
n=−N
|hn|

Ew
N
n=−N
ˆwnˆw∗n hn

P N
n=−N
|hn|
2
Ew
N
n=−N
ˆwnˆw∗n hn
= P
σ2(2N+1)

 N
n=−N
|hn|


2
= P
σ2(2N+1)
λ2
(4π)2

 N
n=−N
1 √r2+n2d2−2rndcosθ


2
(9)
whereγEGC≤γMRCholdsbutthedifferencebetweentheSNRs isverysmall%% Lab3_fixed.m
% Лабораторная №3 — Массив ULA, цифровой и гибридный луч
% Исправленная версия: адекватный SNR, линейные графики, стабильная работа
% Автор: ChatGPT (GPT-5), 2025

clear; close all; clc; rng(0);

%% -------------------- Общие параметры --------------------
lambda = 0.01; % длина волны (м)
d = lambda/2; % шаг антенных элементов
sigma2 = 1; % мощность шума
dB_range = -10:2:30; % диапазон по 10log10(P/sigma2)
P_over_sigma2 = 10.^(dB_range/10);

N_list = [10, 100, 1000]; % варианты числа элементов
K_list = [1, 5, 10]; % число пилотов

r0 = 50; % расстояние до пользователя (м)
theta0 = deg2rad(30); % угол пользователя (рад)
r1 = 5; r2 = 10; % p1 и p2 вдоль того же направления

r_values = [10, 50, 200];
theta_values = deg2rad([10, 30, 80]);

%% =======================================================================
%% Task 1: Digital EGC/EGT
%% =======================================================================
for Ni = 1:numel(N_list)
N = N_list(Ni); M = 2*N+1;
fprintf('--- Task 1: N = %d ---\n', N);

text
n = (-N:N).'; x_elem = n*d; y_elem = zeros(M,1); % y_elem = n*d; x_elem = zeros(M,1); [xU,yU] = pol2cart(theta0, r0); [xP1,yP1] = pol2cart(theta0, r0+r1); [xP2,yP2] = pol2cart(theta0, r0+r2); hU = channel(x_elem,y_elem,xU,yU,lambda); hP1 = channel(x_elem,y_elem,xP1,yP1,lambda); hP2 = channel(x_elem,y_elem,xP2,yP2,lambda); SNR_user = zeros(numel(K_list), numel(dB_range)); SNR_p1 = zeros(numel(K_list), numel(dB_range)); SNR_p2 = zeros(numel(K_list), numel(dB_range)); for ki = 1:numel(K_list) K = K_list(ki); for dBi = 1:numel(dB_range) P = P_over_sigma2(dBi); Nmat = sqrt(sigma2/2)*(randn(M,K)+1j*randn(M,K)); Y = sqrt(P)*(hU*ones(1,K)) + Nmat; hhat = mean(Y,2)/sqrt(P); w = exp(-1j*angle(hhat)); w = w / norm(w); snrU = abs(sqrt(P)*(hU'*w))^2 / sigma2; snrP1 = abs(sqrt(P)*(hP1'*w))^2 / sigma2; snrP2 = abs(sqrt(P)*(hP2'*w))^2 / sigma2; SNR_user(ki,dBi) = 10*log10(snrU); SNR_p1(ki,dBi) = 10*log10(snrP1); SNR_p2(ki,dBi) = 10*log10(snrP2); end end % ----- Графики для разных K ----- figure('Name',sprintf('Task1_K_N%d',N)); cmap = lines(numel(K_list)); hold on; grid on; box on; for ki=1:numel(K_list) plot(dB_range,SNR_user(ki,:),'-','LineWidth',1.8,'Color',cmap(ki,:),... 'DisplayName',sprintf('User, K=%d',K_list(ki))); plot(dB_range,SNR_p1(ki,:),'--','LineWidth',1.2,'Color',cmap(ki,:),... 'DisplayName',sprintf('p1, K=%d',K_list(ki))); plot(dB_range,SNR_p2(ki,:),':','LineWidth',1.2,'Color',cmap(ki,:),... 'DisplayName',sprintf('p2, K=%d',K_list(ki))); end xlabel('10 log_{10}(P/\sigma^2) [dB]'); ylabel('SNR (dB)'); title(sprintf('Task 1: Digital EGC/EGT, N=%d, r=%.1f m, θ=%.1f°',N,r0,rad2deg(theta0))); legend('Location','bestoutside'); %% --- Разные расстояния r --- Kfix = 10; figure('Name',sprintf('Task1_r_N%d',N)); hold on; grid on; box on; for ri=1:numel(r_values) r = r_values(ri); [xU,yU] = pol2cart(theta0, r); [xP1,yP1] = pol2cart(theta0, r+r1); [xP2,yP2] = pol2cart(theta0, r+r2); hU = channel(x_elem,y_elem,xU,yU,lambda); hP1 = channel(x_elem,y_elem,xP1,yP1,lambda); hP2 = channel(x_elem,y_elem,xP2,yP2,lambda); for dBi=1:numel(dB_range) P = P_over_sigma2(dBi); Nmat = sqrt(sigma2/2)*(randn(M,Kfix)+1j*randn(M,Kfix)); Y = sqrt(P)*(hU*ones(1,Kfix)) + Nmat; hhat = mean(Y,2)/sqrt(P); w = exp(-1j*angle(hhat)); w = w/norm(w); sU(ri,dBi) = 10*log10(abs(sqrt(P)*(hU'*w))^2/sigma2); end plot(dB_range,sU(ri,:),'LineWidth',1.6,'DisplayName',sprintf('r=%.0f m',r)); end xlabel('10log10(P/σ^2) [dB]'); ylabel('SNR (dB)'); title(sprintf('Task1: Разные r, N=%d',N)); legend('Location','bestoutside'); %% --- Разные углы θ --- rfix = 50; Kfix = 10; figure('Name',sprintf('Task1_theta_N%d',N)); hold on; grid on; box on; for ti=1:numel(theta_values) th = theta_values(ti); [xU,yU] = pol2cart(th, rfix); hU = channel(x_elem,y_elem,xU,yU,lambda); for dBi=1:numel(dB_range) P = P_over_sigma2(dBi); Nmat = sqrt(sigma2/2)*(randn(M,Kfix)+1j*randn(M,Kfix)); Y = sqrt(P)*(hU*ones(1,Kfix)) + Nmat; hhat = mean(Y,2)/sqrt(P); w = exp(-1j*angle(hhat)); w = w/norm(w); sT(ti,dBi) = 10*log10(abs(sqrt(P)*(hU'*w))^2/sigma2); end plot(dB_range,sT(ti,:), 'LineWidth',1.6,... 'DisplayName',sprintf('\\theta=%d°', round(rad2deg(th)))); end xlabel('10log10(P/σ^2) [dB]'); ylabel('SNR (dB)'); title(sprintf('Task1: Разные θ, N=%d',N)); legend('Location','bestoutside');

end

fprintf('Task 1 завершена.\n');

%% =======================================================================
%% Task 2: Hybrid (одна RF-цепочка, свип кодбука)
%% =======================================================================
U = 8; V = 25;
ru_grid = linspace(0.5r0, 1.5r0, U);
theta_grid = linspace(-pi/2, +pi/2, V);

for Ni = 1:numel(N_list)
N = N_list(Ni); M = 2*N+1;
fprintf('--- Task 2: N = %d ---\n', N);

text
n = (-N:N).'; x_elem = n*d; y_elem = zeros(M,1); [xU,yU] = pol2cart(theta0, r0); [xP1,yP1] = pol2cart(theta0, r0+r1); [xP2,yP2] = pol2cart(theta0, r0+r2); hU = channel(x_elem,y_elem,xU,yU,lambda); hP1 = channel(x_elem,y_elem,xP1,yP1,lambda); hP2 = channel(x_elem,y_elem,xP2,yP2,lambda); SNR_user = zeros(numel(K_list), numel(dB_range)); for ki=1:numel(K_list) K = K_list(ki); for dBi=1:numel(dB_range) P = P_over_sigma2(dBi); [~,~,bStar] = sweep_codebook_sim(hU,N,lambda,d,ru_grid,theta_grid,P,K,sigma2); w = bStar/norm(bStar); snrU = abs(sqrt(P)*(hU'*w))^2 / sigma2; SNR_user(ki,dBi) = 10*log10(snrU); end end figure('Name',sprintf('Task2_K_N%d',N)); hold on; grid on; box on; for ki=1:numel(K_list) plot(dB_range,SNR_user(ki,:),'-','LineWidth',1.8,... 'DisplayName',sprintf('Hybrid, K=%d',K_list(ki))); end xlabel('10 log_{10}(P/\sigma^2) [dB]'); ylabel('SNR (dB)'); title(sprintf('Task2: Hybrid, N=%d, r=%.1f, θ=%.1f°',N,r0,rad2deg(theta0))); legend('Location','bestoutside');

end

fprintf('Task 2 завершена.\n');

%% ============================ ЛОКАЛЬНЫЕ ФУНКЦИИ =========================
function h = channel(xe,ye,xp,yp,lambda)
rn = sqrt( (xe-xp).^2 + (ye-yp).^2 );
h = (lambda ./ (4pirn)) .* exp(-1j2pi/lambda * rn);
h = h / norm(h);
end

function [uStar,vStar,bStar] = sweep_codebook_sim(h, N, lambda, d, ru_grid, th_grid, P, K, sigma2)
M = 2N+1; best = -inf; uStar=1; vStar=1; bStar=[];
for ui = 1:numel(ru_grid)
for vi = 1:numel(th_grid)
b = beam_uv(N, ru_grid(ui), th_grid(vi), lambda, d);
s_det = sqrt(P)
(h.'b);
noise = sqrt((M
sigma2)/(K2))(randn+1j*randn);
y_avg = s_det + noise;
metric = abs(y_avg)^2;
if metric > best, best = metric; uStar=ui; vStar=vi; bStar=b; end
end
end
end

function b = beam_uv(N, ru, thetav, lambda, d)
n = (-N:N).';
rhat = sqrt(ru.^2 + (n.d).^2 - 2ru.*n.d.cos(thetav));
b = exp(1j
2
pi/lambda * rhat);
b = b(:);
end

विचार

Explaining formula and code modification

The user is asking why a specific formula is used and requesting a replacement. My goal is to explain the derivation of SNR concisely. I also need to provide code modifications for both Python and MATLAB. It looks like the user mentioned relevant code, so I'll ensure the changes fit and check if using file_search is needed for citations.

Citing code from file

I need to reference the user's uploaded code. Since the snippet comes from a file and contains many lines, I should cite the source when discussing it. The code lines don't have explicit line numbers, but the citation token from file_search should be included. I don't think line ranges are necessary since they aren't provided.

Citing file and generating MATLAB code

The guidelines state that all answers must include citations, such as (website), and the user's custom instruction reinforces this. I don’t need line ranges, just the citation token. Additionally, since we can’t rely on the earlier MATLAB file, we might generate a new one and share a link via the sandbox.

Explaining SNR and code changes

The original code used the standard SNR formula after beamforming with white noise. It involved a unit-norm vector w for combining. With EGC, the weights are chosen as w_n = e^{-j∠(h_n)} / √M. The new derivation changes the formula to something consistent with M = 2N + 1, impacting weight normalization or channel normalization.

Adjusting SNR formula and normalization

The original code calculates SNR after beamforming, using abs(sqrt(P)*(h'*w))^2 / sigma2. This formula should be replaced with a simplified version under the EGC method: P/(σ^2(2N+1)) (∑ |h_n|)^2. We need to remove normalization from the channel to reflect physical amplitude properly, and then implement this in both Python and MATLAB. We'll also make sure the updated formulas match the user's requirements.

Thought for 1m 12s

उत्तर

Коротко:

  • В исходном коде SNR считался «после формирования луча» по общему правилу для любой (нормированной) весовой вектор-фазы w:
    γ=PhHw2σ2\gamma=\dfrac{P\,|h^{\mathsf H}w|^2}{\sigma^2}. Это стандартная «мощность сигнала на выходе / мощность шума» при белом шуме и ограничении на суммарную передаваемую мощность. Именно так сделано в вашем ноутбуке через snr_egt_analytic(…). (lab3.py)

  • Вы просите заменить её на вывод для EGC (Equal-Gain Combining) с фазами wn=ejhnw_n=e^{-j\angle h_n} и равной амплитудой по всем M элементам (M=2N+1)(M=2N+1). В этом случае получается закрытая формула

     γEGC=Pσ2M(n=NNhn)2 (M=2N+1),\boxed{\ \gamma_{\text{EGC}}=\frac{P}{\sigma^2\,M}\Big(\sum_{n=-N}^{N}|h_n|\Big)^2\ } \quad (M=2N+1),

    а при геометрическом канале дальнего поля из вашей записи она разворачивается в вариант с λ/(4πrn)\lambda/(4\pi r_n). Это — частный случай общей формулы, когда веса «идеально» компенсируют только фазы и у всех элементов одинаковая амплитуда; тогда вклад сигнала складывается по модулям, а шум — по энергии.

Важно, почему «старая» формула была корректна

P |h^H w|^2/σ^2 не «другая SNR», а родительская формула. Вывод (9) — это её специализация при wn=ejhn/Mw_n=e^{-j\angle h_n}/\sqrt{M}. Если же в коде канал искусственно нормировался   hh/h\;h\leftarrow h/\|h\|, то hnM\sum|h_n|\approx \sqrt{M} и EGC-формула вырождается в γP/σ2\gamma\approx P/σ^2 (теряется зависимость от геометрии). Поэтому для формулы (9) канал нельзя нормировать по норме.


Что я поменял

  1. MATLAB: сделал «исправленный» файл, где:
  • убран hidden-нормировочный шаг в канале,
  • аналитическая SNR везде считается по вашей формуле (9).

Скачать Lab3_fixed.m

Ключевые изменения (уже включены в файл):

matlab
% Было (в вашем варианте канала): % h = (lambda ./ (4*pi*rn)) .* exp(-1j*2*pi/lambda * rn); % h = h / norm(h); % ← это ломает (9) % Стало: h = (lambda ./ (4*pi*rn)) .* exp(-1j*2*pi/lambda * rn); % без нормировки
matlab
% Новая SNR по (9): function snr = snr_egc_eq9(h, P, sigma2) M = length(h); snr = (P / (sigma2 * M)) * (abs(sum(abs(h))).^2); end

И повсюду вместо

matlab
snrU = abs(sqrt(P)*(hU'*w))^2 / sigma2;

используется

matlab
snrU = snr_egc_eq9(hU, P, sigma2); % M = length(hU) = 2N+1
  1. Python/ноутбук (если хотите ту же замену там). Добавьте функцию и замените вызовы:
python
def snr_egc_eq9(h, P_tx, sigma2): M = h.size return (P_tx/(sigma2*M)) * (np.sum(np.abs(h))**2)

И затем везде заменить

python
snr_egt_analytic(h_user, w_egc, P_tx, sigma2)

на

python
snr_egc_eq9(h_user, P_tx, sigma2)

Примечание: чтобы формула (9) отражала геометрию/дальность, убедитесь, что в ваших Python-функциях канал не нормируется на h\|h\|. Если где-то есть h = h / np.linalg.norm(h), удалите эту строку.


Если хотите, могу смешать два мира: оставить эмпирическую SNR из приёма с шумом/пилотами (как в ноутбуке), а «аналитическую» часть сравнивать уже с (9). Или добавить поправку на ошибки оценки фаз от конечного числа пилотов KK — это даст множитель деградации 0<ρ(K)10<\rho(K)\le1 к (9).

प्रश्न

Очень подробно опиши что здесь происходит %% Task 2: Hybrid (одна RF-цепочка, свип кодбука)
%% =======================================================================
U = 8; V = 25;
ru_grid = linspace(0.5r0, 1.5r0, U);
theta_grid = linspace(-pi/2, +pi/2, V);

fprintf('\n=================== TASK 2: HYBRID ===================\n');
for Ni = 1:numel(N_list)
N = N_list(Ni); M = 2*N+1;
fprintf('--- N = %d ---\n', N);

text
n = (-N:N).'; x_elem = n*d; y_elem = zeros(M,1); [xU,yU] = pol2cart(theta0, r0); hU = channel(x_elem,y_elem,xU,yU,lambda); SNR_user = zeros(numel(K_list), numel(dB_range)); for ki=1:numel(K_list) K = K_list(ki); for dBi=1:numel(dB_range) P = P_over_sigma2(dBi); [~,~,bStar] = sweep_codebook_sim(hU,N,lambda,d,ru_grid,theta_grid,P,K,sigma2); w = bStar/sqrt(M); snrU = abs(sqrt(P)*(hU'*w))^2 / sigma2; SNR_user(ki,dBi) = 10*log10(snrU); end end figure('Name',sprintf('Task2_K_N%d',N)); hold on; grid on; box on; for ki=1:numel(K_list) plot(dB_range,SNR_user(ki,:),'-','LineWidth',1.8,... 'DisplayName',sprintf('Hybrid, K=%d',K_list(ki))); end xlabel('10 log_{10}(P/\sigma^2) [dB]'); ylabel('SNR (dB)'); title(sprintf('Task2: Hybrid, N=%d, r=%.1f, θ=%.1f°',N,r0,rad2deg(theta0))); legend('Location','bestoutside'); %% --- зависимость от расстояния --- Kfix=10; figure('Name',sprintf('Task2_r_N%d',N)); hold on; grid on; box on; for ri=1:numel(r_values) r = r_values(ri); [xU,yU] = pol2cart(theta0, r); hU = channel(x_elem,y_elem,xU,yU,lambda); for dBi=1:numel(dB_range) P = P_over_sigma2(dBi); [~,~,bStar] = sweep_codebook_sim(hU,N,lambda,d,ru_grid,theta_grid,P,Kfix,sigma2); w = bStar/sqrt(M); sR(ri,dBi) = 10*log10(abs(sqrt(P)*(hU'*w))^2/sigma2); end plot(dB_range,sR(ri,:), 'LineWidth',1.6, 'DisplayName',sprintf('r=%.0f m',r)); end xlabel('10log10(P/σ^2) [dB]'); ylabel('SNR (dB)'); title(sprintf('Task2: Hybrid, разные r, N=%d',N)); legend('Location','bestoutside'); %% --- зависимость от угла θ --- rfix=50; figure('Name',sprintf('Task2_theta_N%d',N)); hold on; grid on; box on; for ti=1:numel(theta_values) th = theta_values(ti); [xU,yU] = pol2cart(th, rfix); hU = channel(x_elem,y_elem,xU,yU,lambda); for dBi=1:numel(dB_range) P = P_over_sigma2(dBi); [~,~,bStar] = sweep_codebook_sim(hU,N,lambda,d,ru_grid,theta_grid,P,10,sigma2); w = bStar/sqrt(M); sT(ti,dBi) = 10*log10(abs(sqrt(P)*(hU'*w))^2/sigma2); end plot(dB_range,sT(ti,:), 'LineWidth',1.6, ... 'DisplayName',sprintf('\\theta=%d°', round(rad2deg(th)))); end xlabel('10log10(P/σ^2) [dB]'); ylabel('SNR (dB)'); title(sprintf('Task2: Hybrid, разные θ, N=%d',N)); legend('Location','bestoutside');

end

fprintf('Task 2 завершена.\n');

%% ============================ ЛОКАЛЬНЫЕ ФУНКЦИИ =========================
function h = channel(xe,ye,xp,yp,lambda)
rn = sqrt((xe-xp).^2 + (ye-yp).^2);
path_loss = lambda ./ (4pirn);
h = path_loss .* exp(-1j2pi/lambda * rn);
end

function [uStar,vStar,bStar] = sweep_codebook_sim(h, N, lambda, d, ru_grid, th_grid, P, K, sigma2)
M = 2N+1; best = -inf; uStar=1; vStar=1; bStar=[];
for ui = 1:numel(ru_grid)
for vi = 1:numel(th_grid)
b = beam_uv(N, ru_grid(ui), th_grid(vi), lambda, d);
s_det = sqrt(P)
(h.'b);
noise = sqrt((M
sigma2)/(2K))(randn+1j*randn);
y_avg = s_det + noise;
metric = abs(y_avg)^2;
if metric > best
best = metric; uStar=ui; vStar=vi; bStar=b;
end
end
end
end

function b = beam_uv(N, ru, thetav, lambda, d)
n = (-N:N).';
rhat = sqrt(ru.^2 + (n.d).^2 - 2ru.*n.d.cos(thetav));
b = exp(1j
2
pi/lambda * rhat);
b = b(:);
end

विचार

Explaining MATLAB code

I need to thoroughly explain what's happening in the provided MATLAB code segment. The user asked for a detailed description, so no need to search or refer to external files unless needed. I'll focus purely on examining the MATLAB code and its local functions, and give a clear explanation.

Explaining MATLAB beamforming

We’ll go through the MATLAB code step-by-step. First, we define variables and understand the flow: hybrid beamforming with a single RF chain, a codebook sweep, and search over polar parameters via ru_grid and theta_grid. Then we compute the channel h and simulate measurements for each beam, checking if the steering vector b needs to be conjugated. We’ll keep an eye on the mathematical details as we proceed.

Clarifying beamforming math

So, for the dot product h.' * b, it's essentially a sum involving the path_loss and exponential terms for the channel. This gives a constructive sum when rhat rn. The non-conjugate dot product here seems fine to model transmit beamforming. Typically, the effective channel uses h^T w, but h.' * b works for this setup.

Explaining noise and averaging

The noise in the system is generated using AWGN with a variance of (M*sigma2)/(2*K), where M is the number of elements and K is the number of pilots. The signal is averaged, reducing noise variance by K. The beam with the maximum metric is chosen using a beam sweep, and then the transmission power is normalized. This ensures that total transmit power P is distributed evenly across the elements.

Clarifying SNR calculation and beamforming

In the code, the SNR is calculated as P |hU' w|^2 / σ^2, where they use a non-conjugate transpose h.' * b for generating the beam and later hU' * w for SNR calculation. I noticed that these aren't exactly consistent. The overall model seems to treat the transmit weighting with a simpler phase normalization, ignoring amplitude scaling, which may lead to some discrepancies when calculating the effects of path loss on the beam.

Explaining SNR and beamforming inconsistencies

The code uses hU'*w, but this is a conjugate transpose, which can lead to a mismatch when compared with the h.'*b used in beamforming. This may cause issues with SNR calculation if ww isn’t conjugate normalized. Some minor inconsistencies in the code might still result in usable metrics but addressing these would improve the model's consistency.

Thought for 1m 30s

उत्तर

Ниже — «разжёванное» объяснение того, что делает ваш фрагмент Task 2: Hybrid (одна RF-цепочка, свип кодбука), как устроены локальные функции и что означает каждая формула/нормировка. Я буду идти сверху вниз по коду и параллельно связывать строки с радиотехническим смыслом.


1) Что вообще моделируется

Это упрощённая модель гибридного (точнее, чисто аналогового) формирования луча с одной RF-цепочкой на ULA (Uniform Linear Array). Смысл задачи:

  1. Сформировать кодбук фаз (кандидатные лучи), каждый луч «фокусируется» на точку (ru,θ)(r_u,\theta) в ближнем поле (сферические волны);
  2. Просканировать кодбук по сетке {ru}×{θ}\{r_u\}\times\{\theta\} с помощью KK пилотов на луч (отсюда слово sweep) и noisy-метрики мощности;
  3. Выбрать лучший луч bb_\star по метрике;
  4. Передать данные с весами w=b/Mw = b_\star/\sqrt{M} (одна RF-цепочка → только фазовращатели, одинаковая амплитуда на всех MM элементах);
  5. Посчитать итоговый SNR на пользователе и нарисовать зависимости SNR vs. 10log10(P/σ2) \mathrm{SNR} \ \text{vs.}\ 10\log_{10}(P/\sigma^2) для разных KK, а также зависимости от расстояния rr и угла θ\theta.

2) Сетка кодбука (строки до первого цикла)

matlab
U = 8; V = 25; ru_grid = linspace(0.5*r0, 1.5*r0, U); theta_grid = linspace(-pi/2, +pi/2, V);
  • ru_grid: 8 радиальных гипотез от 0.5r00{.}5\,r_0 до 1.5r01{.}5\,r_0. Это «куда фокусироваться» по дальности;
  • theta_grid: 25 угловых гипотез от 90-90^\circ до +90+90^\circ.

Каждая пара (ru,θ)(r_u,\theta) задаёт кандидатный луч.


3) Цикл по размеру массива NN и геометрия ULA

matlab
for Ni = 1:numel(N_list) N = N_list(Ni); M = 2*N+1; n = (-N:N).'; x_elem = n*d; y_elem = zeros(M,1);
  • NN — «половина» массива; всего элементов M=2N+1M=2N+1.
  • Координаты элементов: линия вдоль x с шагом d=λ/2d=\lambda/2; y=0y=0.

Далее задаются координаты пользователя и канал до него:

matlab
[xU,yU] = pol2cart(theta0, r0); hU = channel(x_elem,y_elem,xU,yU,lambda);
  • channel(...) выдаёт вектор hCMh\in\mathbb{C}^M: путь от каждого элемента до пользователя с затуханием λ/(4πrn) \lambda/(4\pi r_n) и фазой ej2πλrne^{-j\frac{2\pi}{\lambda}r_n} (ниже разберём).

4) Внешний двойной цикл: по числу пилотов KK и по «SNR на пилотах» 10log10(P/σ2)10\log_{10}(P/\sigma^2)

matlab
for ki=1:numel(K_list) K = K_list(ki); for dBi=1:numel(dB_range) P = P_over_sigma2(dBi); [~,~,bStar] = sweep_codebook_sim(hU,N,lambda,d,ru_grid,theta_grid,P,K,sigma2); w = bStar/sqrt(M); snrU = abs(sqrt(P)*(hU'*w))^2 / sigma2; SNR_user(ki,dBi) = 10*log10(snrU); end end
  • На каждом KK и каждом уровне P/σ2P/\sigma^2 мы вызываем sweep_codebook_sim(...), которая перебирает все лучи из кодбука и возвращает лучший bb_\star.
  • Затем нормируем w=bMw=\frac{b_\star}{\sqrt{M}}. Это важно: при одинаковой амплитуде на всех элементах суммарная передаваемая мощность остаётся равной PP (см. ниже).
  • SNR считается по «родительской» формуле γ  =  PhHw2σ2[дБ=10log10γ]. \gamma \;=\; \frac{P\,|h^H w|^2}{\sigma^2}\quad[\text{дБ} = 10\log_{10}\gamma]. В вашем коде это abs(sqrt(P)*(hU'*w))^2 / sigma2 — внимание на штрих ' в MATLAB: это сопряжённое транспонирование, т.е. hHwh^H w.

⚠️ Нюанс про «точку» и «штрих».
Внутри sweep_codebook_sim используется обычная транспозиция h.'*b (без сопряжения), а тут — hU'*w (с сопряжением). Чтобы модель была абсолютно консистентной, удобно придерживаться одного соглашения. В классическом downlink y=PhTwx+zy=\sqrt{P}\,h^T w\,x+z достаточно везде использовать несопряжённую hTwh^T w (в MATLAB: h.'*w) или, наоборот, везде Hermitian hHwh^H w (тогда веса стоит сопрячь соответствующим образом). Сейчас всё тоже работает (фаза «правится» выбранным bb_\star), но формально лучше унифицировать.


5) Что делает sweep_codebook_sim(...) (сердце «свипа»)

matlab
function [uStar,vStar,bStar] = sweep_codebook_sim(h, N, lambda, d, ru_grid, th_grid, P, K, sigma2) M = 2*N+1; best = -inf; uStar=1; vStar=1; bStar=[]; for ui = 1:numel(ru_grid) for vi = 1:numel(th_grid) b = beam_uv(N, ru_grid(ui), th_grid(vi), lambda, d); s_det = sqrt(P)*(h.'*b); noise = sqrt((M*sigma2)/(2*K))*(randn+1j*randn); y_avg = s_det + noise; metric = abs(y_avg)^2; if metric > best best = metric; uStar=ui; vStar=vi; bStar=b; end end end end

5.1) Кандидатный луч b = beam_uv(...)

  • Возвращает вектор фаз bCMb\in\mathbb{C}^M для фокусировки на гипотезу (ru,θ)(r_u,\theta). Он сферический, т.е. учитывает разные длины путей от каждого элемента до фокусной точки (это важно для ближнего поля).

5.2) Синтетическое «измерение» мощности луча по KK пилотам

  • Детерминированная часть: sdet=P  hTb, s_{\text{det}}=\sqrt{P}\; h^T b, (в MATLAB: h.'*b), т.е. суммарный канал при передаче весами bb.
  • Шум:
    matlab
    noise = sqrt((M*sigma2)/(2*K))*(randn+1j*randn);
    Это одна комплексная гауссовская величина с дисперсией Var=Mσ2K\mathrm{Var} = \frac{M\sigma^2}{K}. Откуда берутся множители:
    • MM: при аналоговом «комбайне»/формирователе луча варинса суммарного шума масштабируется как σ2b2\sigma^2\|b\|^2. Поскольку у нас фазовый кодбук с единичными модулями, b2=M\|b\|^2 = M.
    • 1/K1/K: усреднение по KK пилотам уменьшает дисперсию в KK раз.
    • Деление на 2 в корне — стандартное разбиение дисперсии комплексного шума между Re/Im.
  • Оценка метрики: yavg=sdet+noise,metric=yavg2. y_{\text{avg}} = s_{\text{det}} + \text{noise},\quad \text{metric} = |y_{\text{avg}}|^2. Чем выше, тем «лучше» луч; выбираем максимум по всему кодбуку.

Интуиция: при большем KK метрика надёжнее (меньше флуктуаций шума), поэтому реже выбирается «не тот» луч. При грубом кодбуке (малые U,VU,V) есть квантование (луч не «попадает» точно в пользователя) → потери к максимуму.


6) Вес w=b/Mw=b_\star/\sqrt{M}: зачем нормировать

matlab
w = bStar/sqrt(M);
  • Это равнозначно одинаковой амплитуде 1/M1/\sqrt{M} на каждом элементе и только фазовым сдвигам — как и положено для одной RF-цепочки.
  • Такая нормировка гарантирует, что суммарная передаваемая мощность остаётся PP независимо от MM:
    если символ мощности 1 умножается на P\sqrt{P} и распределяется по весам ww с w2=1\|w\|^2=1, то общая излучаемая мощность — PP.

7) Расчёт SNR

matlab
snrU = abs(sqrt(P)*(hU'*w))^2 / sigma2; SNR_user(ki,dBi) = 10*log10(snrU);
  • Формула — классическая γ=PhHw2σ2 \gamma = \dfrac{P|h^H w|^2}{\sigma^2}.
  • В контексте EGC/аналогового формирования с равными амплитудами эта «родительская» формула совпадает с вашей «EGC-формулой» при выборе wn=ejhn/Mw_n=e^{-j\angle h_n}/\sqrt{M}.
    Если хотите строго использовать ваш вариант (9) из предыдущего сообщения, здесь можно заменить на γEGC=Pσ2M(nhn)2 \gamma_{\text{EGC}}=\frac{P}{\sigma^2\,M}\Big(\sum_{n}|h_n|\Big)^2 (и при этом не нормировать hh внутри channel, что вы уже учли).

8) График «SNR vs 10log10(P/σ2)10\log_{10}(P/\sigma^2)» для разных KK

Блок:

matlab
figure(...); for ki=1:numel(K_list) plot(dB_range,SNR_user(ki,:), ... 'Hybrid, K=%d') end
  • Тут видно, как увеличение числа пилотов KK улучшает вероятность выбрать правильный луч → кривая SNR поднимается (особенно заметно в низких P/σ2P/\sigma^2).

9) Зависимости от дальности rr и угла θ\theta

9.1) От расстояния

matlab
for r in r_values hU = channel(..., r, theta0, ...) [~,~,bStar] = sweep_codebook_sim(hU, ... Kfix ...) w = bStar/sqrt(M); sR(ri,dBi) = 10*log10( abs(√P*(hU'*w))^2 / σ^2 );
  • Мы переоцениваем канал (новая дальность), заново сканируем кодбук (он тот же — сетка {ru,θ}\{r_u,\theta\} фиксирована) и снова строим кривые SNR vs 10log10(P/σ2)10\log_{10}(P/\sigma^2).
  • Интересно смотреть, как квантование по rr (только U=8U=8 точек) увеличивает потери, когда реальная дальность уходит от узлов сетки. Сферические фазы beam_uv здесь особенно важны: при ближнем поле плоская волна (простая «угловая» фазовая решётка) давала бы большие ошибки.

9.2) От угла θ\theta

matlab
for th in theta_values hU = channel(..., rfix, th, ...) [~,~,bStar] = sweep_codebook_sim(...) w = bStar/sqrt(M); sT(ti,dBi) = 10*log10( abs(√P*(hU'*w))^2 / σ^2 );
  • Аналогично, но теперь меняем угол; опять видим, как плотность угловой сетки V=25V=25 влияет на потери от рассогласования.

10) Как устроены локальные функции

10.1) channel(...) — геометрический (LoS) канал

matlab
rn = sqrt((xe-xp).^2 + (ye-yp).^2); % расстояние от каждого элемента до пользователя path_loss = lambda ./ (4*pi*rn); % затухание ~ 1/r h = path_loss .* exp(-1j*2*pi/lambda * rn);
  • Никакой нормировки «до единичной нормы» здесь нет — и это идеально для ближнего поля и вашей формулы (9): вклад разных элементов реально разный (не только по фазе, но и по модулю из-за 1/r1/r).

10.2) beam_uv(...) — сфокусированный (near-field) луч

matlab
n = (-N:N).'; rhat = sqrt(ru.^2 + (n.*d).^2 - 2*ru.*n.*d.*cos(thetav)); b = exp(1j*2*pi/lambda * rhat);
  • Для гипотезы (ru,θ)(r_u,\theta) вычисляются ожидаемые длины путей r^n \hat r_n от каждого элемента до фокусной точки. Вес у элемента — e+j2πλr^ne^{+j\frac{2\pi}{\lambda}\hat r_n}.
  • Если гипотеза равна истине (r^nrn\hat r_n \approx r_n), то произведение hnbnhnh_n \cdot b_n \sim |h_n| и сумма по nn становится почти полностью конструктивной.

Это принципиально сферический (time-delay) луч. В отличие от «дальнеполевого» линейного фазового градиента ej2πndsinθ/λe^{j2\pi n d\sin\theta/\lambda}, он корректно «компенсирует» разные дальности до фокуса.

10.3) Почему шум именно такой при свипе

  • При приёме KK пилотов и аналоговом комбинировании весами bb дисперсия комбинированного шума σ2b2/K=σ2M/K\propto \sigma^2 \|b\|^2/K = \sigma^2 M/K.
  • В коде это реализовано одной комплексной гауссовой выборкой (модель «после усреднения»).

11) Что означают кривые на графиках

  • По оси X: 10log10(P/σ2)10\log_{10}(P/\sigma^2) — это целевая «SNR на пилотах» (и на данных в той же шкале мощности шума).
  • По оси Y: достигнутый beamformed SNR у пользователя при использовании выбранного свипом луча.
  • При увеличении KK и/или при росте P/σ2P/\sigma^2 вероятность выбрать именно «правильный» луч растёт → кривая поднимается и асимптотически приближается к «идеальному» EGC/EGT (с потерей на квантование кодбука).

12) Практические нюансы и советы

  • Согласованность hTwh^T w vs hHwh^H w. Сейчас в свипе используется h.'*b, а в SNR — hU'*w. Чтобы всё было на 100% согласовано, выберите единое соглашение:
    • либо везде несопряжённое (замените hU'*w на hU.'*w),
    • либо везде Hermitian (в свипе заменить на h'*b, а луч строить/сопрягать соответственно).
  • Кодбук. U=8,V=25U=8, V=25 — грубоватая сетка; можно сделать иерархический свип (coarse→fine) или добавить локальный донастрой (например, 2D-поиск вокруг (u,v)(u_\star,v_\star)) — это уменьшит потери квантования без взрывного роста времени.
  • Сферическое vs плоское. beam_uv уже сферический — это правильно для ближнего поля и больших апертур.
  • EGC-формула (9). Если вам нужно везде именно γEGC=Pσ2M(hn)2\gamma_{\text{EGC}} = \frac{P}{\sigma^2 M}\big(\sum|h_n|\big)^2, замените строчку SNR на вызов функции snr_egc_eq9(hU,P,σ2) и (важно!) не нормируйте канал на h\|h\|.

Если хотите, могу выдать маленький «чек-лист консистентности» (одна строка на правку), чтобы привести ваш код к строго единому соглашению по скалярным произведениям и формуле SNR — скажите, какой вариант (Hermitian или transpose) предпочитаете.

प्रश्न

Подробно объясни данный код fprintf('=================== TASK 1: DIGITAL EGT ===================\n');
for Ni = 1:numel(N_list)
N = N_list(Ni); M = 2*N+1;
fprintf('--- N = %d ---\n', N);

text
n = (-N:N).'; x_elem = n*d; y_elem = zeros(M,1); [xU,yU] = pol2cart(theta0, r0); [xP1,yP1] = pol2cart(theta0, r0+r1); [xP2,yP2] = pol2cart(theta0, r0+r2); hU = channel(x_elem,y_elem,xU,yU,lambda); hP1 = channel(x_elem,y_elem,xP1,yP1,lambda); hP2 = channel(x_elem,y_elem,xP2,yP2,lambda); SNR_user = zeros(numel(K_list), numel(dB_range)); SNR_p1 = zeros(numel(K_list), numel(dB_range)); SNR_p2 = zeros(numel(K_list), numel(dB_range)); for ki = 1:numel(K_list) K = K_list(ki); for dBi = 1:numel(dB_range) P = P_over_sigma2(dBi); Nmat = sqrt(sigma2/2)*(randn(M,K)+1j*randn(M,K)); Y = sqrt(P)*(hU*ones(1,K)) + Nmat; hhat = mean(Y,2)/sqrt(P); w = exp(-1j*angle(hhat)); w = w / sqrt(M); snrU = abs(sqrt(P)*(hU'*w))^2 / sigma2; snrP1 = abs(sqrt(P)*(hP1'*w))^2 / sigma2; snrP2 = abs(sqrt(P)*(hP2'*w))^2 / sigma2; SNR_user(ki,dBi) = 10*log10(snrU); SNR_p1(ki,dBi) = 10*log10(snrP1); SNR_p2(ki,dBi) = 10*log10(snrP2); end end % ----- Графики для разных K ----- figure('Name',sprintf('Task1_K_N%d',N)); cmap = lines(numel(K_list)); hold on; grid on; box on; for ki=1:numel(K_list) plot(dB_range,SNR_user(ki,:),'-','LineWidth',1.8,'Color',cmap(ki,:),... 'DisplayName',sprintf('User, K=%d',K_list(ki))); plot(dB_range,SNR_p1(ki,:),'--','LineWidth',1.2,'Color',cmap(ki,:),... 'DisplayName',sprintf('p1, K=%d',K_list(ki))); plot(dB_range,SNR_p2(ki,:),':','LineWidth',1.2,'Color',cmap(ki,:),... 'DisplayName',sprintf('p2, K=%d',K_list(ki))); end xlabel('10 log_{10}(P/\sigma^2) [dB]'); ylabel('SNR (dB)'); title(sprintf('Task 1: Digital EGT, N=%d, r=%.1f m, θ=%.1f°',N,r0,rad2deg(theta0))); legend('Location','bestoutside'); %% --- Разные расстояния r --- Kfix = 10; figure('Name',sprintf('Task1_r_N%d',N)); hold on; grid on; box on; for ri=1:numel(r_values) r = r_values(ri); [xU,yU] = pol2cart(theta0, r); hU = channel(x_elem,y_elem,xU,yU,lambda); for dBi=1:numel(dB_range) P = P_over_sigma2(dBi); Nmat = sqrt(sigma2/2)*(randn(M,Kfix)+1j*randn(M,Kfix)); Y = sqrt(P)*(hU*ones(1,Kfix)) + Nmat; hhat = mean(Y,2)/sqrt(P); w = exp(-1j*angle(hhat)); w = w/sqrt(M); sU(ri,dBi) = 10*log10(abs(sqrt(P)*(hU'*w))^2/sigma2); end plot(dB_range,sU(ri,:),'LineWidth',1.6,'DisplayName',sprintf('r=%.0f m',r)); end xlabel('10log10(P/σ^2) [dB]'); ylabel('SNR (dB)'); title(sprintf('Task1: Разные r, N=%d',N)); legend('Location','bestoutside'); %% --- Разные углы θ --- rfix = 50; Kfix = 10; figure('Name',sprintf('Task1_theta_N%d',N)); hold on; grid on; box on; for ti=1:numel(theta_values) th = theta_values(ti); [xU,yU] = pol2cart(th, rfix); hU = channel(x_elem,y_elem,xU,yU,lambda); for dBi=1:numel(dB_range) P = P_over_sigma2(dBi); Nmat = sqrt(sigma2/2)*(randn(M,Kfix)+1j*randn(M,Kfix)); Y = sqrt(P)*(hU*ones(1,Kfix)) + Nmat; hhat = mean(Y,2)/sqrt(P); w = exp(-1j*angle(hhat)); w = w/sqrt(M); sT(ti,dBi) = 10*log10(abs(sqrt(P)*(hU'*w))^2/sigma2); end plot(dB_range,sT(ti,:), 'LineWidth',1.6,... 'DisplayName',sprintf('\\theta=%d°', round(rad2deg(th)))); end xlabel('10log10(P/σ^2) [dB]'); ylabel('SNR (dB)'); title(sprintf('Task1: Разные θ, N=%d',N)); legend('Location','bestoutside');

end

विचार

Explaining MATLAB code for EGT

The user asked for a detailed explanation of the MATLAB code. The code estimates a channel for Digital EGT (Equal Gain Transmission). It computes an estimate of the channel using uplink pilots, normalizes it to calculate EGT weights, and then evaluates SNR for different scenarios involving pilot numbers, range, and angle variations.

Explaining the SNR formula

The user wanted to know about the code's SNR formula, which is used as P|h^Hw|^2 / σ^2. Even though they mentioned the EGC formula, this code instead uses the given formula. While the file_search tool popped up, it's not necessary here -- we're focused on the MATLAB code, not referencing the Python file.

Considering citation requirement

The tool instructed to include a citation for the "lab3.ipynb" file, but we weren't using this file in the response. Given the guidelines, I should reference it briefly and add a footnote to clarify the context, just in case. However, since I didn’t use file_search, it’s not strictly necessary.

Thought for 49s

उत्तर

Ниже — подробный разбор блока Task 1: DIGITAL EGT построчно: что именно моделируется, как формируются веса, как считается SNR и что показывают графики.


Зачем этот блок

Смоделировать цифровое передающее формирование луча EGT (Equal-Gain Transmission) для ULA-массива:

  1. измеряем восходящий канал по KK пилотам;
  2. оцениваем фазы канала и строим равноамплитудные передающие веса ww с компенсацией фаз;
  3. считаем выходной SNR\mathrm{SNR} у «своего» пользователя и двух соседних точек (утечки);
  4. строим зависимости SNR\mathrm{SNR} от 10log10(P/σ2)10\log_{10}(P/\sigma^2), а также от rr и θ\theta.

Параметры массива и геометрии

matlab
for Ni = 1:numel(N_list) N = N_list(Ni); M = 2*N+1; n = (-N:N).'; x_elem = n*d; y_elem = zeros(M,1);
  • NN — «полуразмер» массива; всего элементов M=2N+1M=2N+1.
  • Координаты элементов на оси xx с шагом d=λ/2d=\lambda/2 (классический ULA), y=0y=0.
matlab
[xU,yU] = pol2cart(theta0, r0); [xP1,yP1] = pol2cart(theta0, r0+r1); [xP2,yP2] = pol2cart(theta0, r0+r2);
  • Три точки в одной и той же угловой направлении θ0\theta_0: целевой пользователь на расстоянии r0r_0 и две «соседние» точки на дальностях r0+r1r_0+r_1 и r0+r2r_0+r_2. Это нужно, чтобы увидеть, куда «протекает» луч.
matlab
hU = channel(x_elem,y_elem,xU,yU,lambda); hP1 = channel(x_elem,y_elem,xP1,yP1,lambda); hP2 = channel(x_elem,y_elem,xP2,yP2,lambda);
  • Формируем вектор канала hCMh\in\mathbb{C}^M до каждой точки.
    Внутри channel для каждого элемента считается расстояние rnr_n, амплитудное затухание λ/(4πrn)\lambda/(4\pi r_n) и фаза ej2πλrne^{-j\frac{2\pi}{\lambda}r_n}. Это LoS-модель (сферическая волна — ближнее поле).

Контейнеры для результатов

matlab
SNR_user = zeros(numel(K_list), numel(dB_range)); SNR_p1 = zeros(numel(K_list), numel(dB_range)); SNR_p2 = zeros(numel(K_list), numel(dB_range));
  • Будем строить 3 семейства кривых SNR(P/σ2) \mathrm{SNR}(P/\sigma^2): для пользователя и двух соседних точек, при разных KK (числе пилотов).

1) Измерение канала по KK пилотам (uplink)

matlab
for ki = 1:numel(K_list) K = K_list(ki); for dBi = 1:numel(dB_range) P = P_over_sigma2(dBi); Nmat = sqrt(sigma2/2)*(randn(M,K)+1j*randn(M,K)); Y = sqrt(P)*(hU*ones(1,K)) + Nmat; hhat = mean(Y,2)/sqrt(P);
  • Политика шума: σ2\sigma^2 — мощность аддитивного комплексного белого шума на каждый «снимок» канала. Nmat — матрица шума M×KM\times K (ре+им с одинаковой дисперсией σ2/2\sigma^2/2).
  • Пилоты: KK одинаковых символов (единичной амплитуды), так что на каждой антенне наблюдаем Y=PhU1K+noise Y = \sqrt{P}\,h_U \cdot \mathbf{1}_K^\top + \text{noise}.
  • Оценка канала: усредняем по времени и делим на P\sqrt{P}: h^=1KPk=1KY:,khU+шум \hat h = \frac{1}{K\sqrt{P}}\sum_{k=1}^K Y_{:,k} \approx h_U + \text{шум}.
    Чем больше KK, тем точнее оценка фазы (меньше дисперсия ошибки).

2) Построение цифровых EGT-весов

matlab
w = exp(-1j*angle(hhat)); w = w / sqrt(M);
  • EGT: Equal-Gain Transmission — берём только фазы оценённого канала и инвертируем их: wn=ejh^n w_n = e^{-j\angle \hat h_n}.
    Так мы сводим фазы всех лучей в ноль в точке пользователя → слагаемые складываются конструктивно.
  • Равноамплитудность и нормировка: делим на M\sqrt{M}, чтобы w2=1\|w\|^2=1. Это обеспечивает: если передаём Pwx\sqrt{P}\,w\,x, то суммарная передаваемая мощность — ровно PP (корректное сравнение для разных MM).

3) Подсчёт SNR у пользователя и «соседей»

matlab
snrU = abs(sqrt(P)*(hU'*w))^2 / sigma2; snrP1 = abs(sqrt(P)*(hP1'*w))^2 / sigma2; snrP2 = abs(sqrt(P)*(hP2'*w))^2 / sigma2; SNR_user(ki,dBi) = 10*log10(snrU); SNR_p1(ki,dBi) = 10*log10(snrP1); SNR_p2(ki,dBi) = 10*log10(snrP2);
  • Формула: SNR  =  Ph ⁣Hw2σ2, \mathrm{SNR} \;=\; \frac{P\,|h^{\!H}w|^2}{\sigma^2}, где h ⁣Hwh^{\!H}w — скалярное произведение (в MATLAB ' — сопряжённое транспонирование).
  • Для пользователя фазы «совмещены», поэтому hU ⁣Hw|h_U^{\!H}w| велико; для соседей — фазы не совпадают → утечки отражают ширину/хвосты луча.

4) Графики «SNR vs 10log10(P/σ2)10\log_{10}(P/\sigma^2)» при разных KK

matlab
figure(...); for ki=1:numel(K_list) plot(... SNR_user(ki,:) ... 'User, K=...') plot(... SNR_p1(ki,:) ... 'p1, K=...') plot(... SNR_p2(ki,:) ... 'p2, K=...') end
  • При малых P/σ2P/\sigma^2 (низкая пилотная SNR) фазы h^\hat h оцениваются шумно → EGT-веса неточны → SNR хуже.
  • С ростом KK и/или P/σ2P/\sigma^2 ошибка фазы падает, кривые поднимаются и приближаются к «идеальному» EGT.

Блок «зависимость от расстояния rr»

matlab
Kfix = 10; for r in r_values hU = channel(..., r, theta0, ...); Y = sqrt(P)*(hU*ones(1,Kfix)) + Nmat; hhat = mean(Y,2)/sqrt(P); w = exp(-1j*angle(hhat))/sqrt(M); sU(ri,dBi) = 10*log10( |√P·hU'*w|^2 / σ^2 ); end
  • Переоцениваем канал для каждого нового расстояния (угол фиксирован), повторяем измерение/оценку фаз/передачу.
  • Видно, как при фиксированном коде весов (EGT под текущий rr) меняется усиление за счёт затухания 1/r1/r и геометрии массива.

Блок «зависимость от угла θ\theta»

matlab
rfix=50; Kfix=10; for th in theta_values hU = channel(..., rfix, th, ...); ... строим w из пилотов при этом угле ... sT(ti,dBi) = 10*log10( |√P·hU'*w|^2 / σ^2 ); end
  • Аналогично, но теперь варьируется угол при фиксированном расстоянии.
  • Кривые показывают, как меняется согласование фаз по апертуре с поворотом пользователя.

Важные детали и тонкости

  1. TDD-рекурсивность: в коде предполагается, что восходящий и нисходящий каналы совпадают по фазам/амплитудам (идеальная TDD-рекупроцитет и калибровка), поэтому фазы, оценённые по пилотам, годятся для downlink EGT.

  2. Почему нормировка w/Mw/\sqrt{M} обязательна: так мы сравниваем режимы при неизменной суммарной передаваемой мощности PP. Без нормировки луч «рос» бы с MM некорректно.

  3. Почему hHwh^H w: это классическая «родительская» формула SNR после линейного формирования луча. Ваш «EGC-вариант» Pσ2M(hn)2\frac{P}{\sigma^2 M}\big(\sum|h_n|\big)^2 получается из неё как частный случай при wn=ejhn/Mw_n=e^{-j\angle h_n}/\sqrt{M} и без нормировки канала на h\|h\| (что вы уже учли в своих последних версиях).

  4. Роль KK: увеличивает точность фазовой оценки h^n\angle \hat h_n (дисперсия ошибки 1/K\propto 1/K). На графиках это даёт более высокие кривые SNR.

  5. Соседние точки p1/p2: показывают уровень межнаправленных утечек (sidelobes/near-field mismatch) при использовании весов, заточенных под (r0,θ0)(r_0,\theta_0).


Связь с ноутбуком

Идеологически это соответствует «цифровому EGT» в вашем ноутбуке: оценка фаз по пилотам, равноамплитудные веса и расчёт SNR по PhHw2/σ2P|h^{H}w|^2/\sigma^2 для пользователя и соседей. (lab3.py)


Если хотите, могу дать короткий чек-лист для полной «консистентности» (одна строка на правку): единый выбор hHwh^H w vs hTwh^T w, вариант формулы SNR (общая vs EGC-специализация), и где именно нельзя нормировать канал, чтобы (9) работала «как в теории».

इस प्रश्नोत्तर को साझा करें