Generators#
- class SymbolGenerator(M: int, *, distribution: ndarray | None = None, seed: int | None = None, name: str = 'generator')[source]#
Generator of independent and identically distributed (IID) integer symbols.
Signal Model#
Each output symbol \(y[n]\) is drawn independently from the integer alphabet \(\{0, 1, \ldots, M-1\}\), uniformly by default:
\[\Pr\left(y[n] = m\right) = \frac{1}{M}, \qquad m \in \{0, 1, \ldots, M-1\}\]A source is not always uniform, though: probabilistic shaping sends inner constellation points more often than outer ones, and
distribution=gives that source directly,\[\Pr\left(y[n] = m\right) = p_m\]which is what
maxwell_boltzmann()returns. Note what this block is not: an i.i.d. draw from \(P_X\) is the idealization a distribution matcher approaches, not what it produces – a matcher maps uniform bits onto a finite set of sequences, so its output is neither independent nor exactly \(P_X\) on a finite block (seeDistributionMatcher). Use this block to study what a distribution is worth, and the matcher to produce it.This is a source block: the call argument is not an input signal \(x\) but the requested output size.
Axes: element-wise – each symbol is drawn independently; the output shape is the requested size (int or tuple).
- param M:
Alphabet size \(M\); symbols are drawn from \(\{0, 1, \ldots, M-1\}\).
- type M:
int
- param distribution:
Probabilities \(p_m\), of length \(M\). Default (None) is the uniform law.
- type distribution:
np.ndarray, optional, keyword-only
- param seed:
Local RNG seed.
- type seed:
int, optional, keyword-only
- param name:
Name of the generator instance. Default is
"generator".- type name:
str, optional, keyword-only
- raises ValueError:
If
distributiondoes not have one non-negative probability per symbol, summing to one.
References
J. G. Proakis, M. Salehi, Digital Communications, 5th ed., McGraw-Hill, 2008, Chapter 1; G. Böcherer, F. Steiner, P. Schulte, IEEE Trans. Commun., vol. 63, no. 12, 2015 (non-uniform signaling).
Examples
>>> generator = SymbolGenerator(M=4, seed=42) >>> symbols_1D = generator(5) # Generates a 1D array of size 5 >>> print(symbols_1D) [0 3 2 1 1] >>> symbols_2D = generator((2, 3)) # Generates a 2D array of shape (2, 3) >>> print(symbols_2D) [[3 0 2] [0 0 2]]
A shaped source, drawn from a Maxwell-Boltzmann law:
>>> from comnumpy.core.shaping import maxwell_boltzmann >>> pam = np.arange(-3, 4, 2).astype(float) >>> shaped = SymbolGenerator(4, distribution=maxwell_boltzmann( ... pam, entropy=1.5), seed=0) >>> print(np.bincount(shaped(10000)) / 10000) [0.0557 0.4433 0.4457 0.0553]
- class GaussianGenerator(sigma2: float = 1, *, seed: int | None = None, name: str = 'gaussian_generator')[source]#
Generator of IID circularly-symmetric complex Gaussian samples.
Signal Model#
Each output sample \(y[n]\) is drawn independently from a zero-mean circular complex Gaussian distribution of variance \(\sigma^2\):
\[y[n] \sim \mathcal{CN}\left(0, \sigma^2\right)\]This is a source block: the call argument is not an input signal \(x\) but the requested output size.
Axes: element-wise – each sample is drawn independently; the output shape is the requested size (int or tuple).
- param sigma2:
Variance \(\sigma^2\) of the complex Gaussian distribution. Default is 1.
- type sigma2:
float
- param seed:
Local RNG seed.
- type seed:
int, optional, keyword-only
- param name:
Name of the generator instance. Default is
"gaussian_generator".- type name:
str, optional, keyword-only
References
J. G. Proakis, M. Salehi, Digital Communications, 5th ed., McGraw-Hill, 2008, Chapter 2.
Examples
>>> generator = GaussianGenerator(sigma2=1.0, seed=42) >>> symbols_1D = generator(5) # Generates a 1D array of 5 complex symbols >>> print(np.round(symbols_1D, 3)) [ 0.215-0.921j -0.735+0.09j 0.531-0.224j 0.665-0.012j -1.38 -0.603j] >>> symbols_2D = generator((3, 3)) # Generates a 2D array of shape (3, 3) >>> symbols_2D.shape (3, 3)