Skip to main content

Ofdm

Struct Ofdm 

Source
pub struct Ofdm {
    pub n_fft: usize,
    pub n_active: usize,
    pub oversampling: usize,
    pub n_cp: usize,
    pub dc_null: bool,
    pub dft_spread: bool,
    pub sample_rate: Hertz,
}
Expand description

An OFDM (or DFT-spread OFDM) modulator and demodulator.

Fields§

§n_fft: usize

Size $N$ of the subcarrier grid.

§n_active: usize

Number $K$ of active (modulated) subcarriers, centred on the carrier.

§oversampling: usize

Oversampling factor $L$ (IFFT of size $L N$).

§n_cp: usize

Cyclic prefix, in Nyquist-rate samples ($L N_{\mathrm{cp}}$ samples).

§dc_null: bool

Leave the DC subcarrier empty (the active subcarriers skip $k = 0$).

§dft_spread: bool

DFT spreading of the data (localised SC-FDMA).

§sample_rate: Hertz

The rate of the modulated samples, $L N \Delta f$ ($\Delta f$ the subcarrier spacing): the rate of the Signal of Modulate, and the rate Demodulate expects; 1 Hz by default (time in samples).

Implementations§

Source§

impl Ofdm

Source

pub fn new(n_fft: usize, n_active: usize) -> Result<Ofdm>

$K$ active subcarriers out of $N$, oversampling 4, no prefix, at the sample rate 1 Hz.

§Errors

comnum_core::Error::Config unless $1 \le K \le N$.

Source

pub fn check(&self) -> Result<()>

Validate the configuration.

§Errors

comnum_core::Error::Config for an empty or overfull grid, a zero oversampling or a sample rate that is not positive and finite.

Source

pub fn fft_len(&self) -> usize

Size of the IFFT, $L N$.

Source

pub fn block_len(&self) -> usize

Samples per block, prefix included, $L (N + N_{\mathrm{cp}})$.

Source

pub fn subcarrier(&self, i: usize) -> isize

Subcarrier index $k$ of the active subcarrier i.

Source

pub fn bin(&self, i: usize) -> usize

FFT bin of the active subcarrier i (fft::centred_bin, one bin further from the subcarrier 0 on with dc_null).

Source

pub fn pulse(&self, i: usize, n: usize) -> (usize, Vec<C64>)

The transmit pulse of the active subcarrier i of symbol n, prefix included, on its support: (first sample, values), $\frac{1}{\sqrt{LN}} e^{j 2\pi k (t - L N_{\mathrm{cp}})/(LN)}$ for $t = 0, \dots, L(N + N_{\mathrm{cp}}) - 1$ (energy $(N + N_{\mathrm{cp}})/N$); a column of the matrix $\mathbf{G}$ of Nissel, Schwarz & Rupp 2017, eq. (20).

Source

pub fn window(&self, i: usize, n: usize) -> (usize, Vec<C64>)

The receive pulse (the window of the demodulator) of the active subcarrier i of symbol n: the Ofdm::pulse without its prefix, of unit energy, on its support (first sample, values).

Source

pub fn is_active_bin(&self, bin: usize) -> bool

Whether an FFT bin carries an active subcarrier.

Source

pub fn spread(&self, data: &[C64]) -> Vec<C64> ⓘ

The values of the active subcarriers of data (the identity, or the unitary DFT of size $K$ with dft_spread).

Source

pub fn despread(&self, active: &[C64]) -> Vec<C64> ⓘ

The inverse of Ofdm::spread.

Source

pub fn to_time(&self, active: &[C64]) -> Result<Vec<C64>>

The time block (without prefix, $L N$ samples) of the values of the active subcarriers.

§Errors

comnum_core::Error::Shape if active does not have $K$ values.

Source

pub fn to_active(&self, block: &[C64]) -> Result<Vec<C64>>

The values of the active subcarriers of a time block (without prefix).

§Errors

comnum_core::Error::Shape if block does not have $L N$ samples.

Source

pub fn filter(&self, block: &[C64]) -> Result<Vec<C64>>

Keep only the active subcarriers of a time block (an ideal band-pass filter).

§Errors

As Ofdm::to_active.

Source

pub fn with_prefix(&self, block: &[C64]) -> Result<Vec<C64>>

Prepend the cyclic prefix to a time block.

§Errors

comnum_core::Error::Shape if the prefix is longer than the block.

Source

pub fn windowed(&self, samples: &[C64], ramp: usize) -> Result<Vec<C64>>

The raised-cosine window of whole blocks of Ofdm::block_len samples (prefix included): the first ramp samples of every prefix rise as

$$ w[n] = \frac{1}{2}\left(1 - \cos\frac{\pi (n + 1/2)}{R}\right), \qquad n = 0 \dots R - 1, $$

a cyclic postfix of $R$ samples of the block falls as $1 - w$ and overlaps the ramp of the next block (the postfix of the last block wraps onto the first: the stream stays periodic), so the output has the length of the input and the FFT part of every block is untouched. The pulse of a block then lasts $L(N + N_{\mathrm{cp}}) + R$ samples with $(1 - \cos)$ edges: the raised-cosine impulse shape of windowed OFDM (Saul, Proc. IEEE VTC2004-Fall, 2004, eq. (1): a guard interval and a roll-off of 11.1 %), whose out-of-band sidelobes fall as $f^{-3}$ instead of the $f^{-1}$ of the rectangular pulse. ramp = 0 returns the samples unchanged.

§Errors

comnum_core::Error::Config if ramp exceeds the prefix $L N_{\mathrm{cp}}$, comnum_core::Error::Shape for a partial block.

§Examples
use comnum_waveform::ofdm::Ofdm;
use comnum_math::C64;
let ofdm = Ofdm { n_cp: 4, oversampling: 1, ..Ofdm::new(16, 16).unwrap() };
let data: Vec<C64> = (0..32).map(|k| C64::new(if k % 3 == 0 { 1.0 } else { -1.0 }, 0.0)).collect();
let x = ofdm.modulate(&data).unwrap();
let y = ofdm.windowed(&x, 4).unwrap();
assert_eq!(y.len(), x.len());
// the FFT part of every block is untouched
assert!(y[4..20].iter().zip(&x[4..20]).all(|(a, b)| (a - b).norm() < 1e-12));
Source

pub fn modulate(&self, data: &[C64]) -> Result<Vec<C64>>

Modulate data symbols (a multiple of $K$): $L (N + N_{\mathrm{cp}})$ samples per block.

§Errors

comnum_core::Error::Shape if the number of symbols is not a multiple of $K$, and the errors of Ofdm::check.

Source

pub fn demodulate(&self, samples: &[C64]) -> Result<Vec<C64>>

Demodulate whole blocks into data symbols.

§Errors

comnum_core::Error::Shape if the number of samples is not a multiple of the block length.

Source

pub fn papr_db_per_block(&self, samples: &[C64]) -> Vec<f64>

The PAPR (dB) of every whole block of samples, the cyclic prefix excluded (comnum_math::papr_db of the useful part).

Source

pub fn modulate_with( &self, data: &[C64], reduction: &dyn PaprReduction, ) -> Result<(Vec<C64>, Vec<usize>)>

Modulate with a PAPR reduction technique: the samples and the side information of every block (the selected candidate of SLM or PTS, 0 otherwise).

§Errors

As Ofdm::modulate, with the number of data symbols per block of the technique, and the errors of the technique.

Source

pub fn demodulate_with( &self, samples: &[C64], reduction: &dyn PaprReduction, side: &[usize], ) -> Result<Vec<C64>>

Demodulate blocks transmitted with a PAPR reduction technique and its side information.

§Errors

comnum_core::Error::Shape for a partial block or a side information of another length.

Trait Implementations§

Source§

impl Clone for Ofdm

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Ofdm

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Demodulate for Ofdm

OFDM as a Demodulate block: one stream of samples at Ofdm::sample_rate.

Source§

fn demodulate_into(&mut self, y: &Signal, out: &mut Symbols) -> Result<()>

§Errors

comnum_core::Error::Config for several streams or a signal at another sample rate, and the errors of Ofdm::demodulate.

Source§

fn demodulate(&mut self, y: &Signal) -> Result<Out, Error>
where Out: Default,

Demodulate y (allocates, calls Demodulate::demodulate_into). Read more
Source§

impl Modulate for Ofdm

OFDM as a Modulate block: one stream of data symbols into one stream of samples at Ofdm::sample_rate.

Source§

fn modulate_into(&self, x: &Symbols, out: &mut Signal) -> Result<()>

Modulate x into out. Read more
Source§

fn modulate(&self, x: &In) -> Result<Signal, Error>

Modulate x (allocates, calls Modulate::modulate_into). Read more
Source§

impl PartialEq for Ofdm

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for Ofdm

Auto Trait Implementations§

§

impl Forget for Ofdm

§

impl Freeze for Ofdm

§

impl RefUnwindSafe for Ofdm

§

impl Send for Ofdm

§

impl Sync for Ofdm

§

impl Unpin for Ofdm

§

impl UnsafeUnpin for Ofdm

§

impl UnwindSafe for Ofdm

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.