sdr.rms_bandwidth(x: ArrayLike, sample_rate: float = 1.0) float

Measures the RMS bandwidth \(B_{\text{rms}}\) of the signal \(x[n]\).

Parameters:
x: ArrayLike

The time-domain signal \(x[n]\) to measure.

Note

For best measurement performance, the time-domain signal should be very long. This allows for more averaging of its power spectra.

sample_rate: float = 1.0

The sample rate \(f_s\) in samples/s.

Returns:

The RMS signal bandwidth \(B_{\text{rms}}\) in Hz.

Notes

The root-mean-square (RMS) bandwidth \(B_{\text{rms}}\) is calculated by

\[ B_{\text{rms}} = \sqrt{\frac {\int_{-\infty}^{\infty} (f - \mu_f)^2 \cdot S(f - \mu_f) \, df} {\int_{-\infty}^{\infty} S(f - \mu_f) \, df} } \]

where \(S(f)\) is the power spectral density (PSD) of the signal \(x[n]\). The RMS bandwidth is measured about the centroid of the spectrum

\[ \mu_f = \frac {\int_{-\infty}^{\infty} f \cdot S(f) \, df} {\int_{-\infty}^{\infty} S(f) \, df} . \]

The RMS bandwidth is a measure of the energy spread of the spectrum about the centroid. For a rectangular spectrum, the RMS bandwidth is \(B_{\text{rms}} = B_s / \sqrt{12}\).

Examples

Calculate the RMS bandwidth of a signal with a rectangular spectrum with normalized bandwidth of 1.

In [1]: symbol_rate = 1  # symbols/s

In [2]: symbol_rate / np.sqrt(12)
Out[2]: np.float64(0.2886751345948129)

Create a BPSK signal with a rectangular pulse shape. Note, the time-domain pulse shape is rectangular, but the spectrum is sinc-shaped. Measure the RMS bandwidth of the signal and compare it to the ideal rectangular spectrum.

In [3]: psk = sdr.PSK(2, pulse_shape="rect")

In [4]: symbols = np.random.randint(0, psk.order, 10_000)

In [5]: x_rect = psk.modulate(symbols)

In [6]: sdr.rms_bandwidth(x_rect, sample_rate=symbol_rate * psk.sps)
Out[6]: np.float64(0.7446372175904691)

Make the same measurements with square-root raised cosine (SRRC) pulse shaping. The SRRC spectrum is narrower and, therefore, closer to the rectangular spectrum.

In [7]: psk = sdr.PSK(2, pulse_shape="srrc")

In [8]: symbols = np.random.randint(0, psk.order, 10_000)

In [9]: x_srrc = psk.modulate(symbols)

In [10]: sdr.rms_bandwidth(x_srrc, sample_rate=symbol_rate * psk.sps)
Out[10]: np.float64(0.29088345066048465)

Plot the power spectral density (PSD) of the rectangular and SRRC pulse-shaped signals.

In [11]: plt.figure(); \
   ....: sdr.plot.periodogram(x_rect, sample_rate=symbol_rate * psk.sps, label="Rectangular"); \
   ....: sdr.plot.periodogram(x_srrc, sample_rate=symbol_rate * psk.sps, label="SRRC");
   ....: 
../../_images/sdr_rms_bandwidth_1.png