%% QPSK Adaptive Equalization Using Adaptive Lattice Filter
% Note: If you are using R2016a or an earlier release, replace each call to the object with the equivalent step syntax. For example, obj(x) becomes step(obj,x).
% Create the QPSK signal and the noise, filter them to obtain the received signal, and delay the received signal to obtain the desired signal.

D = 16;
b = exp(1i*pi/4)*[-0.7 1];
a = [1 -0.7];
ntr = 1000;
s = sign(randn(1,ntr+D)) + 1i*sign(randn(1,ntr+D));
n = 0.1*(randn(1,ntr+D) + 1i*randn(1,ntr+D));
r = filter(b,a,s) + n;
x = r(1+D:ntr+D);
d = s(1:ntr);

%
% Use the Adaptive Lattice Filter to compute the filtered output and the filter error for the input and desired signal.

lam = 0.995;
del = 1;
alf = dsp.AdaptiveLatticeFilter('Length', 32, ...
    'ForgettingFactor', lam, 'InitialPredictionErrorPower', del);
[y,e] = alf(x,d);

%
% Plot the In-Phase and the Quadrature components of the desired, output, and the error signals.

subplot(2,2,1); plot(1:ntr,real([d;y;e]));
title('In-Phase Components');
legend('Desired','Output','Error');
xlabel('time index'); ylabel('signal value');
subplot(2,2,2); plot(1:ntr,imag([d;y;e]));
title('Quadrature Components');
legend('Desired','Output','Error');
xlabel('time index'); ylabel('signal value');

%
% Plot the received and equalized signals’ scatter plots.

subplot(2,2,3); plot(x(ntr-100:ntr),'.'); axis([-3 3 -3 3]);
title('Received Signal Scatter Plot'); axis('square'); 
xlabel('Real[x]'); ylabel('Imag[x]'); grid on;
subplot(2,2,4); plot(y(ntr-100:ntr),'.'); axis([-3 3 -3 3]);
title('Equalized Signal Scatter Plot'); axis('square');
xlabel('Real[y]'); ylabel('Imag[y]'); grid on;