MATLAB Code
clc; clear; close all;
%% --- Numerical input arrays (example values) ---
h_x = [1, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1]; % x-axis channel
h_y = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]; % y-axis channel
h_z = [0.5, 0.6, 0.4, 0.7, 0.3, 0.8, 0.2, 0.9, 0.1, 1]; % z-axis channel
r_x = [0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0.1]; % received x
r_y = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]; % received y
r_z = [0.5, 0.4, 0.6, 0.3, 0.7, 0.2, 0.8, 0.1, 0.9, 0.1]; % received z
% Ensure all arrays are the same length
N = min([length(h_x), length(h_y), length(h_z), length(r_x), length(r_y), length(r_z)]);
h_x = h_x(1:N); h_y = h_y(1:N); h_z = h_z(1:N);
r_x = r_x(1:N); r_y = r_y(1:N); r_z = r_z(1:N);
%% --- Maximal Ratio Combining (MRC) across 3 channels ---
w_x = abs(h_x).^2 ./ (abs(h_x).^2 + abs(h_y).^2 + abs(h_z).^2);
w_y = abs(h_y).^2 ./ (abs(h_x).^2 + abs(h_y).^2 + abs(h_z).^2);
w_z = abs(h_z).^2 ./ (abs(h_x).^2 + abs(h_y).^2 + abs(h_z).^2);
rx_MRC = w_x .* r_x + w_y .* r_y + w_z .* r_z;
%% --- DOA Estimation (basic y-z plane relative to x-axis) ---
epsilon = 1e-12; % avoid division by zero
O = atan(real(r_x .* r_y) ./ (real(r_x .* r_z) + epsilon));
O_avg = mean(O);
angle_deg = rad2deg(O_avg);
fprintf('MRC Estimated DOA (in the y–z plane relative to x-axis): %.2f degrees\n', angle_deg);
%% --- Rotate y-z plane signals along DOA ---
r_yz = r_z * cos(O_avg) + r_y * sin(O_avg);
h_yz = h_z * cos(O_avg) + h_y * sin(O_avg);
%% --- MRC after DOA ---
w1 = abs(h_x).^2 ./ (abs(h_x).^2 + abs(h_yz).^2);
w2 = abs(h_yz).^2 ./ (abs(h_x).^2 + abs(h_yz).^2);
rx_postDOA = w1 .* r_x + w2 .* r_yz;
%% --- Optional: Linear combination scaling ---
Linear_sum_postDOA = r_x + 1 * r_yz;
Linear_sum_postDOA2 = r_x + 2 * r_yz;
%% --- MUSIC DOA Estimation ---
% Stack signals into a 3xN array
X = [r_x; r_y; r_z];
% Covariance matrix
R = (X * X') / N;
% Eigen-decomposition
[Evecs, Evals] = eig(R);
[~, idx] = sort(diag(Evals), 'descend');
Evecs = Evecs(:, idx);
% Noise subspace (assume 1 signal)
En = Evecs(:, 2:end);
% Scan angles in y-z plane (-90 to 90 deg)
theta_scan = -90:0.5:90;
P_MUSIC = zeros(size(theta_scan));
for k = 1:length(theta_scan)
theta = deg2rad(theta_scan(k));
a = [1; sin(theta); cos(theta)]; % steering vector in y-z plane
P_MUSIC(k) = 1 / (a' * (En * En') * a);
end
% Normalize and convert to dB
P_MUSIC_dB = 10*log10(abs(P_MUSIC)/max(abs(P_MUSIC)));
% Find peak
[~, max_idx] = max(P_MUSIC);
theta_MUSIC = theta_scan(max_idx);
fprintf('MUSIC Estimated DOA: %.2f degrees\n', theta_MUSIC);
%% --- Plot results ---
figure;
subplot(3,1,1); plot(abs(rx_MRC), '-o'); title('MRC output before DOA'); xlabel('Sample'); ylabel('|Amplitude|');
subplot(3,1,2); plot(abs(rx_postDOA), '-o'); title('MRC output after DOA'); xlabel('Sample'); ylabel('|Amplitude|');
subplot(3,1,3); plot(theta_scan, P_MUSIC_dB); title('MUSIC Pseudo-spectrum'); xlabel('Angle (deg)'); ylabel('Normalized Power (dB)');
grid on;
Output
MRC Estimated DOA (in the y–z plane relative to x-axis): 47.80 degrees
MUSIC Estimated DOA: 48.00 degrees
MUSIC Estimated DOA: 48.00 degrees