MATLAB Examples

Eigenbeam Responses for the Optimum Beamformer Demo.

To demonstrate the optimum beamformer, we consider a scenario in which there are three interference sources and compare it to a conventional beamformer (spatial matched filter). The array is a 20-element ULA with $\lambda/2$ element spacing. These interferers are at the following angles with the corresponding interference-to-noise ratios (INRs) in decibels: $\phi_1 = 20^{\circ}$ and $INR_1 = 35 dB$, $\phi_2 = -30^{\circ}$ and $INR_2 = 70 dB$, and $\phi_3 = 50^{\circ}$ and $INR_3 = 50 dB$. The optimum beamformer is first computed using (11.3.15) for a look direction of $\phi_s = 0^{\circ}$.

Copyright 2017 - 2027, Ilias S. Konsoulas.

Contents

Workspace Initialization.

clc; clear; close all;

Signal Definitions.

M      = 20;        % Number of Array Elements.
N      = 200;       % Number of Signal Samples.
n      = 1:N;       % Time Sample Index Vector.
lambda = 1;         % Incoming Signal Wavelength in (m).
d      = lambda/2;  % Interelement Distance in (m).
SNR    = 20;        % Target SNR in dBs.
phi_s  = 10;        % Target azimuth angle in degrees.
phi_i1 = 20;        % Interference angle in degrees.
phi_i2 = -30;       % Interference angle in degrees.
phi_i3 = 50;        % Interference angle in degrees.
INR1   = 70;        % Interference #1 INR in dBs.
INR2   = 50;        % Interference #2 INR in dBs.
INR3   = 35;        % Interference #3 INR in dBs.

u_s    = (d/lambda)*sin(phi_s*pi/180);   % Normalized Spatial Frequency of the Target signal.
u_int1 = (d/lambda)*sin(phi_i1*pi/180);  % Normalized Spatial Frequency of the Interferer #1.
u_int2 = (d/lambda)*sin(phi_i2*pi/180);  % Normalized Spatial Frequency of the Interferer #2.
u_int3 = (d/lambda)*sin(phi_i3*pi/180);  % Normalized Spatial Frequency of the Interferer #3.

% Target Signal definition.
s = zeros(M,N);
v_s = exp(-1i*2*pi*u_s*(0:M-1).')/sqrt(M);       % Target Steering Vector.
v_i1 = exp(-1i*2*pi*u_int1*(0:M-1).')/sqrt(M);   % Interferer #1 Steering Vector.
v_i2 = exp(-1i*2*pi*u_int2*(0:M-1).')/sqrt(M);   % Interferer #2 Steering Vector.
v_i3 = exp(-1i*2*pi*u_int3*(0:M-1).')/sqrt(M);   % Interferer #3 Steering Vector.


s(:,100) = 10^(SNR/20)*v_s;  % Amplitude of Target Signal Generation.

% The uncorrelated unit power thermal noise samples with a Gaussian
% distribution are generated by:
w = (randn(M,N)+1i*randn(M,N))/sqrt(2);

% The interference (jammer) voltage vectors are generated by:
i_x1 = 10^(INR1/20)*v_i1*(randn(1,N)+1i*randn(1,N))/sqrt(2);
i_x2 = 10^(INR2/20)*v_i2*(randn(1,N)+1i*randn(1,N))/sqrt(2);
i_x3 = 10^(INR3/20)*v_i3*(randn(1,N)+1i*randn(1,N))/sqrt(2);

%The three signals are added to produce the overall array signal.
x = s + i_x1 + i_x2 + i_x3 + w;

iplusn = i_x1 + i_x2 + i_x3 + w;

% Calculation of the i+n autocorrelation matrix.
R_ipn = 10^(INR1/10)*(v_i1*v_i1') + 10^(INR2/10)*(v_i2*v_i2') + 10^(INR3/10)*(v_i3*v_i3') + eye(M);

InvR = inv(R_ipn);

% Calculate the Interference-plus-Noise Correlation Matrix Eigrnvectors and
% Eigenvalues:
[V, D] = eig(R_ipn);

q1 = V(:,end);
q2 = V(:,end-1);
q3 = V(:,end-2);
eigs_sorted = sort(diag(D),'descend');
lambda1 = eigs_sorted(1);
lambda2 = eigs_sorted(2);
lambda3 = eigs_sorted(3);

% Plot the Interference-plus-Noise eigenvalues.
figure('NumberTitle', 'off','Name','Eigenvalues of Interference-plus-Noise Correlation Matrix');
stem(10*log10(eigs_sorted),'*r');
title('Eigenvalues of Interference-plus-Noise Correlation Matrix');
grid on;

MVDR Optimum Beamformer computed for a phi_s = 0 deg.

c_opt = InvR*v_s/(v_s'*InvR*v_s);  %#ok<*MINV>

Spatial Matched Filter or Steering Vector Beamformer Eq. (11.2.16).

c_mf = v_s;

Calculate the Beam Patterns.

Nsamples1 = 3e4;
angle1          = -90:180/Nsamples1:90-180/Nsamples1;
Opt_Beam_Pat    = zeros(Nsamples1,1);
Conv_Beam_Pat   = zeros(Nsamples1,1);
Eigen_Beam1_Pat = zeros(Nsamples1,1);
Eigen_Beam2_Pat = zeros(Nsamples1,1);
Eigen_Beam3_Pat = zeros(Nsamples1,1);

for k=1:Nsamples1
    u = (d/lambda)*sin(angle1(k)*pi/180);
    v = exp(-1i*2*pi*u*(0:M-1).')/sqrt(M); % Azimuth Scanning Steering Vector.
    Opt_Beam_Pat(k)    = c_opt'*v;
    Conv_Beam_Pat(k)   = c_mf'*v;
    Eigen_Beam1_Pat(k) = q1'*v;
    Eigen_Beam2_Pat(k) = q2'*v;
    Eigen_Beam3_Pat(k) = q3'*v;
end

Plot the corresponding Beampatterns in Cartesian Coordinates.

figure('NumberTitle', 'off','Name','Figure 11.16(a)');
plot(angle1,10*log10(abs(Conv_Beam_Pat).^2),angle1,10*log10(abs(Opt_Beam_Pat).^2),'r', 'LineWidth',1.5)
xlim([-95 95]);
ylim([-100 0]);
title(['     Beamformer Design with d = \lambda/2 and M = 20.            ';
    'Conventional Beamformer (blue) and MVDR Optimum Beamformer (red).';]);
xlim([-90 90]);
xlabel('Angle (deg)');
ylabel('Power (dB)');
grid on;

Plot the corresponding Beampatterns in Polar Coordinates.

figure('NumberTitle','off','Name','Figure 11.16(a)-Polar','Position',[0 0 1050 500]);
subplot(1,2,1);
polardb(angle1'*pi/180,10*log10(abs(Conv_Beam_Pat).^2),-60,'b');
title('Conventional BF');
grid on;

subplot(1,2,2);
polardb(angle1'*pi/180,10*log10(abs(Opt_Beam_Pat).^2),-60,'r');
title('Optimum BF');
grid on;

tightfig;

Calculate the SINR loss factor for the Optimum Beamformer:

Nsamples = 3e4;  % The resolution must be very fine to reveal the true depth of the notches.
Lsinr_opt = zeros(Nsamples,1);
Lsinr_mf  = zeros(Nsamples,1);
SNR0 = M*10^(SNR/10);
angle = -90:180/Nsamples:90-180/Nsamples;

for k=1:Nsamples
    v = exp(-1i*pi*(0:M-1)'*sin(angle(k)*pi/180))/sqrt(M); % Azimuth Scanning Steering Vector.
    c_mf = v;  % This is the spatial matched filter beamformer.
    Lsinr_opt(k) = v'*InvR*v;
    SINRout_mf = real(M*(10^(SNR/10))*(abs(c_mf'*v)^2)/(c_mf'*R_ipn*c_mf));
    Lsinr_mf(k) = SINRout_mf/SNR0;
end

Plot the Eigenbeam Patterns.

figure('NumberTitle', 'off','Name','Eigenbeam Patterns','Position',[100 100 1050 300]);
subplot(1,3,1);
plot(angle,10*log10(abs(Eigen_Beam1_Pat).^2));
title('Eigenbeam Pattern for Jammer #1');
xlabel('Angle (deg)');
ylabel('Eigenbeam Power (dB)');
ylim([-70 5]);
xlim([-90 90]);
grid on;

subplot(1,3,2);
plot(angle,10*log10(abs(Eigen_Beam2_Pat).^2),'r', 'LineWidth',1.5)
title('Eigenbeam Pattern for Jammer #2');
xlabel('Angle (deg)');
ylabel('Eigenbeam Power (dB)');
ylim([-70 5]);
xlim([-90 90]);
grid on;

subplot(1,3,3);
plot(angle,10*log10(abs(Eigen_Beam3_Pat).^2),'g', 'LineWidth',1.5)
title('Eigenbeam Pattern for Jammer #3');
ylim([-70 5]);
xlim([-90 90]);
xlabel('Angle (deg)');
ylabel('Eigenbeam Power (dB)');
grid on;

tightfig;