Skip to main content
added 2242 characters in body
Source Link
Dan Boschen
  • 55k
  • 2
  • 59
  • 143

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.

As to MATLABBelow is Python code, please 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 this post hereDSP.SE #31318 which details the process to find the least squared solution for the coefficients when post processing iscan be used. Working code is typically out of scope for this site, but forFor adaptive solutions seein addition to the simpler LMS algorithm detailed above (very easy but slow to converge) oralso consider the Recursive Least Squares (more complex, fast convergence and good tracking).

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 to MATLAB code, please see this post here which details the process to find the coefficients when post processing is used. Working code is typically out of scope for this site, but for adaptive solutions see the LMS algorithm (very easy but slow to converge) or Recursive Least Squares (more complex, fast convergence and good tracking).

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).

added 1 character in body
Source Link
Dan Boschen
  • 55k
  • 2
  • 59
  • 143

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 to MATLAB code, please see this post here which details the process to find the coefficients when post processing is used. Working code is typically out of scope for this site, but for adaptive solutions see the LMS algorithm (very easy but slow to converge) or Recursive Least Squares (more complex, fast convergence and good trackintracking).

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 to MATLAB code, please see this post here which details the process to find the coefficients when post processing is used. Working code is typically out of scope for this site, but for adaptive solutions see the LMS algorithm (very easy but slow to converge) or Recursive Least Squares (more complex, fast convergence and good trackin).

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 to MATLAB code, please see this post here which details the process to find the coefficients when post processing is used. Working code is typically out of scope for this site, but for adaptive solutions see the LMS algorithm (very easy but slow to converge) or Recursive Least Squares (more complex, fast convergence and good tracking).

added 223 characters in body
Source Link
Dan Boschen
  • 55k
  • 2
  • 59
  • 143

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 to MATLAB code, please see this post here which details the process to find the coefficients when post processing is used. Working code is typically out of scope for this site, but for adaptive solutions see the LMS algorithm (very easy but slow to converge) or Recursive Least Squares (more complex, fast convergence and good trackin).

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 to MATLAB code, please see this post here which details the process to find the coefficients when post processing is used.

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 to MATLAB code, please see this post here which details the process to find the coefficients when post processing is used. Working code is typically out of scope for this site, but for adaptive solutions see the LMS algorithm (very easy but slow to converge) or Recursive Least Squares (more complex, fast convergence and good trackin).

Source Link
Dan Boschen
  • 55k
  • 2
  • 59
  • 143
Loading