Compensators#

class FrequencyDomainEqualizer(h: ndarray | None = None, *, axis: int = -1, name: str = 'frequency domain equalizer', shift: bool = False)[source]#

One-tap zero-forcing equalizer that compensates the channel per subcarrier in the frequency domain.

This class extends the WeightAmplifier: the weights are computed once from the channel impulse response, then each subcarrier is divided by the corresponding bin of the channel frequency response.

Signal Model#

Given a channel impulse response \(h[l]\), the Frequency Domain Equalizer applies the following weight amplifier:

\[y[k] = \frac{x[k]}{H[k]}, \qquad H[k] = \sum_{l=0}^{L-1} h[l] \, e^{-i 2 \pi k l / N}\]

where:

  • \(x[k]\) is the input value at subcarrier \(k\),

  • \(h[l]\) is the channel impulse response of length \(L\),

  • \(H[k]\) is the \(N\)-point DFT of \(h[l]\), with \(N\) the number of subcarriers (taken from the input shape),

  • \(y[k]\) is the equalized output at subcarrier \(k\).

Axes: declared axis – the weights \(1/H[k]\) are computed and applied along axis (default -1, the block content axis of the Block layout (..., T, F)).

param h:

The impulse response \(h[l]\) of the channel to be equalized. Required (a ValueError is raised when it is missing).

type h:

np.ndarray

param axis:

The axis along which the weights are applied. Default is -1, the only value currently supported: the channel DFT is computed on the 1-D h along its own axis, so any other value raises at prepare.

type axis:

int, optional, keyword-only

param shift:

If True, applies an fftshift to the weights, for inputs whose zero-frequency subcarrier is centered. Default is False.

type shift:

bool, optional, keyword-only

param name:

Name of the equalizer instance. Default is "frequency domain equalizer".

type name:

str, optional, keyword-only

References

R. van Nee, R. Prasad, OFDM for Wireless Multimedia Communications, Artech House, 2000, Chapter 2.

Examples

>>> h = np.array([1.0, 0.5])
>>> equalizer = FrequencyDomainEqualizer(h=h)
>>> X = np.fft.fft(h, 4)  # the channel frequency response itself
>>> print(np.round(equalizer(X), 3) + 0.0)
[1.+0.j 1.+0.j 1.+0.j 1.+0.j]
prepare(X: ndarray) → None[source]#

Compute the amplifier weight from the channel impulse response