Skip to main content

CeOfdm

Struct CeOfdm 

Source
pub struct CeOfdm {
    pub n_subcarriers: usize,
    pub oversampling: usize,
    pub h: f64,
    pub n_cp: usize,
    pub receiver: Receiver,
    pub sample_rate: Hertz,
}
Expand description

A CE-OFDM link (see the module documentation).

Fields§

§n_subcarriers: usize

Data subcarriers K per block.

§oversampling: usize

Oversampling factor J: the DFT has N = 2J(K + 1) points.

§h: f64

Modulation index h (phase standard deviation 2πh).

§n_cp: usize

Cyclic prefix, in samples of the DFT of $N$ points (the oversampling is already in $N$, unlike crate::ofdm::Ofdm::n_cp, which counts Nyquist-rate samples).

§receiver: Receiver

The receiver of Demodulate (CeOfdm::demodulate_with_receiver); the arctangent demodulator of the principal phase by default.

§sample_rate: Hertz

The rate of the samples (one per point of the DFT of $N$): the rate of the Signal of Modulate and the rate Demodulate expects; 1 Hz by default (time in samples).

Implementations§

Source§

impl CeOfdm

Source

pub fn n_fft(&self) -> usize

The DFT size N = 2J(K + 1).

Source

pub fn block_len(&self) -> usize

Samples per block, N + N_cp.

Source

pub fn sps(&self) -> f64

Samples per data symbol, (N + N_cp)/K.

Source

pub fn noise_variance(&self, esn0_db: f64) -> f64

Noise variance per sample for an E_s/N_0 (dB) per data symbol and a unit envelope: σ² = (N + N_cp)/(K E_s/N_0).

Source

pub fn new(n_subcarriers: usize, oversampling: usize, h: f64) -> Result<CeOfdm>

K data subcarriers, oversampling J, modulation index h, no prefix, the default receiver, at the sample rate 1 Hz.

§Errors

comnum_core::Error::Config for invalid parameters (see CeOfdm::check).

§Examples
use comnum_waveform::ce_ofdm::CeOfdm;
let ce = CeOfdm { n_cp: 8, ..CeOfdm::new(16, 2, 0.1)? };
assert_eq!(ce.block_len(), 2 * 2 * 17 + 8);
Source

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

Validate the configuration.

§Errors

comnum_core::Error::Config unless K ≥ 1, J ≥ 1, h > 0, the prefix is at most one block of N samples and the sample rate is positive and finite.

Source

pub fn ofdm_signal(&self, d: &[C64]) -> Result<Vec<f64>>

The real OFDM signal x = (F d + F* d*)/√(2K) of every block (no prefix).

§Errors

comnum_core::Error::Config for invalid parameters, comnum_core::Error::Shape for a number of symbols that is not a multiple of K.

Source

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

The transmitted samples exp(j2πh x), with the cyclic prefix of every block.

§Errors

As CeOfdm::ofdm_signal.

Source

pub fn demodulate_with_receiver( &self, r: &[C64], receiver: Receiver, ) -> Result<Vec<C64>>

The symbol estimates of every block with the receiver: the projection of its proxy of the phase on the data bins, divided by $2\pi h$ and by Bussgang’s gain of the receiver (theory::receiver_gain), so that the estimates are unbiased. With Receiver::Arctangent, the estimates d̂ = G ψ/(2πh) of the arctangent demodulator with its unwrapping.

§Errors

comnum_core::Error::Config for invalid parameters, comnum_core::Error::Shape for a number of samples that is not a multiple of N + N_cp.

§Examples
use comnum_waveform::ce_ofdm::{CeOfdm, Receiver};
use comnum_mapping::constellation::Constellation;
use comnum_core::rng::Rng;
let ce = CeOfdm::new(64, 2, 0.02).unwrap();
let c = Constellation::qam(16).unwrap().normalized();
let (_, d) = comnum_mapping::source::symbols(&c, 64, None, &mut Rng::new(1)).unwrap();
// without noise the linear receivers err only by their distortion, small at a small h
let e = ce.demodulate_with_receiver(&ce.modulate(&d).unwrap(), Receiver::Enhanced).unwrap();
assert_eq!(c.decide(&e), c.decide(&d));
Source

pub fn received_phase(&self, r: &[C64], unwrap: Unwrap) -> Vec<f64>

The phase of the receiver before the DFT, prefix included: the principal phase arg r or the phase unwrapped along the stream.

Trait Implementations§

Source§

impl Clone for CeOfdm

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 CeOfdm

Source§

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

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

impl Demodulate for CeOfdm

CE-OFDM as a Demodulate block: one stream of samples at CeOfdm::sample_rate, demodulated by CeOfdm::receiver.

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 CeOfdm::demodulate_with_receiver.

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 CeOfdm

CE-OFDM as a Modulate block: one stream of data symbols into one stream of samples at CeOfdm::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 CeOfdm

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 CeOfdm

Auto Trait Implementations§

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.