# Fractionally spaced equalizer - LMS algorithm

I am doing a project in MATLAB about the fractionally spaced equalizer. The method that i have chosen to update the tap weight coefficients is the LMS algorithm. Here is the block scheme that i have tried to follow:

• x(k) are the elements of the received training sequence.
• p(k) are the tap weight coefficients.

The vectors x(k) and p(k) have the same number of elements as there are tap weights. As it can be seen y(k) is the output of the equalizer. The formulas to calculate the error and then update the tap weights are the following:

for the training phase and

for the tracking phase.

This is the MATLAB code:

The training phase

for k = 1:2*length(trainSymtx)

for i = N+1:2*length(trainSymtx)-N

currSymbols = train_syms_real(i-N:i+N);
y(k) = tapWeights * currSymbols';

if mod(k, 2) == 0  % considero solo 'k' pari

a = k/2;
error = y(k) - trainSymtx(a);
x = conj(train_syms_real(i-N:i+N));
tapWeights = tapWeights - stepSize * error * x;

end
end
end


The tracking phase

for b = 1:2*length(trainSymtx)

for m = N+1:2*length(trainSymtx)-N

currSymbols = train_syms_real(m-N:m+N);
y(b) = tapWeights * currSymbols';

if mod(b, 2) == 0

w = b/2;
c_est(w) = y(b);
error_est = y(b) - c_est(w);
x = conj(train_syms_real(m-N:m+N));
tapWeights = tapWeights - stepSize * error_est * x;

end
end
end


My questions are the following:

1. What are exactly the ĉ symbols? From the scheme it looks like the vector ĉ is just a part of the vector y(k) that we choose via the decision block.

2. What is the decision block and how it works? How does it decides which symbols to consider and which ones to eliminate?

3. How to implement this block scheme in MATLAB? I have done most of it but I'm not sure how to implement the switch between training and tracking.

The help will be gratefully appreciated.

The way it is drawn suggests that $$\hat{c}[k]$$ samples are the complex decisions for the demodulated symbols. This assumes correct timing to only use the samples for demodulation. Instead, assuming a training sequence is used, I recommend comparing all samples to the “ideal” waveform given by the training sequence at the same sampling rate as it would appear in this location of the receiver (as then a fractionally spaced equalizer). The switch between training and tracking would then have to change from a fractional spaced equalizer to a baud rate equalizer if implemented as shown.

Below is Python code I have for the implementation of a normalized LMS equalizer:

def LMS(input_signal, desired_signal, num_taps, alpha, shift=0):
'''
LMS(input_signal, desired_signal, num_taps, alpha, shift=0)
LMS equalizer implementation  Dan Boschen 10-12-2023

input parameters:
input_signal: received signal (1D array like)
desired_signal: transmitted (reference) signal (1D array like)
num_taps: length of equalizer (positive integer)
alpha: damping coefficient, typically < 0.01  (positive float)
shift: number of samples to shift dominant equalizer tap to the right (signed integer)
input_signal and desired_signal should be aligned in time with zero phase

returns:
y: equalized output (1D array)
coeff: converged channel coefficients (1D array)
e: error vs iteration (1D array)
'''

if shift > 0:
rx_shift = shift
tx_shift = 0
else:
tx_shift = -shift
rx_shift = 0

# align to delay of equalizer
input_signal = input_signal[rx_shift + (num_taps-1)//2:]
desired_signal = desired_signal[tx_shift:]
num_points = min(len(input_signal), len(desired_signal))

# normalize signals
input_signal = input_signal[:num_points]/np.std(input_signal)

desired_signal = desired_signal[:num_points]/np.std(desired_signal)
coeff = np.zeros(num_taps, dtype=complex)
y = np.zeros(num_points, dtype=complex)
e = np.zeros(num_points, dtype=complex)

for n in np.arange(num_taps, num_points):
x = input_signal[n:n-num_taps:-1]
y[n] = np.dot(np.conj(coeff), x)        # predicted output
e[n] = y[n] - desired_signal[n]           # error
coeff =   coeff - alpha * x * np.conj(e[n])

return y, np.conj(coeff), e


Please also see DSP.SE #31318 which details the process to find the least squared solution for the coefficients when post processing can be used. For adaptive solutions in addition to the simpler LMS algorithm detailed above (very easy but slow to converge) also consider the Recursive Least Squares (more complex, fast convergence and good tracking).