Chains#
- class OFDMTransmitter(N_carrier_data: int, N_cp: int, *, carrier_type: ndarray | CarrierAllocation | None = None, pilots: ndarray | None = None, name: str = 'ofdm_transmitter')[source]#
OFDM transmitter chain: allocation, IFFT, cyclic prefix, serialization.
Signal Model#
The serial data symbols are split into blocks, allocated to the data subcarriers (pilot and null subcarriers are filled according to the allocation mask), and each allocated block \(X_t[k]\) of length \(N\) is brought to the time domain with the orthonormal IDFT:
\[x_t[n] = \frac{1}{\sqrt{N}} \sum_{k=0}^{N-1} X_t[k] \, e^{i 2 \pi k n / N}, \qquad n = 0, \dots, N-1\]A cyclic prefix of length \(N_{cp}\) (the last \(N_{cp}\) samples of the block) is prepended to each block, and the extended blocks are serialized into the time-domain signal \(y[m]\).
Axes: declared axis – consumes the serial axis -1 (length \(T \, N_{data}\)), produces a serial time-domain signal of length \(T (N + N_{cp})\) on axis -1.
- param N_carrier_data:
Number of data subcarriers \(N_{data}\) per OFDM symbol.
- type N_carrier_data:
int
- param N_cp:
Length \(N_{cp}\) of the cyclic prefix.
- type N_cp:
int
- param carrier_type:
Subcarrier allocation mask (e.g. data, pilot, null), passed to
CarrierAllocator. Default is an all-data mask of lengthN_carrier_data.- type carrier_type:
CarrierAllocation or np.ndarray, optional, keyword-only
- param pilots:
Pilot values, one per pilot subcarrier of the allocation mask.
- type pilots:
np.ndarray or list, optional, keyword-only
- param name:
Name of the processor instance. Default is
"ofdm_transmitter".- type name:
str, optional, keyword-only
References
R. van Nee, R. Prasad, OFDM for Wireless Multimedia Communications, Artech House, 2000, Chapter 2.
Examples
>>> transmitter = OFDMTransmitter(4, 2) >>> x = np.arange(8) + 0j # 2 OFDM symbols of 4 data subcarriers >>> y = transmitter(x) >>> print(y.shape) # 2 blocks of length 4 + 2 (12,)
- class OFDMReceiver(N_carrier_data: int, N_cp: int, *, h: ndarray = <factory>, carrier_type: ndarray | CarrierAllocation | None = None, name: str = 'ofdm_receiver')[source]#
OFDM receiver chain: prefix removal, FFT, equalization, extraction.
Signal Model#
The serial received signal is split into blocks of length \(N + N_{cp}\), the cyclic prefix is discarded, and each block \(r_t[n]\) is brought to the frequency domain with the orthonormal DFT before one-tap zero-forcing equalization:
\[R_t[k] = \frac{1}{\sqrt{N}} \sum_{n=0}^{N-1} r_t[n] \, e^{-i 2 \pi k n / N}, \qquad Y_t[k] = \frac{R_t[k]}{H[k]}\]where \(H[k]\) is the \(N\)-point DFT of the channel impulse response \(h[l]\). The data subcarriers are then extracted according to the allocation mask and serialized.
Axes: declared axis – consumes the serial axis -1 (length \(T (N + N_{cp})\)), produces the serial data symbols of length \(T \, N_{data}\) on axis -1.
- param N_carrier_data:
Number of data subcarriers \(N_{data}\) per OFDM symbol.
- type N_carrier_data:
int
- param N_cp:
Length \(N_{cp}\) of the cyclic prefix.
- type N_cp:
int
- param h:
Channel impulse response \(h[l]\) used by the frequency domain equalizer. Default is the ideal channel
[1.0].- type h:
np.ndarray or list, keyword-only
- param carrier_type:
Subcarrier allocation mask (e.g. data, pilot, null), passed to
CarrierExtractor. Default is an all-data mask of lengthN_carrier_data.- type carrier_type:
CarrierAllocation or np.ndarray, optional, keyword-only
- param name:
Name of the processor instance. Default is
"ofdm_receiver".- type name:
str, optional, keyword-only
References
R. van Nee, R. Prasad, OFDM for Wireless Multimedia Communications, Artech House, 2000, Chapter 2.
Examples
>>> x = np.arange(8) + 0j >>> y = OFDMTransmitter(4, 2)(x) >>> x_est = OFDMReceiver(4, 2)(y) >>> print(np.round(x_est.real, 6) + 0.0) [0. 1. 2. 3. 4. 5. 6. 7.]