Skip to content

komm.UniformQuantizer

Uniform scalar quantizer. It is a scalar quantizer in which the separation between levels is a constant $\Delta$, called the quantization step, and the thresholds are the mid-point between adjacent levels. More precisely, the levels are given by $$ v_i = (i - (L - 1)/2 + \theta) \Delta, \qquad i \in [0 : L), $$ where $\theta \in \mathbb{R}$ is an arbitrary offset (normalized by $\Delta$), and the finite thresholds are given by $$ t_i = \frac{v_{i-1} + v_i}{2}, \qquad i \in [1 : L). $$ For more details, see Say06, Sec. 9.4.

Parameters:

  • num_levels (int)

    The number of quantization levels $L$. It must be greater than $1$.

  • step (float)

    The quantization step $\Delta$. It must be a positive number.

  • offset (float)

    The offset $\theta$ of the quantizer. The default value is $0$.

Examples:

>>> quantizer = komm.UniformQuantizer(num_levels=4, step=0.5)
>>> quantizer.levels
array([-0.75, -0.25,  0.25,  0.75])
>>> quantizer.thresholds
array([-0.5,  0. ,  0.5])
>>> quantizer = komm.UniformQuantizer(num_levels=5, step=0.5)
>>> quantizer.levels
array([-1. , -0.5,  0. ,  0.5,  1. ])
>>> quantizer.thresholds
array([-0.75, -0.25,  0.25,  0.75])
>>> quantizer = komm.UniformQuantizer(num_levels=5, step=0.5, offset=2.0)
>>> quantizer.levels
array([0. , 0.5, 1. , 1.5, 2. ])
>>> quantizer.thresholds
array([0.25, 0.75, 1.25, 1.75])

mid_riser() classmethod

Constructs a mid-riser uniform quantizer. In a mid-riser quantizer, $0$ is always a threshold. It is a symmetric quantizer when $L$ is even.

Parameters:

  • num_levels (int)

    The number of quantization levels $L$. It must be greater than $1$.

  • step (float)

    The quantization step $\Delta$. It must be a positive number.

Examples:

>>> quantizer = komm.UniformQuantizer.mid_riser(num_levels=4, step=0.5)
>>> quantizer.levels
array([-0.75, -0.25,  0.25,  0.75])
>>> quantizer.thresholds
array([-0.5,  0. ,  0.5])
>>> quantizer = komm.UniformQuantizer.mid_riser(num_levels=5, step=0.5)
>>> quantizer.levels
array([-1.25, -0.75, -0.25,  0.25,  0.75])
>>> quantizer.thresholds
array([-1. , -0.5,  0. ,  0.5])

mid_tread() classmethod

Constructs a mid-tread uniform quantizer. In a mid-tread quantizer, $0$ is always a level. It is a symmetric quantizer when $L$ is odd.

Parameters:

  • num_levels (int)

    The number of quantization levels $L$. It must be greater than $1$.

  • step (float)

    The quantization step $\Delta$. It must be a positive number.

Examples:

>>> quantizer = komm.UniformQuantizer.mid_tread(num_levels=4, step=0.5)
>>> quantizer.levels
array([-1. , -0.5,  0. ,  0.5])
>>> quantizer.thresholds
array([-0.75, -0.25,  0.25])
>>> quantizer = komm.UniformQuantizer.mid_tread(num_levels=5, step=0.5)
>>> quantizer.levels
array([-1. , -0.5,  0. ,  0.5,  1. ])
>>> quantizer.thresholds
array([-0.75, -0.25,  0.25,  0.75])

levels NDArray[floating] cached property

The quantizer levels $v_0, v_1, \ldots, v_{L-1}$.

Examples:

>>> quantizer = komm.UniformQuantizer(num_levels=8, step=3.0)
>>> quantizer.levels
array([-10.5,  -7.5,  -4.5,  -1.5,   1.5,   4.5,   7.5,  10.5])
>>> quantizer = komm.UniformQuantizer(num_levels=5, step=2.0)
>>> quantizer.levels
array([-4., -2.,  0.,  2.,  4.])

thresholds NDArray[floating] cached property

The quantizer finite thresholds $t_1, t_2, \ldots, t_{L-1}$.

Examples:

>>> quantizer = komm.UniformQuantizer(num_levels=8, step=3.0)
>>> quantizer.thresholds
array([-9., -6., -3.,  0.,  3.,  6.,  9.])
>>> quantizer = komm.UniformQuantizer(num_levels=5, step=2.0)
>>> quantizer.thresholds
array([-3., -1.,  1.,  3.])

mean_squared_error()

Computes the mean squared (quantization) error (MSE) of the quantizer for a given input probability density function (pdf). It is defined as $$ \mse = \int_{-\infty}^{\infty} (y - x)^2 f_X(x) \, dx $$ where $y$ is the quantized signal and $f_X(x)$ is the pdf of the input signal.

Parameters:

  • input_pdf (Callable[[NDArray[floating]], NDArray[floating]])

    The probability density function $f_X(x)$ of the input signal.

  • input_range (tuple[float, float])

    The range $(x_\mathrm{min}, x_\mathrm{max})$ of the input signal.

  • points_per_interval (int)

    The number of points per interval for numerical integration (default: 4096).

Returns:

  • mse (float)

    The mean square quantization error.

Examples:

>>> quantizer = komm.UniformQuantizer(num_levels=4, step=2.0)
>>> gaussian_pdf = lambda x: 1/np.sqrt(2*np.pi) * np.exp(-x**2/2)
>>> quantizer.mean_squared_error(
...     input_pdf=gaussian_pdf,
...     input_range=(-5, 5),
... )
0.3363025489037716
>>> uniform_pdf = lambda x: 1/8 * (np.abs(x) <= 4)
>>> quantizer.mean_squared_error(
...     input_pdf=uniform_pdf,
...     input_range=(-4, 4),
... )
0.3333333730891729
>>> quantizer.step**2 / 12
0.3333333333333333

digitize()

Returns the quantization indices for the input signal.

Parameters:

  • input (ArrayLike)

    The input signal $x$ to be digitized.

Returns:

  • output (NDArray[integer])

    The integer indices of the quantization levels for each input sample.

Examples:

>>> quantizer = komm.UniformQuantizer(num_levels=4, step=2.0)
>>> quantizer.digitize([-2.4,  0.8,  3.2])
array([0, 2, 3])

quantize()

Quantizes the input signal.

Parameters:

  • input (ArrayLike)

    The input signal $x$ to be quantized.

Returns:

  • output (NDArray[floating])

    The quantized signal $y$.

Examples:

>>> quantizer = komm.UniformQuantizer(num_levels=4, step=2.0)
>>> quantizer.quantize([-2.4,  0.8,  3.2])
array([-3.,  1.,  3.])