Model frekvencijskog ofseta u baziopojasnom kompleksnom signalu.
Frekvencijski ofset nastaje zbog razlike između LO (local oscillator)
frekvencija predajnika i prijemnika. U baziopojasnom domenu modelira se kao
multiplikacija kompleksnim eksponencijalom:
r[n] = s[n] * exp( j * 2*pi*Δf * n / f_s )
gdje je:
- s[n] : originalni (TX) kompleksni signal
- r[n] : signal sa frekvencijskim ofsetom
- Δf : frekvencijski ofset u Hz
- f_s : sample rate u Hz
- n : indeks uzorka (0, 1, 2, ...)
Klasa internu pamti indeks uzorka, tako da se više uzastopnih poziva
`apply` ponašaju kao jedna kontinuirana sekvenca (bez skokova faze).
Parameters
----------
freq_offset_hz : float
Frekvencijski ofset Δf u Hz. Pozitivna vrijednost znači da će
faza signala napredovati u pozitivnom smjeru (rotacija u
kompleksnoj ravni).
sample_rate_hz : float
Sample rate signala f_s u Hz (npr. 1.92e6 za LTE 1.4 MHz ili
30.72e6 za “punu” LTE konfiguraciju).
initial_phase_rad : float, optional
Početna faza (u radijanima) kompleksnog eksponencijala. Default je 0.
| np.ndarray channel.frequency_offset.FrequencyOffset.apply |
( |
| self, |
|
|
np.ndarray | tx_samples ) |
Primjenjuje frekvencijski ofset na dati kompleksni TX signal.
Očekuje se da su uzorci kompleksni (IQ) i da je vremenska osa na
zadnjoj dimenziji. Funkcija podržava 1D i višedimenzionalne nizove:
- 1D: shape = (N,)
- 2D: shape = (n_antena, N)
- ... općenito: shape = (..., N), gdje je N broj uzoraka.
Parameters
----------
tx_samples : np.ndarray
Kompleksni NumPy niz (dtype kompleksan) sa uzorcima signala
na koje se primjenjuje frekvencijski ofset. Zadnja dimenzija
se tretira kao vremenski indeks.
Returns
-------
np.ndarray
Novi NumPy niz iste forme kao `tx_samples`, sa primijenjenim
frekvencijskim ofsetom.
Raises
------
ValueError
Ako `tx_samples` nije barem 1D niz ili nije kompleksnog tipa.
Examples
--------
Jednostavan primjer sa 1D signalom::
>>> import numpy as np
>>> from channel.frequency_offset import FrequencyOffset
>>>
>>> fs = 1.92e6 # sample rate u Hz
>>> freq_off = 500.0 # 500 Hz ofset
>>> fo = FrequencyOffset(freq_offset_hz=freq_off, sample_rate_hz=fs)
>>>
>>> # Npr. OFDM izlaz (ovdje samo dummy signal)
>>> tx = np.ones(1000, dtype=np.complex64)
>>> rx = fo.apply(tx)
>>> rx.shape
(1000,)
Primjer sa više antena (2D)::
>>> tx_mimo = np.vstack([tx, 1j * tx]) # shape (2, 1000)
>>> rx_mimo = fo.apply(tx_mimo)
>>> rx_mimo.shape
(2, 1000)