comnum.Constellation#

class comnum.Constellation(kind, m)#

A constellation with Gray labels: point i carries the bits of i, MSB first.

The points and their labels are those of OptiCommPy (GrayMapping): square QAM as the product of two PAM listed row by row from the top in a “snake” order, PSK on e^{j2πk/M}, PAM on -(M-1), …, -1, 1, …, M-1, OOK on {0, 1}; the i-th point of the construction order gets the Gray label i ^ (i >> 1). The grids keep their integer spacing; call normalized() for unit mean energy.

Parameters:
  • kind (str) – "qam", "psk", "pam" or "ook".

  • m (int) – the order, a power of two (2 for OOK).

Raises:

ValueError – for an invalid parameter (the message names it).

Examples

>>> import comnum, numpy as np
>>> c = comnum.Constellation("qam", 16).normalized()
>>> round(c.energy, 12)
1.0
>>> bits = np.array([0, 0, 0, 0, 1, 1, 1, 1], dtype=np.uint8)
>>> c.demap_bits(c.map_bits(bits)).tolist()
[0, 0, 0, 0, 1, 1, 1, 1]
static from_name(name)#

A constellation from the name the specifications use ("16-QAM", "QPSK", "8PSK", "4-PAM", "OOK"; case, dashes and spaces are ignored), with its integer grid (call normalized() for unit energy).

Parameters:

name (str) – the name.

Returns:

the constellation.

Return type:

Constellation

Raises:

ValueError – for an unknown family or an invalid order.

Examples

>>> import comnum
>>> c = comnum.Constellation.from_name("16-QAM")
>>> c.kind, c.order
('qam', 16)
static from_points(points)#

A custom constellation from its points, labelled by their index.

Parameters:

points (array_like) – the M points (complex), M a power of two.

Returns:

the constellation (kind "custom").

Return type:

Constellation

Raises:

ValueError – for an invalid parameter or input (the message names it).

Examples

>>> import comnum
>>> comnum.Constellation.from_points([1, -1]).order
2
static set_partitioning(kind, m)#

The points of Constellation(kind, m) with a set-partitioning labelling (Ungerboeck): natural labels for PSK, Fig. 2(a) of Caire, Taricco & Biglieri (1998) for 16-QAM.

Parameters:
  • kind (str) – "psk" or "qam" (16-QAM only).

  • m (int) – the order.

Returns:

the constellation (kind "custom").

Return type:

Constellation

Raises:

ValueError – for an invalid parameter (the message names it).

Examples

>>> import comnum
>>> comnum.Constellation.set_partitioning("qam", 16).points[0b1001]
np.complex128(-3+3j)
decide(z)#

Index of the nearest point of every sample (minimum-distance decisions).

Parameters:

z (array_like) – received samples.

Returns:

the indices (int64).

Return type:

numpy.ndarray

Raises:

ValueError – for an input that is not an array of numbers of the expected shape.

demap_bits(z)#

Hard-decision bits of every sample (OptiCommPy demodulateGray).

Parameters:

z (array_like) – received samples.

Returns:

log2 M bits per sample (uint8).

Return type:

numpy.ndarray

Raises:

ValueError – for an input that is not an array of numbers of the expected shape.

energy_with(px)#

Mean energy of the points under the probabilities px.

Parameters:

px (array_like) – the probabilities of the points.

Returns:

Σ p_i |s_i|².

Return type:

float

Raises:

ValueError – for an input that is not an array of numbers of the expected shape.

indices(bits)#

Symbol indices of a bit sequence (log2 M bits per symbol, MSB first).

Parameters:

bits (array_like) – the bits, a multiple of log2 M.

Returns:

the indices (int64).

Return type:

numpy.ndarray

Raises:

ValueError – if the length is not a multiple of log2 M.

llr(z, noise_var, *, px=None, max_log=False)#

Bit log-likelihood ratios ln p(b=0|y) - ln p(b=1|y), log2 M per sample.

The likelihood of point s is exp(-|y - s|²/σ²) (OptiCommPy calcLLR).

Parameters:
  • z (array_like) – received samples.

  • noise_var (float) – complex noise variance E|w|² (for a real constellation over a real channel, twice the variance of the real noise).

  • px (array_like, optional) – prior probabilities of the points.

  • max_log (bool) – max-log approximation instead of log-sum-exp.

Returns:

log2 M LLRs per sample, MSB first (float64).

Return type:

numpy.ndarray

Raises:

ValueError – for an invalid parameter or input (the message names it).

Examples

>>> import comnum
>>> c = comnum.Constellation("qam", 4).normalized()
>>> llr = c.llr(c.map_bits([0, 1]), 0.1)
>>> bool(llr[0] > 0 and llr[1] < 0)
True
map_bits(bits)#

Symbols of a bit sequence (OptiCommPy modulateGray).

Parameters:

bits (array_like) – the bits, a multiple of log2 M.

Returns:

one symbol per log2 M bits (complex128).

Return type:

numpy.ndarray

Raises:

ValueError – for an invalid parameter or input (the message names it).

normalized()#

The same constellation scaled to unit mean energy.

Returns:

the normalised constellation.

Return type:

Constellation

project(z)#

The nearest point of every sample.

Parameters:

z (array_like) – received samples.

Returns:

the points (complex128).

Return type:

numpy.ndarray

Raises:

ValueError – for an input that is not an array of numbers of the expected shape.

scaled(s)#

The same constellation with every point multiplied by s.

Parameters:

s (float) – the scale.

Returns:

the scaled constellation.

Return type:

Constellation

symbols(indices)#

Symbols of an index sequence.

Parameters:

indices (array_like) – the indices, below M.

Returns:

the points (complex128).

Return type:

numpy.ndarray

Raises:

ValueError – for an invalid parameter or input (the message names it).

bits_per_symbol#

Bits per symbol, log2 M.

Type:

int

energy#

Mean energy of the points under uniform probabilities.

Type:

float

kind#

The family, "qam", "psk", "pam", "ook" or "custom".

Type:

str

order#

The number of points M.

Type:

int

points#

The points, in label order (a copy, complex128).

Type:

numpy.ndarray